Stateless Template method implementation - java

Let's say I have a Strategy interface :
public interface Strategy {
void perform();
}
And a template method to implement it :
public abstract class AbstractStrategy implements Strategy {
#Override
public void perform() {
String firstInfo = doStuff();
String secondInfo = firstDelegationToImplementor(firstInfo);
String thirdInfo = processSecondInfo(secondInfo);
String fourthInfo = secondDelegationToImplementor(thirdInfo);
finalProcessing(fourthInfo);
}
private void finalProcessing(String fourthInfo) {
//TODO automatically generated method body, provide implementation.
}
protected abstract String secondDelegationToImplementor(String thirdInfo);
protected abstract String firstDelegationToImplementor(String firstInfo);
private String processSecondInfo(String secondInfo) {
return "thirdResult";
}
private String doStuff() {
return "firstResult";
}
}
And I have a concrete subclass of that :
public class ConcreteStrategy extends AbstractStrategy {
private String firstInfo;
#Override
protected String secondDelegationToImplementor(String thirdInfo) {
return someMoreProcessing(firstInfo, thirdInfo);
}
private String someMoreProcessing(String firstInfo, String thirdInfo) {
return null;
}
private String someProcessing(String firstInfo) {
return null;
}
#Override
protected String firstDelegationToImplementor(String firstInfo) {
this.firstInfo = firstInfo;
return someProcessing(firstInfo);
}
}
But due to the fact that it needs to remember some intermediate result in between the method calls it is not stateless. Stateless classes have several advantages, they are automatically thread safe for instance.
So the question is : how can I make ConcreteStrategy stateless, while taking advantage of the template method?
(edit) Clarification : the published methods of both the interface and the template method class cannot change.
(note, I have solved this question already and will answer it myself, but I'll give others a chance to solve it)

Ok here's the answer I have come up with when I faced this :
public class StatelessConcreteStrategy implements Strategy {
#Override
public void perform() {
new ConcreteStrategy().perform();
}
}
StatelessConcreteStrategy is stateless. It has all the benefits any other stateless class has, and by delegating the perform() to a new ConcreteStrategy instance, it gets to use the template method pattern, and is able to 'remember' any data it wants to in between method calls.
In fact you'll most likely want to inline ConcreteStrategy to an inner or even anonymous inner class.

Related

How to implement factory pattern with dagger using annotation

What I have done currently is
Created an abstract class
public interface AbstractRawPathStrategy {
String getRouteKey();
void processRequest();
}
Implemented the classes
public class GetDocumentImpl implements AbstractRawPathStrategy {
#Override
public String getRouteKey() {
return "GET_DOCUMENT";
}
#Override
public void processRequest() {
log.info("Inside get document");
}
}
Created a routing factory
public class RawPathStrategyFactory {
private final Map<String, AbstractRawPathStrategy> dictionary;
#Inject
public RawPathStrategyFactory(final Set<AbstractRawPathStrategy> abstractRawPathStrategySet) {
dictionary = new HashMap<>();
for (AbstractRawPathStrategy abstractRawPathStrategy : abstractRawPathStrategySet) {
dictionary.put(abstractRawPathStrategy.getRouteKey(), abstractRawPathStrategy);
}
}
public AbstractRawPathStrategy getByRouteKey(final String rawPath) {
return dictionary.get(rawPath);
}
}
Instantiated the factory
#Module
public class AppModule {
#Provides
#Singleton
public RawPathStrategyFactory getRouteKeyStrategyFactory() {
Set<AbstractRawPathStrategy> abstractRouteKeyStrategies = new HashSet<>();
abstractRouteKeyStrategies.add(new GetDocumentImpl());
abstractRouteKeyStrategies.add(new GetUserRightsImpl());
return new RawPathStrategyFactory(abstractRouteKeyStrategies);
}
What I want is to go to respective class based on the route key (String). How can this be done without instantiating each class with new in AppModule. Any cleaner way to do this?
Try to use multibindings when create RawPathStrategyFactory
https://dagger.dev/dev-guide/multibindings.html
The easy, boring, way would be to use some static identifier which you'll have to set for each distinct subtype of your abstract class, and subsequent subtype thereof.
The more complicated, albeit fun, way to do this would be to use reflection.

Which OOP design pattern to use for different actions on an object based on its field values?

I have entity in database, say, MonthPlan:
class MonthPlan {
private boolean approved;
// other fields
}
There is also REST interface, which accepts external requests based on which program changes entity instances. For example, request
class EditMonthPlanRequest {
private long amount;
// other fields
}
is used to change month plan amount.
What I need is to execute different actions on MonthPlan entity based on value of approved field. For example, code for mentioned request could be as following
MonthPlan plan = getPlan(...);
if (plan.isApproved()) {
// actions using data from EditMonthPlanRequest
} else {
// other actions using data from EditMonthPlanRequest
}
There would be 5-6 different requests each with exactly two variants of actions based on value of approved field of edited entity. What OOP design pattern can I use for such use case to write more concise code?
I do not think you need a design pattern in such a simple case. Each request will be processed by the corresponding method at Service layer.
In this scenario, the state pattern is more suitable.
State design pattern is used when an Object changes its behavior based on its internal state.
If we have to change behavior of an object based on its state, we can have a state variable in the Object and use if-else condition block to perform different actions based on the state. State pattern is used to provide a systematic and lose-coupled way to achieve this through Context and State implementations.
Try to implement based on your description:
public class StatePattern {
public static void main(String[] args) {
MonthPlan monthPlan = null; //= new MonthPlan(...)
StateContext stateContext = new StateContext();
if(monthPlan.isApproved()) {
stateContext.setState(new Approved());
}else {
stateContext.setState(new NotApproved());
}
}
}
class MonthPlan {
private boolean approved;
public boolean isApproved() {
return approved;
}
// other fields
}
interface State{
public void doAction(StateContext ctx);
}
class StateContext{
private State currentState;
public StateContext() {
//default Approved state, you can change if you want
currentState = new Approved();
}
public void setState(State state) {
currentState = state;
}
public void doAction() {
currentState.doAction(this);
}
}
class Approved implements State{
#Override
public void doAction(StateContext ctx) {
//actions using data from EditMonthPlanRequest
}
}
class NotApproved implements State{
#Override
public void doAction(StateContext ctx) {
//other actions using data from EditMonthPlanRequest
}
}
For this simple case, the Template Method pattern may apply:
abstract class AbstractRequest {
public void execute(...){
MonthPlan plan = getPlan(...);
if (plan.isApproved()) {
executeForApproved(plan);
} else {
executeForNonApproved(plan);
}
}
protected abstract void executeForApproved(MonthPlan plan);
protected abstract void executeForNonApproved(MonthPlan plan);
}
This way, you don't need to repeat the if statement and the getPlan(...) in each subclass:
class EditMonthPlanRequest extends AbstractRequest {
private long amount;
// other fields
protected void executeForApproved(MonthPlan plan){
...
}
protected void executeForNonApproved(MonthPlan plan){
...
}
}
If you want to do OOP, then replace conditionals with polymorphism.
In this example, it means splitting MonthPlan in two.
class ApprovedMonthPlan extends MonthPlan
class UnapprovedMonthPlan extends MonthPlan
Each class handles EditMonthPlanRequest in its own way.

Why does adding a super-class break my Spring beans?

I have a Spring Boot web application that is working correctly. I noticed that two #Repository beans had a lot in common, so I refactored them using an abstract super class and now my application is broken. I've double-checked and this is the only change that I've made between the working and non-working states. Can anyone see what I've done wrong?
Here's my working code:
public class One { ... }
public class Two { ... }
#Repository
public class RepoOne {
private final ISource<One> sourceOne;
private ICache<One> cache;
#Value("${com.example.lifetime.one}")
private int lifetime;
public RepoOne(ISource<One> sourceOne) {
this.sourceOne = sourceOne;
}
#PostConstruct
public void createCache() {
Duration lifetime = Duration.ofMinutes(this.lifetime);
this.cache = new Cache<>(lifetime, sourceOne);
}
public One get(String key) {
return cache.get(key);
}
}
#Repository
public class RepoTwo {
private final ISource<Two> sourceTwo;
private ICache<Two> cache;
#Value("${com.example.lifetime.two}")
private int lifetime;
public RepoOne(ISource<Two> sourceTwo) {
this.sourceTwo = sourceTwo;
}
#PostConstruct
public void createCache() {
Duration lifetime = Duration.ofMinutes(this.lifetime);
this.cache = new Cache<>(lifetime, sourceTwo);
}
public Two get(String key) {
return cache.get(key);
}
}
#Service
public class RepoService {
private final RepoOne repoOne;
private final RepoTwo repoTwo;
public RepoService(RepoOne repoOne, RepoTwo repoTwo) {
this.repoOne = repoOne;
this.repoTwo = repoTwo;
}
public void doSomething(String key) {
One one = repoOne.get(key);
...
}
}
Here's my re-factored code where I introduced an abstract, generic super-class.
abstract class AbstractRepo<T> {
private final ISource<T> source;
private ICache<T> cache;
AbstractRepo (ISource<T> source) {
this.source = source;
}
#PostConstruct
private void createCache() {
Duration lifetime = Duration.ofMinutes(lifetime());
this.cache = new Cache<>(lifetime, source);
}
protected abstract int lifetime();
public final T get(String key) {
return cache.get(key);
}
}
#Repository
public class RepoOne extends AbstractRepo<One> {
#Value("${com.example.lifetime.one}")
private int lifetime;
public RepoOne(ISource<One> sourceOne) {
super(source);
}
protected int lifetime() { return lifetime; }
}
#Repository
public class RepoTwo extends AbstractRepo<Two> {
#Value("${com.example.lifetime.two}")
private int lifetime;
public RepoTwo(ISource<Two> sourceTwo) {
super(source);
}
protected int lifetime() { return lifetime; }
}
When using the re-factored code I get a NullPointerException in AbstractRepo::get(). I've confirmed via the debugger that cache is null (along with source). However, I also confirmed via the debugger that instances of RepoOne and RepoTwo are created and their createCache() method called. It's as if two instances of each are being created and only the one is initialised. Any thoughts?
It isn't the fact that you introduced a parent class but the fact that you turned the get method into a final method.
A class annotated with #Repository will get automatic exception translation. This automatic exception translation is added through the use of AOP. The default mechanism to apply AOP in Spring is to use proxies and in this case a class based proxy.
What happens is that CgLib creates a proxy for your classes by subclassing it, so that when a method is called an advice can be added. However a final method cannot be overridden in a subclass. Which will lead to the get method being called on the proxy instead of the actual instance.
There are 2 ways of fixing this
Remove the final keyword
Introduce an interface defining the contract for your repositories. This will lead to a JDK Dynamic proxy being created. JDK Dynamic Proxies are interface based and don't need to subclass your actual class (that is only for class based proxies).

Can I have a single instance of Interface

In my Android application I have a class which gives me static string values; something like this:
public class VehicleInfo {
public static String getVehicleEnginePower(boolean isNew) {
return isNew ? "1800CC" : "1600CC";
}
}
Now I have another category, so I will have to pass another Boolean, and I will get the value I need. However, these categories will keep on increasing. So I looked into the Open/Closed principle which looks promising for quick enhancement. To ensure this I will make the VehicleInfo class as an Interface and then I will have other classes implement VehicleInfo.
public interface VehicleInfo {
String getVehicleEnginePower();
}
public class NewVehicle implements VehicleInfo {
#Override
public String getVehicleEnginePower() {
return "1800CC";
}
}
and the other category classes will also be something like this. In this way I will have to add another class for all the new categories.
The question I wanted to ask is: is there a way that I can have single instance of this interface? Because in the whole application flow, a user will only be able to see one category until he switches to another category.
I don't want to instantiate these classes at multiple points. To clarify my question, I want to do something like this at the start of my application:
if (isNew) {
VehicleInfo vehicleInfor = new NewVehicle();
}
And in the whole application, whenever I call VehicleInfo.getVehicleEnginePower, it should always return engine power from the NewVehicle class.
Is something like this possible? Or am I just being silly and I will have to instantiate this interface on multiple points?
Maybe you need a singleton here
public class VehicleInfoManager {
private static VehicleInfoManager INSTANCE = new VehicleInfoManager();
private VehicleInfo currentVehicleInfo;
public static VehicleInfoManager getInstance() {
return INSTANCE;
}
public void setCurrentVehicleInfo(VehicleInfo info) {
this.currentVehicleInfo = info;
}
public String getVehicleEnginePower() {
return this.currentVehicleInfo.getVehicleEnginePower();
}
private VehicleInfoManager() {
// Constructor private by default
}
}
Then you can call it from everywhere like this
VehicleInfoManager.getInstance().getVehicleEnginePower()
//Or set current info like this
VehicleInfoManager.getInstance().setCurrentVehicleInfo(new NewVehicle())
Just be careful as currentVehicleInfo is null by default so you need to handle null pointer cases.
If I understand your question correctly.
My solution to this would be Enum
public enum VehicleEnginePower {
NEW ("1800CC"),
OLD ("1600CC"),
private final String name;
private Modes(String s) {
name = s;
}
public String toString() {
return this.name;
}
}
Then you can do
if (isNew) {
String powerOfEngine = VehicleEnginePower.NEW.toString();
}

How to set inherited variable in java?

public class Atribut {
int classid;
#Override public String toString() {
return Integer.toString(classid);
}
}
I have made this class which overrides method toString(). I plan on making many subclasses with different classid. The problem is I dont know how to set the variable classid to work in toString method.
public class cas extends Atribut{
int classid=2;
}
The problem is if I make an cas object and toString method it returns "0" not "2".??
My preferred technique for this kind of thing is to use constructor arguments:
public class Parent {
// Using "protected final" so child classes can read, but not change it
// Adjust as needed if that's not what you intended
protected final int classid;
// Protected constructor: must be called by subclasses
protected Parent(int classid) {
this.classid = classid;
}
#Override
public String toString() {
return Integer.toString(classid);
}
}
public class Child extends Parent {
public Child() {
// The compiler will enforce that the child class MUST provide this value
super(2);
}
}
Much as #java_mouse recommended, just use the parent class's variable.
public class Atribut {
protected int classid;
public Atribut() {
classid = 0;
}
#Override
public String toString() {
return Integer.toString(classid);
}
}
public class Cas extends Atribut{
public Cas() {
classid = 2;
}
}
Set classid's value in the constructor and then you can use the superclass's toString() just fine.
When you shadow the variable, the one in the parent class is used in methods there.
If you want to do this, I would do this
class Atribut {
int classid = 0;
protected int classid() { return classid; } // points to Attribut.classid
public String toString() {
return Integer.toString(classid());
}
}
Then in your child class, you can override the method
class cas {
int classid = 2;
protected int classid() { return classid; } // points to cas.classid
}
Why do you want to shadow a variable in child class if it is already available in the parent? why not using the same variable?
if you use the same variable, the issue is resolved automatically. Don't duplicate the attribute if it has to be inherited.
I think most of the answers here narrow down to style preference.
For such small examples, most of the provided solutions would work just fine.
However, let's assume that you have an inheritance tree that is several levels deep. In such a scenario, it might be challenging to understand the source of each property, so using setters, getters, and references to the superclass might come in handy. My personal choice would be as follows:
public class Atribut {
private int firstProp;
private int thirdProp;
public int getFirstProp() {
return firstProp;
}
public void setFirstProp(int firstProp) {
this.firstProp = firstProp;
}
....
#Override
public String toString() {
return Integer.toString(this.getFirstProp()) +
Integer.toString(this.getThirdProp());
}
}
public class Cas extends Atribut {
private int secondProp;
public Cas() {
super.setFirstProp(1);
this.setSecondProp(2);
super.setThirdProp(3);
}
}
An alternative implementation, using the approaches provided above would result in the this Cas class:
public Cas() {
super(1, 3)
secondProp = 2;
}
This second solution is a bit harder to read and is less descriptive about what properties are you setting.
For those reasons, that is the style that I prefer. Also, to reiterate, the benefits of the first approach become more evident for more complex examples.

Categories

Resources