Design Phase - Many references to same object - java

I am designing an application where a class named Rights is used. This class contains information about what the user can /can't do and also contains other classes like DocumentFilters.
The issue here is that I have a lot of different parts of the application getting an instance of that class through their constructor or get method, in order to be able to verify a user action before allowing it. It seems like this is bad practice (I might be wrong). Are there ways to improve this?
The way it works is having the main class of the application creating the Rights class and then creating different components and passing it to those. The components don't have instance of the main class ether.
Example code. This is repeated over several Modules.
public class ModuleA{
private Rights rights;
public ModuleA(Rights rights){
this.rights=rights;
}
private boolean verifyRights(ActionEvent e){
if(e.getSource("copyButton"){
if(rights.allowedToCopy){
return true;
}
return false;
}
}

That is a valid design and it is called Inversion of control and more specificly Dependency Injection. You can try to use an IoC container for java if you don't want to inject your dependencies manually.
It is also possible to separate the security code into aspects by using AOP. This is a more advanced option, but doing so you can separate the code that checks the security from the real business code.
If the method you showed is duplicated exactly in your Module classes, you should extract the method into a base class. This base class should then be used for all your Module classes.
public class ModuleBase
{
private Rights rights;
public ModuleA(Rights rights)
{
this.rights=rights;
}
public boolean verifyRights(ActionEvent e)
{
/// implementation
}
}
public class ModuleA : extends Bicycle
{
public ModuleA(Rights rights)
{
super(rights);
}
}

First of all I would suggest to isolate all the rights checking code into some special layer. Usually, the Facade patten is helpful here - it can check rights and then forward requests to the underlying business logic.
But this is not always possible. In this case you still have to provide classes with references to Rights instance. There are several patterns here:
Pass it to constructor/method (like you do) - still works.
Introduce Context which will store the Rights instance and make it available for necessary classes. But context is really helpful when it stores many reusable instances, not only one.
Use any dependency injection framework.
Hope this helps.

Related

How to use two Guice modules that install a common dependency module

I'm working on a project that consists of four parts:
The Main project that brings everything together. This contains the public static void main(String... args) entry point.
Component A
Component B
A 3rd party Common component that both A and B refer to.
I'm using Guice for the plumbing between all four parts, and this is my problem:
In both As and Bs main Guice modules I install a module that extends one that is defined in Common. At runtime this setup fails with the following error:
A binding to common.SomeClass was already configured at common.AbstractCommonModule.configure(). [source]
The reason for this is that I'm invoking common.AbstractCommonModule.configure() twice; once by installing a subclass instance of common.AbstractCommonPrivateModule from Component A's com.a.MainModule.configure(), and a second time from Component B's com.b.MainModule.configure().
Installing just one instance of common.AbstractCommonPrivateModule in Main is not an option, because AbstractCommonPrivateModule implements a specific binder method bindComplicatedStuff(ComplicatedStuff), for which I only know the argument inside A and B, respectively.
I tried working around this whole thing by wrapping A's and B's respective main Guice modules in PrivateModules. However, this failed with the next error:
Unable to create binding for %s. It was already configured on one or more child injectors or private modules %s%n If it was in a PrivateModule, did you forget to expose the binding? [source]
In my case, A's and B's respective main Guice modules are in fact ServletModules - which apparently I can install twice from Main.
How can I get around these errors and install the AbstractCommonPrivateModule module twice?
Edit: I uploaded some example code (with explanation about some details) to GitHub
Rather than having A and B install Common, have them requireBinding()'s for the classes they need from Common. Then modules that rely on A or B will need to also install Common. This may feel a little odd, but it's actually desirable, since A and B are now less tightly-coupled to Common.
Update
The reason I am installing two ShiroWebModules is because I want the Jersey resources in the ui module to only be secured using one Shiro configuration (one that unserstands password-protecting resources), while all Jersey resources in the api module should be be secured using an entirely different Shiro configuration (one that understands only bearer tokens as an authentication mechanism).
Broadly speaking, this is intractable. A Guice Injector provides one way of doing something (generally one implementation of an interface) to the whole application; not different mechanisms per package. Your two Modules, SwsApiServletModule and SwsUiServletModule provide a number of identical bindings, and SwsModule installs them both together. In essence you're saying "Guice, please provide a bearer-token-based authentication mechanism" then immediately after saying "Guice, please provide a password-based authentication mechanism". It can only do one or the other, so rather than picking one arbitrarily, it fails-fast.
Of course, there are a number of solutions, depending on what exactly your needs are. The most common is to use binding annotations and to have the UI and API code request different annotation. That way you can install two different implementations (with different annotations) of the same interface or class.
Here's an example:
package api;
public class ApiResources {
#Inject
public ApiResources(#ApiAuthMechanism AuthMechanism auth) {
this.auth = auth;
}
}
---
package api;
public class ApiModule implements Module {
public void configure() {
bind(AuthMechanism.class).annotatedWith(ApiAuthMechanism.class)
.to(BearerTokenAuthMechanism.class);
}
}
---
package ui;
public class UiResources {
#Inject
public UiResources(#UiAuthMechanism AuthMechanism auth) {
this.auth = auth;
}
}
---
package ui;
public class UiModule implements Module {
public void configure() {
bind(AuthMechanism.class).annotatedWith(UiAuthMechanism.class)
.to(PasswordAuthMechanism.class);
}
}
---
package webap;
public class WebappModule implements Module {
public void configure() {
// These modules can be installed together,
// because they don't install overlapping bindings
install(new ApiModule());
install(new UiModule());
}
}
You mention in a comment that you don't have control of the overlapping bindings being installed because they're coming from a third-party module. If that is the case (I didn't see where that was happening in your code) it's possible the third party doesn't want you doing what you're trying to do, for security reasons. For example,
simply binding the password-based mechanism might introduce vulnerabilities in the whole app. It might be worth trying to better understand how the third party intends for their modules to be used.
Another option, which isn't ideal but can work for some use cases, is to use two wholly separate Injector instances, one with each binding. Then you manually pass the instances you need to the UI and API code directly. This somewhat defeats the purpose of Guice, but it isn't always the wrong decision. Using child Injectors can make this less painful.
As an aside, your "sample code" is enormous, and probably more than 90% is unrelated to the problem. In the future please take the time to create an SSCCE that contains only the code relevant to the problem at hand. There's simply no way anyone's going to sift through 100+ Java files and 7,300+ lines of code to understand your problem. Not only will this make it easier for people who are trying to help you, but simply trying to create an SSCCE that demonstrates the problem will often be enough to help you understand and resolve it yourself.
To install the same module twice, override the .equals method in your module to refer to class rather than object equality. Guice won't install a module that is equal to one that has already been installed. This doesn't help much most of the time as you type:
install new AbstractCommonPrivateModule();
and so each object is a different instance which won't be equal to the last. Overriding the equals method gets around that:
#Override
public boolean equals(Object obj) {
return obj != null && this.getClass().equals(obj.getClass());
}
// Override hashCode as well.
#Override
public int hashCode() {
return this.getClass().hashCode();
}
However, note that this method is often incorrect.
Why not to do the above?
At this point, you're not really making use of Guice or dependency injection. Instead, you've tightly coupled the implementation of AbstractCommonPrivateModule with the implementation of B and C which install it. As mentioned by #dimo414, it seems like here the OP really wants to use two different ShiroWebModules, which is exactly what Guice is good at doing by installing those two different modules at a higher level. Likewise, higher level installs let you swap out while testing. If you actually want to swap one of the modules out at some point, Guice will again break.
This can also break if you override a module (which is another useful tool for testing).
The OP also wants to install a generic module twice. Wrapping another library's generic module adds additional risk; the original authors may have very good reasons for not implementing the above trick themselves, such as security.

How to test code from nested packages

I would like to test my java code with mockito and I would NOT like to have all my methods being public.
My problem is the following, let's assume I have the following code:
package com.whatever;
public class Parent
{
public void PlayWithChild(Child child)
{
child.Hug();
}
}
package com.whatever.subpackage;
public class Child
{
public void Hug()
{
}
}
and I have the test:
package com.whatever;
import com.whatever.subpackage;
public class Test
{
#Test
public void PlayWithChild_ChildHugged()
{
//Arrange
Child mckChild = Mockito.mock(Child.class);
//Act
new Parent(mckChild).PlayWithChild();
//Assert
Mockito.verify(mckChild).Hug();
}
}
Now if I make Hug method package-accessible (removing) the 'public', then I can not access it from the test... and I don't want to put everything (Parent, CHild, and my whole testable library) to the same package, I want to organize them.
You'll need to decide what degrees of encapsulation and abstraction you want your design to have. Java doesn't have a particularly granular way of specifying which components are accessible from which other components, so you may have to express those in documentation instead of relying on the compiler to enforce them for you.
In your case, I think you should make the Hug method public; if you want to make it really clear, add corresponding Javadoc or put Child into a subpackage called "internal" to discourage its casual use.
Java's four access levels:
public access, which poses no problem to testing or mocking
protected access, which includes package access and out-of-package subclasses. Testing within the same package is easy, but you may have to create manual test doubles to access/verify protected method calls from outside the package in question.
Default or package-private access, which as you noted is easy to test/call from within the same package. From other packages, the methods don't exist in any meaningful way for calling or testing.
private methods, which can't be called or tested directly.
Why would someone make a private method in test-driven development? Easy: Because the private method is an implementation detail that doesn't need to be tested. Likewise, protected or package-private methods are implementation details that don't need to be tested outside of the package. Here, if the Hug() method is public and it calls private or package-private method FeelBetter(), then callers from other packages should go only by the public API Hug without calling or concerning themselves with implementation details like FeelBetter().
The consequence of this is to almost encourage large, overscoped packages, because that may look to be the best way to hide irrelevant implementation details from other packages and to limit the number of entry points. It's true that putting close collaborators in the same package allows small package APIs, which is a good goal. With enough classes in one package, though, this notion breaks down; luckily, it only breaks down once the package is demonstrated to be so big it merits two separate packages, at which point you can stop and think about which components are connected and which ones can be extracted into APIs of their own. This may mean widening access for certain classes/methods from package to public, which is to be expected when splitting packages. It may also imply adding accessible getters or other state-querying methods for the sake of testing, which is also to be expected when developing testable components.
For more information about how to make testable systems, and how to interact with test doubles (or real tested components), I suggest reading Martin Fowler's article Mocks Aren't Stubs.

Sharing Singleton logic between projects, with modifications for each project

I am developing two Android applications with similar -- but not identical -- logic, and I want to share code between them. Currently, I have a project for each application, and an additional project for shared classes. The shared-classes project is a library, and the application projects are linked to this library.
The problem I have is with a class that's responsible for getting data from the server and caching that data. The class is called DataSingleton. Fetching the data has some logic which is the same for both applications, and some which is different. My question is how to design the class to support this.
There are some limitations here:
The data Singleton should be a singleton, as implied by its name.
Some of the shared logic in the shared project uses the DataSingleton, so the DataSingleton must also be in the shared-classes project (otherwise I get a build error).
I don't want to put the application-specific logic in the shared project.
If this was C++, I would have 2 different classes name DataSingleton -- one in each application -- and then have the linker connect the correct class. Both classes could inherit from some common base class, to handle the code sharing for shared logic. Can I do something similar in Java?
If it helps, I can "initialize" the DataSingleton at the start of the application with some argument that will determine its behavior. I thought about passing a class to it, but then that class doesn't have access to the DataSingleton's private members.
What is the "right" way to do this?
Think about singleton. It is a class that does 3 thigs:
1. it has a business logic
2. it creates instance of itself
4. it holds this single instance and provides access to it.
You want to hold more than one implementations of your class. This means that you need interface and/or abstract base class and several concrete classes. But in this case the best solution is to separate #1 from #2 and #3: create hierarchy of DataFetchers (I am sorry, I changed your name DataSingleton because it does not describe the reality any more) and DataFetcherAccessor:
interface DataFetcher {}
class DataFetcher1 implements DataFetcher{}
class DataFetcher2 implements DataFetcher{}
class DataFetcherAccessor<A extends DataFetcher> {
private static A accessor;
public static void setImpl(Class<A> c) {
accessor = c.newInstance();
}
public static A getAccessor() [
return accessor;
}
}
There are obviously a lot of other solutions. For example you can use SPI to locate available implementation of your interface. You can also scan your classpath yourself and discover available implementation of interface DataFetcher or use Reflections for this.
Strip the DataSingleton in the shared project of the parts that will need to change in the different projects, define it as an abstract class and change its name to AbstractDataSingleton or something like that, then just create 2 separate classes in each product called DataSingleton or whatever and make them extend the AbstractDataSingleton in the shared project.

Is there a way to create Model here without duplicating the code?

I need to use two similar libraries one for one specific session of MVC. Means, they (their methods) won't be used simultaneously (I'll use If...Else around that specific session to choose methods of only one library at a time). The problem is:
For both libraries to work, its mandatory for my Entities (Model) to extend their classes (wished I was with C++).
They don't provide any Interface. So, I can't do multi-inheritance.
The only choice I have left: Create two different Models each for both libraries & use specific Model based on session (or being used libraries).
But, it'll duplicate the codes in Models. At this time there's no need to sync data between them due to use of persistent storage between MVC sessions. But still, duplicate code is a big headache to manage. Is there a way to avoid this?
You could create Adapters for each specific libraray. This would keep your own code clean from the other libraries.
Also you should consider using the Strategy Pattern for switching between both libraries. This becomes handy when the code becomes more complex and you can mock the libraries in tests.
You can't get around including both libraries if that's what you're asking. You could have a few options just depends on how you want things to work.
From what I understand, you could create two classes, each extending a different library, these classes implement an Interface, override any methods you need to.
Pseudo code:
private class Lib1Adapter extends Lib1 implements LibAdapter {
// wrapper methods call lib1 methods
}
private class Lib2Adapter extends Lib2 implements LibAdapter {
// wrapper methods call lib2 methods
}
public interface LibAdapter {
// method signatures for publicly accessible methods
}
public class YourModel {
public LibAdapter la = < boolean statement > ? new Lib1Adapter() : new Lib2Adapter();
}

Designing Constructors for Testability

I'm working with some existing code, trying to add to it and increase the unit tests for it. But running into some problems with getting the code testable.
Original Constructor:
public Info() throws Exception
{
_ServiceProperties = new ServiceProperties();
_SshProperties = new SshProperties();
}
I'm aware that this is bad, and obviously not testable. In a junit environment, this class will fail to create every time since it wont be able to find the necessary properties to construct itself. Now, I'm aware this class would be a lot more testable with the simple change of moving anything prefaced with 'new' as a parameter.
So I end up with:
New Constructor:
public Info(ServiceProperties srvProps, SshProperties sshProps) throws Exception
{
_ServiceProperties = srvProps;
_SshProperties = sshProps;
}
Which allows me to properly unit test this Info class. The problem though, is now all that work is pushed to some other class:
Some Other Class' Method:
public void useInfo() throws Exception
{
ServiceProperties srvProps = new ServiceProperties();
SshProperties sshProps = new SshProperties();
Info info = new Info(srvProprs, sshProprs);
doStuffWithInfo(info);
}
Now this method isn't testable. All I've managed to do is push off where the constructions of these Property objects are occurring, and somewhere else some piece of code is going to be stuck actually having to call "new".
Here's the rub for me: I can't figure out how to break this chain of events of simply pushing these "new" calls somewhere else. What am I missing?
Look at using a Dependency Injection framework such as Spring. This application of Inversion of Control means that each of your types can avoid the pitfall you've seen, leaving the configuration to "wire" components together.
This introduction to Spring (pdf) gives a comprehensive overview of Spring. The first chapter or two should be sufficient to explain the concepts.
Also see Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler
You have the right idea. Perhaps this will help you. I recommend you follow two rules for all your classes of significance, where "of significance" means if you don't follow the steps it will be more difficult to test, reuse, or maintain the class. Here are the rules:
never instantiate or self-acquire a dependency
always program to interfaces
You have a start at rule #1. You changed your Info class to no longer create its dependencies. By "dependency" I mean other classes, configuration data loaded from property files or whatever, etc. When you depend on how something is instantiated you are tying your class to it and making it more difficult to test, reuse and maintain. So, even if a dependency is created via a factory or a singleton, don't have your class create it. Have something else call create() or getInstance() or whatever and pass it in.
So you chose the "something else" to be the class that uses your class, and realized there is a bad smell to it. The remedy is to instead have the entry-point to your application instantiate all dependencies. In a traditional java app, this is your main() method. if you think about it, instantiating classes and hooking them up to each other, or "wiring" them together, is a special kind of logic: "application assembly" logic. Is it better to spread this logic throughout your code, or to collect it in one place to more easily maintain it? The answer is that collecting it in one place is better - not only for maintainance, but the act of doing so turns all your classes of significance into more useful and flexible components.
In your main() or equivalent of main() you should create all the objects you need, passing them into each others' setters and constructors to "wire" them together. Your unit tests would then wire them differently, passing in mock objects or similar things. The act of doing all this is called "dependency injection". After doing as I say, you will likely have a big ugly main() method. This is where a dependency injection tool can help you out and in fact make your code infinitely more flexible. The tool I would suggest when you get to this point, as others have also suggested, is Spring.
The less important rule #2 - always program to interfaces, is still very important because it eliminates all dependencies on implementation, making reuse much easier, not to mention leveraging other tools like mock object frameworks, ORM frameworks, etc. easier as well.
Even dependency injection frameworks like Spring, Guice, PicoContainer etc. need some sort of boostrap so you always have to build something up.
I would suggest you to use a provider/factory that returns a configured instance of you class. This would allow you to exit the "creation"-hierarchy.
Your constructors aren't incorrect and the problem isn't about when/where code is executed, it's about what everyone else mentioned: Dependency Injection. You need to create mock SshProperties objects to instantiate your object. The simplest way (assuming the class isn't marked as final) is to extend the class:
public class MockSshProperties extends SshProperties {
// implemented methods
}
You can you use mock frameworks like Mockito:
public class Info {
private final sshProps;
private final serviceProps;
public Info() {
this(new SshProperties(), new ServiceProperties());
}
public Info(SshProperties arg1, ServiceProperties arg2) {
this.sshProps = arg1;
this.serviceProps = arg2
}
}
public class InfoTester
{
private final static SshProperties sshProps = mock(SshProperties.class);
private final static ServiceProperties serviceProps = mock(ServiceProperties.class);
static {
when(sshProps.someGetMethod("something")).thenReturn("value");
}
public static void main(String[] args) {
Info info = new Info(sshProps, serviceProps);
//do stuff
}
}
The easiest answer is Spring. However another answer is to put your config stuff into JNDI.
Spring in some ways is a better answer, especially if you don't have anything that changes depending on environment.
You let the some-other-class have too much knowledge about the Info class and its dependencies. A dependency injection framework would use a provider class. Using generic types one can make a Provider of Info objects:
interface Provider<T> {
T get();
}
If your some-other-class take a Provider<Info> in its constructor your method would look like:
public void useInfo() throws Exception
{
Info info = infoProvider.get();
doStuffWithInfo(info);
}
This has removed construction of concrete classes from your code. Next step is to make Info into an interface to make it easier to create a mock for the specific unit-test case.
And yes, this will push and push all the object construction code further and further up. It will lead to some module that only describes how to wire things together. The "rules" for such code is that it should be free of conditional statements and loops.
I recommend reading Misko Heverys blog. All the presentations are useful and printing out the guide to writing testable code as little rulebook once you understand the rules is a good thing.

Categories