Design pattern to use when you need to initialize your object? - java

I have a class, which has an Initialize method, which creates a bunch of tables in a database. This class looks like this:
public class MyClass
{
private bool initialized = false;
public void Initialize()
{
if(!initialized)
{
//Install Database tables
initialized = true;
}
}
public void DoSomething()
{
//Some code which depends on the database tables being created
}
public void DoSomethingElse()
{
//Some other code which depends on the database tables being created
}
}
The two methods DoSomething and DoSomethingElse need to make sure that the Initialize method has been called before proceeding because they depend on having the tables in the database. I have two choices:
Call the Initialize method in the constructor of the class - this does not seem like a good idea because constructors should now call methods, which are non-trivial and could cause an exception.
Call the Initialize method in each of the two methods - this does not seem like a great solution either especially if there are more than a handful of methods.
Is there a design pattern which could solve this in a more elegant way?

I would use a static factory method in which Initialize is invoked, and make the constructor private, to force use of the static factory method:
public class MyClass
{
private MyClass() { ... }
public static MyClass createInstance() {
MyClass instance = new MyClass();
instance.Initialize();
return instance;
}
}
Also, I would remove the initialized variable - in part because you don't need it any more - but also because it requires some means of guaranteeing visibility (e.g. synchronization, volatile or AtomicBoolean) for thread safety.
I think that Miško Hevery's blog post on (not) doing work in constructors is an interesting read.

I would separate the installation of the database from the definition of tasks that depends on it:
static factory could be used for the database installation as pointed out by #andy-turner
and the repository pattern to do work on the database
I suggest this solution because if i understand correctly, you are concerned about the high number of tasks that depends on the database.
Using the dependency injection pattern the repository can get a reference to the database, so in your bootstrapping code you can execute the database installation once and then inject the reference to the database in all the repositories that depends on it.

I would recommend using a collaborator that does the initialisation. That way MyClass can easily be tested by substituting a mock for the initialiser collaborator. For example:
public class MyClass {
public MyClass(MyClassInitialiser initialiser) {
initialiser.initialize();
}
public void DoSomething() {
//Some code which depends on the database tables being created
}
public void DoSomethingElse() {
//Some other code which depends on the database tables being created
}
}

Or an alternative solution, the idea here is that you're breaking the single responsibility principle in MyClass. There is non-trivial initialisation behaviour (installing database tables) and behaviour on those tables in the same class. So you should separate those responsibilities into two different classes and pass one in as a collaborator to the other.
public class MyClass {
DatabaseCollaborator collaborator;
public MyClass(DatabaseCollaborator collaborator) {
this.collaborator = collaborator;
}
public void DoSomething() {
//Some code which depends on the database tables being created
collaborator.someMethod();
}
public void DoSomethingElse() {
//Some other code which depends on the database tables being created
collaborator.anotherMethod();
}
}
public class DatabaseCollaborator {
DatabaseConfig config;
public DatabaseCollaborator(DatabaseConfig config) {
this.config = config;
}
public void someMethod() {
}
public void anotherMethod() {
}
}
public class DatabaseConfig {
public DatabaseConfig() {
// initialize
}
}

When I want a class whose instances must be initialized exactly once but I want to defer initialization until right before it's necessary (at which point the caller may fail to call an Initialize function, find it inconvenient to do so, or etc.), I do it similar to how you've started out with your code, but I make the initialization method private and name it something like "EnsureInitialized". It uses a flag to track and early exit if initialization has already been done, and all functions which depend on initialization already having happened just call that function as their first line (after argument-checking).
If I expect the caller to control when this instance's initialization is done, I make the method public, name it "Init", track whether it has been run with a flag, handle idempotence or max-run-once inside the Init method however is appropriate for that class, and all methods which depend on Init having already been run will call a different, private method named "AssertIsInitialized" which will throw an exception with text like "Must call init on {class name} instance before using this function".
My goal with these different patterns is to be unambiguous about each method's expectations and operation regarding initialization within the class instance lifecycle, and provide discoverability (of the design or code bugs using it) and automatic behavior (in the case of the self-initializing class in my first paragraph) wherever I think each is most appropriate to what the rest of the application is doing.

Related

Java private vs default method protection

Java Question: I am working on a class (call it ProcessorA that only extends Object. It is also stateless). It will reside in a Spring Service on a Web Server. The class declares several public methods as the class' API.
I want to test this class with a simple JUnit test. I need to test some functionality that is a few method calls deep inside of 1 public method. However, between the API Method and the method to test there are several classes would be loaded at runtime by Spring in the Web Server.
I can completely by-pass this by declaring the method to be tested as a 'default' method and calling it directly from an instance (of ProcessorA) from the JUnit test.
I have been told that this is NOT a best practice.
However, I am at a loss as to exactly what is gained by further restricting access to the method to be tested.
So, what is it that can be gained by declaring a method as private over default (which is more restrictive than "protected" (which by inclusion is also verboten). \
public class ProcessorA {
public methodA(String input) throws ValidationException {
doSomeValidationStuff(input);
doStuffToTest(input);
}
private doSomeValidationStuff(String input) throws ValidationException {
//Libraries that are not loaded at execution and not available for the JUnit test
}
doStuffToTest(String input) {
//Code to be tested}
}
}
class MyJunitTest {
#Test
void doStuffToTestTest() {
ProcessorA processorA = new ProcessorA();
String testData = "test data String";
assertNotNull( processorA.doStuffToTest(testDate));
}
}
The answer that I am looking for isn't for how to get around this constraint, but what is gained by blindly following a blanket directive that has (seemingly) no payoff.
Default scope in Java is a package-private scope which means that all classes from the same package can use this method. If you restrict it to private, only methods from the same class can do it. This is what we gain. It is your decision, do you need to expose this method to other classes or it is enough to just keep it private but don't expose something only for testing purposes.

Statically providing metadata for a class in an enforceable manner

This is a little bit of a complicated issue, but I'll do my best to explain it understandably.
To start, consider the following classes.
public abstract class Invokable {
private String name;
protected Invokable(String name) { ... }
public String getName() { ... }
public abstract void invoke();
}
public class PrintInvokable extends Invokable {
public PrintInvokable() {
super("print");
}
#Override
public void invoke() { ... }
}
Another class, InvokerDispatcher, handles events from a messaging application and calls Invokable#invoke on an instance of the appropriate implementation based on the name field. This is all done reflectively so as to be able to scan the classpath for all the valid Invokable implementations and dynamically load them at runtime.
The issue here is that I can only access name via instance, so I have to instantiate a copy of every Invokable in order to check its name against the message content. My solution right now is to keep a list of pre-instantiated copies of each implementation in a separate class, then call a method that fetches and replaces an instance from the list by name.
I'd like to be able to access name statically instead, but I can't come up with a way to do so enforcably. Having a static abstract getName() in Invokable would be the easiest way to do it, but unfortunately Java doesn't support it. Any ideas?
My abstraction of this issue probably isn't the best, so here's my actual source code. The relevant classes are in the command package.

Mockito: Detect when a method on a private resource is invoked

I need to write a test for this class. I need to verify that when the size of the list is exactly 2 then the modelService.save is called. Is it also possible to get to the object productModel?
I don't know where to start.
public class SoldMaterialPrepareInterceptor implements PrepareInterceptor<SoldMaterialModel> {
#Resource
private ModelService modelService;
#Override
public void onPrepare(SoldMaterialModel soldMaterialModel, InterceptorContext interceptorContext) throws InterceptorException {
setSAPSubstance(soldMaterialModel);
}
private void setSAPSubstance(SoldMaterialModel soldMaterialModel) {
ProductModel productModel = soldMaterialModel.getBaseProduct();
Set superCatagoriesList = [....]// gets the list somehow
if (superCatagoriesList.size() == 2) {
productModel.setSupercategories(superCatagoriesList);
modelService.save(productModel);
}
}
}
It is not a problem that the modelService field is private, it is a class field for which private access modifier is usually expected. You need to check the invocation of its save() method, which in turn cannot be private, otherwise it would not be possible to call it from the interceptor class.
As for the test, assuming the superCatagoriesList (which is actually a Set and not a List and also should be generic) gets its content directly or indirectly (e.g. through productModel) from the soldMaterialModel parameter, your task is to write a test, which populates soldMaterialModel with such values so that superCatagoriesList.size() will be 2, and then you can verify that the modelService.save() method was called exactly once with e.g. something like
Mockito.verify(modelService).save(any(ProductModel.class));
I found that when it is difficult to test a method most often there is a design problem of the code I am testing. I suggest a minor to refactoring first: move setSAPSubstance to SoldMaterialModel class and make it public. That is where that method needs to be (see feature envy). Of course modelService.save(productModel); will stay in the interceptor and it will be called only if needed.
Then you will only have to test the two public methods
Is that the whole class? Then I think I see the issue. There are no non-private ways to set the ModelService. When the whole app runs, the dependency injection framework uses reflection to set the ModelService. When you run the test, you don't have anyway to inject a mock. You have a few options.
You can add a constructor to SoldMaterialPrepareInterceptor which takes the ModelService as a parameter. Then you can use that in your test. You would probably also have to add a no-argument constructor because that's how your dependency injection framework creates it. Better yet, you could figure out how to configure the framework to use the new constructor that takes the ModelService.
public class SoldMaterialPrepareInterceptor {
// Public constructor if needed for dependency injection
public SoldMaterialPrepareInterceptor () { }
// If just used for test use protected or package private
// If used with dependency injection, use public.
protected SoldMaterialPrepareInterceptor(ModelService modelService){
this.modelService = modelService
}
The test class is usually in the same package as the actual class, so package private or protected scope is enough. Then the test looks something like this (Assuming Mockito and Junit. Logically, Spock and other frameworks would be similar):
ModelService modelService = Mockito.mock(ModelService.class);
SoldMaterialPrepareInterceptor interceptor = new SoldMaterialPrepareInterceptor(modelService);
// setup SoldMaterialModel and InterceptorContext
interceptor.onPrepare(soldMaterialModel, interceptorContext);
Mockito.verify(modelService, Mockito.times(0)).save(soldMaterialModel);

Is it possible to limit method execution to a certain class?

I was wondering if it was possible to only allow a certain set of classes to execute a function.
I have a method: setPermission()
This method should only be called by certain classes throughout the project.
Some people suggested having the calling class pass in this, referencing the current object and ensuring it is an instanceof an allowed class. But any class could pass in an instance of an allowed class an so this seems to be an poor solution.
I also stumbled across Exception().getStackTrace()[1].getClassName(); however I am led to believe this is quite an expensive operation.
Is there a correct way to do this?
Use a marker interface (one that doesn't have any methods):
public interface Permissible {}
Then have the classes that are allowed to call your method implement it, then change the parameter type of your method to this interface:
public static void myMethodForObjectsThatHavePermission(Permissible obj) {
//
}
There's no way to enforce it that can't be worked around, but you could have most of your functionality on one class, setPermission() on a subclass, and make clients get an instance of your class via a factory method that is declared to return the parent class, but actually returns an instance of the subclass. That way, code that is supposed to call setPermission(), and knows about it, can do a downcast and call it, and all other users of the class won't even see it.
public class Service {
protected boolean permission = false;
protected Service() {
/* control creation */
}
public static Service getService() {
return new RealService();
}
public void doStuff() {
/* the public API side of the service */
}
}
public class RealService extends Service {
protected RealService() {
/* control creation */
}
public void setPermission(boolean permission) {
this.permission = permission;
}
}
A legitimate caller can do this:
public class Legitimate {
public void method() {
Service service = Service.getService();
RealService real = (RealService) service;
real.setPermission(true);
}
}
However, if all the legitimate callers can be put into the same package, and all the rest are outside the package, then package-private access (no access modifier) for setPermission() would be sufficient.
This doesn't prevent malicious callers from getting around the restriction, but it does avoid people calling setPermission without realizing they're not supposed to, because setPermission wouldn't show up in autocompletion (intellisense) in an IDE.
Sounds to me like you're looking for OSGi (en.wikipedia.org/wiki/OSGi). Third party developers should write bundles and with OSGi you can restrict capabilities of their bundles. Put your attention to: "Security The layer that handles the security aspects by limiting bundle functionality to pre-defined capabilities." Here is a thread discussing your case: Managing access to OSGI bundles

suppress a singleton constructor in java with powermock

I'm trying to unit-test some classes that make use of a Singleton class whose constructor does some things I can't (and shouldn't) do from the unit-test environment. My ideal scenario would be to end up with the constructor completely suppressed and then stub out the other member methods that my test classes invoke. My problem is that I can't seem to get the constructor suppressed.
My understanding of a way to solve this would be something like the following:
public class MySingleton extends AbstractSingletonParent {
public final static MySingleton Only = new MySingleton();
private MySingleton(){
super(someVar); // I want the super-class constructor to not be called
//
//more code I want to avoid
}
public Object stubbedMethod() {}
}
public class ClassToBeTested {
public void SomeMethod(){
Object o = MySingleton.Only.stubbedMethod();
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest(MySingleton.class)
public class TestClass {
#Test
public void SomeTest() {
suppress(constructor(MySingleton.class));
mockStatic(MySingleton.class);
PowerMock.replay(MySingleton.class);
// invoke ClassToBeTested, etc
PowerMock.verify(MySingleton.class);
//make some assertions
}
}
Unfortunately during the createMock invocation, the MySingleton constructor is hit, and it still calls the super constructor.
Am I doing something silly? I found an example on the web doing almost exactly this, but it was using a deprecated suppressConstructor method. Despite the deprecation I tried that, too, to no avail...
Is what I'm trying to do possible? If so, what am I doing wrong?
*Edited version now works.
You need to annotate TestClass with the #PrepareForTest annotation so it has a chance to manipulate the bytecode of the singletons.
Also, the superclass ctor supression signature should include somevar's class; right now you're just suppressing the default ctor.
See the #PrepareForTest API docs. Here's a blog post with some more details as well.
FWIW, it's working for me:
#RunWith(PowerMockRunner.class)
#PrepareForTest({EvilBase.class, NicerSingleton.class})
public class TestEvil {
#Test
public void testEvil() {
suppress(constructor(EvilBase.class));
assertEquals(69, EvilBase.getInstance().theMethod());
}
#Test
public void testNice() {
suppress(constructor(EvilBase.class));
suppress(constructor(NicerSingleton.class));
assertEquals(42, NicerSingleton.getInstance().theMethod());
}
}
How about you set the instance field ('only' in your code) of your Singleton with an instance instantiated with the constructor you want (you can do all of this with the Reflection API or dp4j).
The motivating example of a dp4j publication discusses that.
I am not sure what is it that you are doing wrong. But on the design side, i can suggest you look into dependency injection i.e. DI.
For making your code testable, make use of DI. With DI you would pass the singleton class as an constructor argument to your test class. And now since you pass an argument, inside your test case you can create a custom implementation of the AbstractSingleton class and your test case should work fine.
With DI, your code will become more testable.

Categories