I'm trying to implement the Strategy Pattern for some custom validation that doesn't involve only validation input with basic operations but I do need to call some other services to validate the data.
At the beginning I used the example mentioned here which uses enums to have different strategies but of course it was not possible to inject my services in the enum so now I'm looking at this that leverages to java 8 for more clarity.
My idea is to have an interface with has one method validate() and have generic input for different objects I could send it and then a class implementing that interface that would have different validations based on object type and dispatches requests to different services, but on the other hand I'm kinda loosing the enum advantage on having different strategies which I could select for instance based on specific user settings.
Any idea how to have both of these advantages?
I would say that enums and the strategy pattern don't really mix.
The ideal use case for an enum is something that represents an exhaustive set of choices. DayOfWeek representing Monday to Sunday, for example. The problem with using this, in addition to not being able to autowire any other beans, is that your enum will continue to grow as the number of validations increase.
The strategy pattern allows you to use a potentially infinite number of possible strategies, provided it obeys the contract. Take Collections.sort(List<T> list, Comparator<? super T> c), for example. There could be no exhaustive list of possible comparators, because it could never fulfill everyone's use-cases.
It makes more sense to define each of your possible strategies as a component
#Component
class NonNullValidationStrategy implements ValidationStrategy {
private final MyService service;
//constructor
#Override
public boolean isValid(MyClass foo) {
return foo != null;
}
}
How you would obtain an instance of the right strategy when you need it will depend on details you haven't provided. Maybe autowiring with a qualifier is a possibility.
Spring already has it's own way of defining validations, via interfaces and annotations. I suggest you pursue that before rolling your own solution.
It'd like to suggest using javax.validation groups, see more about it here especially #Validated(OnCreate.class)
If you want to apply strategy pattern at the controller level and deeper than see this article and especially my comment, because there is described not a pretty clean solution.
Related
When we use Abstract Factory Pattern, we generally have FactoryMaker class which has a getFactory function in which we pass argument and we have switch or if-else logic in the function on the passed parameter to decide which factory to return. Is creating passed parameter an enum or an object and then having the logic of which factory to return inside those object will be better. For example :
Let us say this us our factory maker which are passed enum CountryCode to decide factory.
public class FacoryMaker {
public final static FacoryMaker fctry= new FacoryMaker();
public static RetailFactory getFactory(CountryCode code){
RetailFactory rt = null;
if(code == CountryCode.UK){
rt = new UKFactory();
}
if(code == CountryCode.US){
rt = new USFactory();
}
return rt;
}
}
Instead of this we will have :
public class FacoryMaker {
public final static FacoryMaker fctry= new FacoryMaker();
public static RetailFactory getFactory(CountryCode code){
return code.getFactory();
}
}
and enum will be modified like this:
public enum CountryCode {
US(){
#Override
public RetailFactory getFactory() {
return new USFactory();
}
},
UK(){
#Override
public RetailFactory getFactory() {
return new UKFactory();
}
};
public abstract RetailFactory getFactory();
}
But I don't see this being followed generally. Why is it so? Why can't we make the passing parameter always an object and have the logic inside the object of which factory to get? Can it fail under any abstract factory design. It looks very generic to me. Also by this it is possible to even remove the factory maker and use the object directly to get the Factory instance.
When designing software, one aspect to consider is Separation of Concerns it doesn't sound very reasonable to me to let a CountryCode create a RetailFactory. Both concepts have a pretty low cohesion towards each other, which should be avoided.
Further, if you already have a country code, why would you need a factory at all, what's preventing you to call the getFactory method directly? It simply makes no sense.
The CountryCode is merely a hint for the FactoryMaker's getFactory method, how to create the factory. It may even completely ignore the country code. What if there is a country without a RetailFactory? Do you return null? a DefaultFactory or the Factory of another country?
Of course it is possible to do it that way, but if you look at your code a half year from now, you may think "Wtf? Why the heck did I create the Factory in the Country Code?!"
Besides, the first example you provided seem to be more of a Factory Method than a Factory because the FactoryMaker is not used at all.
I think that Abstract Factory is a general pattern for all OOP languages. When people describe it, they should show a general implementation which is possible to be applied in all of those languages. Then people follow the pattern, they follow genernal implementation.
And your implementation is using Enum which is specifically supported in Java but not other OOP languages.
Very often in practice, factory methods don't know in advance the implementations. The implementing classes may not exist at the time the factory is created. This is the case for example in service provider frameworks such as the Java Database Connectivity API (JDBC). JDBC defines the interfaces that service providers must implement, but the concrete implementations are not known in advance.
This framework allows adding implementations later, for example for database drivers of new cutting edge databases.
The service provider framework includes a provider registration API to register implementations (ex: DriverManager.registerDriver), and a service access API for clients to obtain an instance of the service (ex: DriverManager.getConnection).
It is common to instantiate the service implementation using reflection (ex: Class.forName("org.blah.Driver")).
Your example is different. You know all the implementation classes you intended.
And you are not considering (yet) the pluggability of other implementations.
Whether you create the instances using a switch or an enum,
it makes little difference.
Both alternatives are fine, equivalent.
Another related alternative is that the various methods in Collections do, for example Collections.emptyList(), Collections.singletonList(...), and so on.
The implementations are not decided by a switch,
but have explicit names by way of using specialized methods.
When you want to make it possible to use implementations of your interfaces not known in advance, and not hard-coded in your factory, look into service provider frameworks such as JDBC.
But I don't see this being followed generally. Why is it so?
Your technique only works because you know all the implementations of RetailFactory in advance.
In frameworks like JDBC, all the implementations of Driver, Connection, and so on, are not known in advance, for all the databases out there, so using such technique with a single enum referencing all implementations is not possible, and not scaleable. So they use a different mechanism, to register and load implementations dynamically at runtime.
Why can't we make the passing parameter always an object and have the logic inside the object of which factory to get?
You can. If you don't need dynamic loading of implementations like JDBC (and most probably don't), your way of using enums has some advantages.
For example, your original implementation does rt = ..., which is not as good as doing return .... Such "mistake" is not possible using your enum solution. On the other hand, if you want dynamic loading, then using an enum will not make much sense.
The bottomline is, there is no big difference between the two alternatives you presented. Both are fine.
Background
I'm writing an application in Java and I'm using Guice for DI.
(It's Android and RoboGuice to be exact, although it probably makes no difference in this context).
Class design
It's an app for keeping score for a popular cardgame - Hearts.
The game consists of various consecutive deals, whose rules differ. Eg. in one deal players are penalized for taking Hearts, in another - for taking Jokers and Kings.
My object design involves several classes:
Deal for identifying each deal
ScoreCalculator for calculating penalties (eg. each Heart may be worth -2 points). Penalties may vary from deal to deal.
ScoreValidator for validating the scores (for instance, it's not possible for each player to take 4 Hearts, because there isn't as many in the deck)
If each Deal class had one corresponding ScoreCalculator and ScoreValidator, dependency injection would be trivial.
But this is not the case. Calculating score for some of the deals can be very specific (distinguishing them from the others), while for the rest it's based on nothing more but multiplying the number of taken cards by the penalty parameter (-2 or -4 etc.)
So, LotteryDeal is associated with a LotteryCalculator, but NoQueens and NoGents both require a class I named SimpleCalculator.
It takes a single integer parameter, which is a multiplier (penalty score).
This is my current solution, in which I implemented Deal as an enum (but I'm not happy with it and I want to drop it):
public enum Deal
{
TakeNothing(-2, PossibleDealResults.fullRange()),
NoHearts(-2, PossibleDealResults.fullRange()),
NoQueens(-2, PossibleDealResults.rangeUpTo(4)),
NoGents(-2, PossibleDealResults.rangeUpTo(8)),
NoKingOfHearts(-18, PossibleDealResults.rangeUpTo(1)),
NoLastOne(
new NoLastOneCalculator(),
new NoLastOneValidator(new NoLastOneCalculator())),
Trump1(2, PossibleDealResults.fullRange()),
Trump2(2, PossibleDealResults.fullRange()),
Trump3(2, PossibleDealResults.fullRange()),
Trump4(2, PossibleDealResults.fullRange()),
Lottery(new LotteryCalculator(), PossibleDealResults.rangeUnique(1, 4));
protected ScoreCalculator calculator;
protected PlainScoreValidator validator;
Deal(int multiplier, PossibleDealResults possibleResults)
{
this(new SimpleCalculator(multiplier), possibleResults);
}
Deal(ScoreCalculator calculator, PossibleDealResults possibleResults)
{
this(calculator, new PlainScoreValidator(possibleResults, calculator));
}
Deal(ScoreCalculator calculator, PlainScoreValidator validator)
{
Preconditions.checkNotNull(calculator, "calculator");
Preconditions.checkNotNull(validator, "validator");
this.calculator = calculator;
this.validator = validator;
}
}
I'm not removing some complexities that are out of the scope of this question (such as the PossibleDealResults class, which I did not describe to you), as it doesn't seem to be very relevant.
The main point is that all dependencies are hard-coded, as you can see, which is not really flexible, for example because there are many different variations of the game, with various scoring rules.
Let's say I'd like to use dependency injection to allow for more flexibility and perhaps even switching between different rules sets more easily - by switching to a different Module in order to re-resolve dependencies if there is a need.
Where's the problem?
I think I have some grasp on how to do it in general.
My question concerns injecting the SimpleCalculator object.
I'd need it with a parameter of -2 for TakeNothingDeal, but -18 for the NoKingOfHeartsDeal.
How to achieve it with Guice?
I'd like to keep the class parameterized and avoid creating a MinusTwoSimpleCalculator and a MinusEighteen... one.
I'm not really sure what's the proper way to achieve that, without abusing the framework (or more general DI design guidelines).
What have you tried?
Not much in terms of actual code. I'm a bit stuck.
I know there's bindConstant, but I can't see how I could make use of it in this case. It requires annotations, but if use Deal-specific annotations - I mean, create a Deal.multiplier field and then annotate it with something to the effect of "inject -2 here, please", what did I really do? I just went back to hard-coding dependencies manually and I'm not really using Guice anymore.
I read about AssistedInject, too, but I can't figure out how it could be of help here, either.
I don't want to overengineer this nor to work against the framework. What's the correct approach? Happy to clarify if the problem is somehow unclear.
You have a lot of options, actually. Here are three:
Factory object
Frankly, I don't think this design needs Guice for this particular problem. Instead, create a simple interface to populate with relevant switch statements:
interface DealFactory {
ScoreCalculator getFromDeal(Deal deal);
ScoreValidator getFromDeal(Deal deal);
}
You might be thinking, "But that works on objects telescopically! Those methods would be better left on Deal." You'd be right, mostly, but one key factor of OOP (and Dependency Injection) is to encapsulate what varies. Having a single set of rules declared statically in Deal is the opposite of the flexibility you want. (The enum itself is fine; there are a finite number of deal types regardless of the rules in play.)
Here, you could easily bind the DealFactory to some lightweight object that provides exactly the right ScoreCalculator and ScoreValidator for any given Deal, and write as many DealFactory objects as you'd like for each set of rules. At that point you can declare the currently-in-play DealFactory in a module and inject it wherever you want.
Also bear in mind that a factory implementation could easily work with Guice and injected bindings:
class DealFactoryImpl implements DealFactory {
#Inject Provider<DefaultScoreCalculator> defaultScoreCalculatorProvider;
#Inject MultiplierScoreCalculator.Factory multiplerScoreCalculatorFactory;
#Override public ScoreCalculator getFromDeal(Deal deal) {
if (TakeNothing.equals(Deal)) {
return defaultScoreCalculatorProvider.get();
} else {
return multiplierScoreCalculatorFactory.create(-2); // assisted inject
}
} /* ... */
}
Private modules
A similar problem to yours is sometimes known as the "robot legs" problem, as if you're writing a common Leg object that needs to refer to a LeftFoot in some trees and a RightFoot in others. Setting aside the (better) above solution for a second, you can set up private modules, which allow you bind things privately to expose only a few public dependencies:
// in your module
install(new PrivateModule() {
#Override public void configure() {
SimpleCalculator calculator = new SimpleCalculator(-2);
bind(ScoreCalculator.class).toInstance(calculator);
bind(ScoreValidator.class).toInstance(
new PlainScoreValidator(calculator, PossibleDealResults.fullRange());
expose(Deal.class).annotatedWith(TakeNothing.class); // custom annotation
}
});
See what I mean? Certainly possible, but a lot of work for Hearts rules. A custom class is a better match for this particular problem. Your need to specify multipliers is shallow; if Deal needed P, which needed Q, which needed R, which needs S, which needs the same ScoreCalculator, then a PrivateModule solution looks much more appealing than passing your calculator around everywhere.
#Provides methods
If you still want to solve this in Guice, but you don't want to write a lot of private modules that expose one binding each, you can take matters into your own hands with #Provides methods.
// in your module adjacent to configure()
#Provides #TakeNothing Deal anyMethodNameWorks(/* dependencies here */) {
SimpleCalculator calculator = new SimpleCalculator(-2);
ScoreValidator validator = new PlainScoreValidator(calculator,
PossibleDealResults.fullRange());
return new Deal(calculator, validator);
}
Again, this will create a binding for every type of Deal, which is probably a bad idea, but it's a bit more lightweight than the above. To some degree you're doing Guice's job for it—creating objects, I mean—but should you need any dependencies Guice can provide, you can inject them as method parameters on the #Provides method itself.
I want to ask if there is a possible way to conditionally implement interfaces or if there can be a workaround to what I want to do. I want to make two interfaces LangA and LangB that will only hold a very large number of final variables that are Strings used to print messages. As you probably imagine LangA is one language and LangB another one. What I want is have my message-handling class conditionally implement the interface needed based on the system's locale. I have no idea if this is possible at all in any way even with some custom ibrary, so if not, explain me if it can be worked around at least. (Quick question: is this possible in Scala? thanks!)
I have thought of a possible, but maybe not a very resource-efficient workaraound, which will have the class's constructor check the locale and set its own finals based on the values of some methodless class that will only feature the finals for each language (e.g. constructor learns that locale is locA so it sets finals myF1=LangA.myF1; myF2=LangB.myF2; etc.) Thanks in advance!
No, this is not possible.
The "class X implements interface Y" relationship is fixed at compile time, and cannot be altered at runtime.
However, using interfaces to import constants into a class is a solution that dates back to Java 1.0. This anti-pattern should not be used for new development.
Moreover, localization with compile-time constants is not a native solution in Java. You should localize using resource bundles.
If you need a way to switch implementations at runtime, replace constants with methods in your interface, and provide implementations that return different constants:
interface Constants {
double getAccelerationDueToGravity();
}
class EarthConstants implements Constants {
double getAccelerationDueToGravity() {
return 9.8;
}
}
class MarsConstants implements Constants {
double getAccelerationDueToGravity() {
return 3.71;
}
}
Sorry, this is not a good design. If you have a large number of messages, you're better off storing them in a database and caching them in an object that lets you look them up in memory.
The idea of interfaces to hold nothing but constants has been discredited for a long time.
Interfaces should be about separating methods and behavior, not constants.
The idea that these are locale-specific points even more strongly to a database or a message bundle or - wait for it - a Map of Property values with Locale as the key.
If you must persist, you'll have a better chance with composition than inheritance. You can inject an object with the messages it needs using a dependency injection engine like Spring's BeanFactory.
Anything other than the idea you posted.
Java design question.
I have an object that needs to maintain sets of say 4 types of widgets: active, inactive, invalid, potential. For each of these types, I have a series of methods that acts on each: say add, get, remove, etc.
My question is, would it be better to have a series of methods like this:
addInactive(Widget)
getInactive()
removeInactive(Widget)
addActive(Widget)
getInactive()
removeInactive(Widget)
addInvalid(Widget)
etc...
OR
Should I have an enum inside this class instead: WidgetStatus and then the consumer would pass in this enum when they need to perform an action. This would result in only 3 public methods instead:
add(Widget, WidgetStatus)
get(WidgetStatus)
remove(Widget, WidgetStatus)
On one hand, I like the first using specialized methods because it not only keeps down the number of parameters needed, but it also forces the consumer's hand to explicitly call the method they need. However, the latter option seems to keep the API simple and makes adding additional status types in the future a bit easier.
Thoughts?
With the enum you get a cleaner API and much easier maintenance if you want to change the states; there really is no good reason for the first approach.
WidgetStatus is attribute of widget, not a container. May be follow will be good for you
Widget.setActive(false);
add(Widget);
I would turn the enum or whatever into some Strategy Pattern that includes the behavior you mention above. Then your add/get/remove methods will simply delegate to the strategy to perform the action.
http://en.wikipedia.org/wiki/Strategy_pattern
I need to create a class which will be responsible for result set processing but it might happen that different algorithms should be used to process that result set.
I am aware of the following options:
1) Use Strategy patern, below is pseudo code:
interface Strategy {
processResultSet(ResultSet rs);
}
class StrategyA implements Strategy {
processResultSet(ResultSet rs);
}
class StrategyB implements Strategy {
processResultSet(ResultSet rs);
}
Context class will contain reference to Strategy and Client should pass the implementation of Strategy creating Context object, i.e.
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public doSomething(rs) {
strategy.processResultSet(rs);
}
The problem is that I don't want to pass strategy object to Context but I would like to create something like StrategyFactory which will be responsible for creation of concrete Strategy implementation. It would separate Client from Strategy - is it a good design?
Is it a mix of Strategy and Factory or in fact only Factory pattern?
It's definitely a combination of Strategy and Factory - but I don't think that's bad. The patterns are intended to be combined and used with each other.
It is hard to tell with out seeing this design plan in context whether this is a good design or a bad one. With just the information you've given here it could go either way.
Seems like your head is in the right place, but let me just give you a word of warning: don't stretch too hard to separate your client from your strategy. I have done this in the past and it lead to a convoluted mess which would have been far simpler had I just allowed a little connection between the two portions of my code. Separation is good, but struggling to maintain perfect separation can lead to bad code and all kinds of problems.
We have used this is many different parsing scenarios and it certainly works. I have blogged about this with a code example: http://www.herrodius.com/blog/136
The trick we use is to give the strategy interface an extra "canProcess" method which simply returns a boolean if the strategy is able to deal with the data. The factory then simply loops through all its strategies and asks each one if it can work with the data. If one can, we return that strategy or execute the strategy.
In the scenario you depict, there wouldn't really be a need for a Context, which would instead be replaced by the Factory you desire. The strategy pattern in this case is just overhead and an unneeded layer of complexity. All you need is an interface or abstract class, implementations, and a Factory or Proxy to retrieve the implementations.
Anny comments related to my thoughts:
1) There is a Service - Singleton. 2) It contains a reference to DAO class - it is also a singleton. 3) In DAO there is a method which retrieves ResultSet: ResultSet rs = ps.executeQuery(); I would like to create an appropriate strategy inside DAO to process this result set. I can't pass this strategy in DAO constructor because it is specific for the incomming request. Passing it in the constructor would make it the same for all incomming request.
So I decided to create a Factory inside DAO (DAO object instance) and inside a method I'm going to create an appropriate strategy (based on the request - local object) from the factory and use it to process the resultset.
Is this solution good in your opinion?
I think strategy pattern should go with a factory pattern. And in a way you used it is absolutely correct. Secondly, it would be better if you kept context class as an abstract class so that you can extend different contexts as per your requirement. Rest of the things seems good but according to the example you mentioned I think it wasn't necessary but you have used it in right way.