How to avoid empty visit functions in visitor pattern? - java

I have the following use case. I have a restriction interface that needs to fill its members from dependencies, do the validations. These methods are applicable for all implementations and hence it is fine till now. Some restrictions require some other validation later. In the main function, I want to loop over each of the restriction and call the methods in a general way instead of using instanceOf and then calling. I think this might be a use case of visitor pattern as mentioned here. Now I have the following classes.
interface Restriction() {
void fillFields();
void firstRoundValidation();
void accept(SecondRoundValidationVisitor secondRoundValidationVisitor);
}
class RestrictionBasic implements Restriction {
Field field;
// Inject dependencies
#Override
void fillFields() {
// Get field from dependencies
}
void firstRoundValidation() {
// Implement
}
#void accept(SecondRoundValidationVisitor secondRoundValidationVisitor) {
secondRoundValidationVisitor.visitRestrictionBasic(this);
}
}
class RestrictionAdvanced implements Restriction {
// Same as above except below function.
#void accept(SecondRoundValidationVisitor secondRoundValidationVisitor) {
secondRoundValidationVisitor.visitRestrictionAdvanced(this);
}
}
interface ValidationVisitor {
void visitRestriction(RestrictionBasic restrictionBasic);
void visitRestriction(RestrictionAdvanced restrictionAdvanced);
}
class SecondRoundValidationVisitor implements ValidationVisitor {
#Override
void visitRestriction(RestrictionBasic restrictionBasic) {
// Empty function
}
#Override
void visitRestriction(RestrictionAdvanced restrictionAdvanced) {
// Perform second level of validation
}
}
class Main() {
List<Restriction> restrictionList = new ArrayList();
ValidationVisitor validationVisitor = new SecondRoundValidationVisitor();
for (restriction : restrictionList) {
restriction.accept(validationVisitor)
}
}
Could you please tell if there is any issue with this approach? There is also another approach where getSecondValidationNeeded() could be added to the interface and based on that, call secondValidation with default value of empty body. But this is not following interface segregation principle. My doubt is how does visitor pattern solve this issue? Even in visitor pattern, there is only one interface and accept is being added in base interface even when only some visitors have non empty visit functions.

Visitor pattern uses overloading of methods to choose appropriate implementation. It can be seen in a wiki example:
interface CarElementVisitor {
void visit(Body body);
void visit(Car car);
void visit(Engine engine);
void visit(Wheel wheel);
}
So I would edit interface ValidationVisitor:
interface ValidationVisitor {
void visitRestrictionBasic(RestrictionBasic restrictionBasic);
void visitRestrictionAdvanced(RestrictionAdvanced restrictionAdvanced);
}
to this:
public interface ValidationVisitor
{
void VisitRestriction(RestrictionBasic restrictionBasic);
void VisitRestriction(RestrictionAdvanced restrictionAdvanced);
}
So we have created VisitRestriction() with different overloads.
Why? If you don't know the type of the object? You probably would need to find out the real type of Restriction and then call VisitRestrictionBasic or VisitRestrictionAdvanced. I highly recommend you to read this very nice answer about What's the point of the accept method?

Pattern-wise I don't think there is a problem. visitRestrictionBasic is only empty because apparently you don't have second round validation for basic restrictions. This is a business rule, not a flaw of the design. If you later decide that you DO want second round validation for basic restrictions, you know where you can add it.
Apart from that, the whole set up might be overkill. It's usually good to start off simple. But I don't know your complete domain and use case, so cannot judge if this is the case here.
EDIT: To evaluate your approach we should get more context and take a step back to understand the problem. So far what I understand is there are several restriction types which have the following characteristics:
each restriction has a fixed groups of dependencies
a restriction extracts values from these dependencies into its fields
each restriction performs two rounds of validation on these fields
the first round validation is implemented in each restriction type
the second round validation is also specific per restriction type, but implemented in the form of a separate visitor
The fundamental difference between the first round and second round validation is not clear to me. Both of them have specific validation code for each restriction type if I understand it correctly. If not, and the basic validator is only used in the first round, and the advanced validator only in the second round, then the model could probably be simplified. In that case first round = basic and second round = advanced...

Related

Is it possible to reference different methods with one method call in a for loop?

I have a plan to make a GUI as minimal as it gets. I have hit a brick wall where I cant find an answer or maybe some kind of workaround due to me being inexperienced in java.
I have searched quite a bit and only found ways to replace the last letter or number in a string but not in a method call
public static int question;
public static void main(String[] args) {
int questionNumber = Integer.parseInt(JOptionPane.showInputDialog("Enter project no."));
if (questionNumber>=7){
questionNumber=6;
}
else if(questionNumber<=3){
questionNumber=4;
}
question = questionNumber;
System.out.println(question);
System.out.println(questionNumber);
for(int i=4; i<=6;i++)
if(question==i){
Question4(); // want the number 4 to be the question variable
}
}
What I would expect is
for(int i=4; i<=6;i++)
if(question==i){
Question *the variable "question" here* ();
}
and have no idea if that is possible or how to get there.
Is it possible to reference different methods with one method call in
a for loop?
Yes. It depends upon what exactly you mean by different methods. Here are three general ways in which this can be achieved:
The Java enum facility allows developers to define constant-specific methods, which are different method bodies defined in each separate enum constant declaration. The actual method body that is invoked depends upon the actual enum constant upon which the method call is made (this is actually a specialization of the next bullet item).
Interfaces enable different method bodies to be defined in each separate implementation. In this way, the actual method body that is invoked depends on the instance of the actual implementation upon which the method call is made.
Another way to invoke different method bodies with "the same method call" is to perform method invocations using Java's Reflection Facility. Since Java is an Object-oriented development environment, a decision to use reflection should be made carefully. Reflection is (often much) slower, less readable, and clumsier than solutions that don't use it. Reflection also makes many errors which could be detected at compile-time detectable at run-time only.
In Java, the principle mechanisms of abstraction are classes and interfaces and, so, when thinking about a problem domain and resolving that into an object domain you should be thinking about how to design interfaces and classes that provide the most natural description possible.
You want to be able to invoke a method that corresponds to a particular question. A better way to approach this is not to abstract over it with the method call to a question, but to abstract over the questions themselves. Your project has questions, so this is a good clue that you should have a Question class.
Here is a skeletal solution to the problem that makes use of the Java enum facility (enums are a special kind of class). This solution is similar to the one suggested by Matthieu but it does not need reflection at all; instead it uses the first bullet item above and defines constant-specific methods (which is, itself, a specialization of the second bullet item above):
public enum Question {
QUESTION_1 {
#Override public String getText() {
return "This is the text for Question #1.";
}
},
QUESTION_2 {
#Override public String getText() {
return "This is the text for Question #2.";
}
},
:
:
QUESTION_N {
#Override public String getText() {
return "This is the text for the final question in the series.";
}
};
public abstract String getText();
}
This enum class defines one constant for each question in the series of questions (each of these constant declarations becomes an instance of the enum class Question at run-time). Each declaration defines a different method body for the method getText() which is overridden inside each enum constant.
The declaration public abstract... at the end of the enum informs the compiler that every enum constant must provide an implementation for the getText() method. If a developer adds a new question to the series but forgets to add a getText() method in it, the compiler will complain (this is a type of error that can be caught at compile-time with an object-based solution that could only be caught at run-time if reflection were used).
Here is a simple program to exercise your Question enum class. It simply prints out the name of each question constant followed by its question text:
public static void main(String[] args) {
for (Question question : Question.values()) { // here is the "one for loop"
String text = question.getText(); // here is the "one method call"
println(question.toString());
println(text);
}
}
No reflection is used. Instead, natural abstraction mechanisms of Java's type system are able to achieve the desired goal of invoking a separate method body for each question.
Using map in this situation is most easiest solution. You should learn how to use them and how they works but, this is more about design now. If you want pass some parameters into your method take a look on Consumer, BiConsumer or even Function class provided by java. Check this example how it could implementation looks with Runnable that takes no parameters.
Map<Integer, Runnable> map = new HashMap<>(); // creating Map variable
// registering questions
map.put(1, () -> {
System.out.println("Question #1");
});
int questionNumber = 0;// get option id
if (map.containsKey(questionNumber)) { // first check if question is registered
map.get(questionNumber).run(); // get runnable that is registered with exact questionNumber and run it
} else {
// print invalid question number
}
You can use reflection:
try {
Method m = MyClass.class.getDeclaredMethod("Question"+questionNum);
m.invoke(this);
} catch (NoSuchMethodException e) {
// Handle
}
But you should handle the exception properly, because it will most probably fail one day or another.
You can also use an enum to define each behavior and call the appropriate:
private static enum EnQuestion {
Question1 {
public void run(MyClass instance) {
// ...
}
},
Question2 {
...
},
...
QuestionN {
...
};
public void run(MyClass instance);
}
The enum has to be static so you can't access MyClass protected/private fields and methods.
Then call it:
EnQuestion.values()[numQuestion].run(this);

How do I create a Builder that can build more than one kind of Java object?

I’m trying to create a kind of Multi Strategy Builder. I mean this builder should be generalized and should have different method depends on entity type. Let me explain it.
Depends on entity we need to have different methods. Examples:
Builder<User> userBuilder;
userBuilder.withName(«Bob»);
userBuilder.withAge(17);
and this builder must have no others method!
Builder<Account> accountBuilder;
accountBuilder.withCounry(«Fr»);
accountBuilder.withNumber(2846218354);
accountBuilder.withCode(«X34»);
What pattern should I use? And how to organize my design?
If you're asking for a single Builder type that doesn't need to know anything about the entities it operates on, Java can't easily do it the way you describe. In the Builder<User> example, the withName and withAge methods would need to be known at compile-time.
Since those methods don't actually exist, but would need to be dynamically added, you'd have to write a custom class-loader. Once the Builder class is linked, you can't change it, and since it doesn't know what methods you want until you pass in an entity, it's too late to change at the point you need to add methods.
You could get mostly there by using reflection. For instance, you could have a single method in Builder called, say, with(String field, Class<?> c, Object value). Then, assuming the object instance you're building has a method named "set___", you can use the Method class to invoke the corresponding set method with the value that was passed in.
That would look something like:
Builder<Account> b = new Builder<>();
b.with("AccountNumber", String.class, "5897-1048-2949");
// this invokes "setAccountNumber" method on internal
// Account instance with "5897-1048-2949" cast to String
A better idea is to have classes for thing you're going to build: AccountBuilder, UserBuilder, and so on. This is clearer and is probably the best you can do in Java without resorting to exotic solutions like custom class-loaders. (Yes, you'll have to write the properties for each one.)
But if you decide you need to do a lot of building, you may want to consider an alternative language that makes this easier to pull off, like Ruby or Elixir. Dynamic methods are not Java's strong suit, and trying to circumvent a language's limitations just to achieve a particular API is generally a terrible idea.
It's not possible for generic interface to have different methods depending on passed to it class in Java. This means that Builder interface can have either:
withName and withAge methods
withCountry, withNumber and withCode methods
all of them
There is no design pattern that can overcome Java language limitations. What I would advise is to have generic builder interface like:
public interface Builder<T> {
T build();
}
and then create separate subclasses for each entity type:
public class UserBuilder implements Builder<User> {
public void withName(String name) {
// ...
}
public void withAge(int age) {
// ...
}
public User build() {
User user = new User();
user.setName(...);
user.setAge(...);
return user;
}
}
public class AccountBuilder implements Builder<Account> {
public void setCountry(String country) {
// ...
}
public void setNumber(String number) {
// ...
}
public void setCode(String code) {
// ...
}
public Account build() {
Account account = new Account();
account.setCountry(...);
account.setNumber(...);
account.setCode(...);
return account;
}
}
and then use it like
UserBuilder userBuilder = new UserBuilder();
userBuilder.setName("John");
userBuilder.setAge(20);
User user = userBuilder.build();
AccountBuilder accountBuilder = new AccountBuilder();
accountBuilder.setCountry("UA");
accountBuilder.setNumber("333-22-1");
accountBuilder.setCode("123");
And that's it. This can be slightly improved by using Fluent Interface pattern but anyway in Java it's impossible to implement it to work exactly like in your question.
Hope this helps...
First, adding dynamic methods is not very java like.
Builder is a creational pattern and strategy is behavioural. I would not mix them here.
Builder will create objects of a given TYPE. Do your USER and Account have a same type? IMO, unlike other design patterns books, the GoF book very effectively explains what a type of an object is. Do read the discussion. Given the code snippets, I wouldn't say user and account have same type. I would use different builders for building the objects of user and account. The type discussion will come in handy for strategy as well.

Design Pattern Advise

I have an class with a method which accepts an argument of particular type. The behavior of the method should be dependent on the specific class. For example,
public void doSomething(SomeInterface t) {
...
}
Depending on the actual class of the argument, I need the behavior to change. I need the outer class to perform an action based on the values found in T. Specifically, the outer class needs to construct a Hibernate criteria object which has restrictions which depend on the type of T, which is an implementation of a "Query" interface. The outer class is an implementation of a parameterized builder interface which constructs instances of objects which can be used to execute queries against a data store (for example, Criteria for hibernate, a SearchQueryBuilder for elasticsearch, etc). So as you can see, the problem with having t do the work is that it would require knowledge of HOW to construct these criteria which is beyond its intended purpose of just containing information about WHAT to query
It feels dirty and wrong to do something like
if (t instanceof X) {
...
} else if (t instance of Y) {
...
}
I see a couple problems here.
This requires previous knowledge about the types being passed in
The class is not "closed for modification" and will require a modification every time a new type needs to be supported.
Can someone suggest a good design pattern that can be used to solve this problem? My first thought is to use a factory pattern in combination with strategy and create instances of the class with a "handler" for a specific type. Another thought I had was to create a mapping of Class -> Handler which is supplied to the class at construction time.
Ideas appreciated.
The simplest idea would be to put the logic in the implementations of SomeInterface:
public interface SomeInterface {
public void actOnUsage();
}
public class SomeOtherClass {
public void doSomething(SomeInterface t) {
t.actonUsage();
}
}

combine multiple set functions into one generic setter in java

I have the a class with the following public methods:
public void setStartGameEvent(GameTypeMode gameTypeMode) {
gameTypeMode.setGameType(readIntFromConsole());
}
#Override
public void setComputerHeuristicEvent(GameTypeMode gameTypeMode) {
gameTypeMode.setComputerHeuristic(readIntFromConsole());
}
#Override
public void setBackgroundChoice(GameTypeMode gameTypeMode) {
gameTypeMode.setBackground(readIntFromConsole());
}
#Override
public void setBorderChoice(GameTypeMode gameTypeMode) {
gameTypeMode.setBorder(readIntFromConsole());
}
notes:
the class is a proxy, that's why the input of the function is where we want to set the data - the class is a consoleEventHandler, the main class does eventHandler.setBlah(GameTypeMode) and gets the data from the correct input method.
readIntFromConsole() is just reading an int from standart input and handels exceptions.
as you can easily see all the function are doing exactly the same, just with different set attributes.
my question is if there's a way to do it in a more generic\sophisticated way such as reflection or anything similar
edit: more explanations about this class
this class is a part of a game.
the input of the game can be from console\graphic display\ mouse etc.
the output (the game itself) is created accordingly to the input method that was chosen.
I have an eventHandler interface which define all the function that a specific input method should implement so the game would work (such as the functions above)
this means that I have consoleEventHandler, graphicEventHandler ...
now for each attribute I need to implement a set method for all eventHandler availabe (which might be a lot), that's why i'm asking this question about generalizing the set function for each eventHandler
Anything you come up with will be more complicated than the obvious, straight-forward code shown.
At this level of abstraction, with this trivial amount of "duplication", the cost far outweighs any benefits.

Why is the following interface contract not allowed?

I'm thinking about offering a new feature to Java and I would like to ask why have it been restricted by design so far:
public abstract class BodyPart {
abstract public void followBodyPart(BodyPart part);
}
public class Head extends BodyPart{
public void followBodyPart(Body body ) { //Why is this kind of implementation not allowed?
...
}
}
public class Body extends BodyPart{
public void followBodyPart(Head head ) { //and this
...
}
public void followBodyPart(Forearm leftForearm ) { //and also this
...
}
...
}
//Arm, Forearm, etc...
Why is followBodyPart(Body body) in Head not implementing followBody in BodyPart? If it would, the advantages would be clear.
Firstly, the IDE would be able to offer within it's autocomplete feature Body objects as parameters to followBody instead of any other BodyParts objects that Head can not follow.
Secondly, the current version of Body consists of one function and many instanceof's, which could be eliminated.
Finally, generics can help here but not solve the problem, since this code should be ported to Java ME devices.
This question was already asked, in the not appropriate forum as I discovered here
In regards to the answers, I invite you to think different. I understand that anything implementing BodyPart should accept any BodyPart, but: what I want is to be able to say that Head would be able to accept A BodyPart to follow.
Thanks.
The question was also answered in the forum post you linked..
Namely; the interface defines the function should be able to accept anything that implements BodyPart.
By implementing the function in Head to only accept the subclass Body, but not any other subclass; you are violating that contract (since it no longer accepts anything implementing BodyPart).
Interfaces are usually used to provide to "external" code, allowing them to be sure that, whichever implementation of the interface is provided; they can for sure use the functions defined by the interface.
So if this external code gets an BodyPart, it knows it has a function followBodyPart that can accept anything extending BodyPart as argument. That external code will, however, never know that it got Head (or can, after casting it after an instanceof check) and thus cannot know that the interface function will only accept a Body.
By request; say that you provide the BodyPart interface as some kind of program API. In that case, I do not directly need to know what type of BodyPart it is. Now say that I have two of them; received through some functions in your API, for example with the signature: public BodyPart getBody(). The method states it might be a Body I get back; but it could as well be something else (fact is, I don't know!).
According to the BodyPart interface; I can call followBodyPart on the first BodyPart, and pass the second one in as argument. However, the actual Body implementation would not allow this; and there is no way for me to know that.
If you really want different classes to accept different entries; you should either drop the function from BodyPart and just implement it in the subclasses.
By passing those subclasses back from the API; everyone knows what they're talking with, and what it can do (e.g. public Body getBody() and public Head getHead()). Since I then have the actual implementation classes, which have the actual implementation with a certain BodyPart to 'follow', it isn't a problem.
An other option would be - but stated impossible in your question - to use generics; in such case you can define an Interface stating:
public interface Accepts<T extends BodyPart> {
public void followBodyPart(T part);
}
And the API could pass back either the implemented BodyPart, or an Accepts<Head> instance, for example.
(Edit: as I wrote this here, I forgot to keep in mind you cannot implement the same interface more then once with different generic types; so the generic interface method would need the actual implementation to encapsulate objects that can actually handle the calls, making everything even more a mess)
Bonus edit: ofcourse you can also make AcceptsHead, AcceptsArm as interfaces and effectively working around the generics issue :).
I hope this edit clears up why it would be a weird (and bad) idea to have a generic interface (using BodyPart as argument), but only specify specific implementations in the (possibly hidden) implementation classes.
First of all, I'm not quite intuitively understanding your class relationships - they are circular which is already an indication of a bad design. I'm not saying you don't happen to NEED that particular structure - I would just suggest that some refactoring to remove the circularity might ultimately be a better design.
What it looks like you're trying to do is implement a visitor-pattern. But if you have a reference to the base class, it could never trigger the invocation of the specialized methods - e.g. since the compiler can't pick the method you intended, then the runtime is just going to have to do the instance-of switching for you - it would only be syntactic sugar at best (look up scala, they actually do that).
def bodyPart(part:BodyPart) =>
part match {
Head(h) => /* do something with head h */
Foot(f) => /* do something with foot f */
Toe(t) => /* do something with toe t */
}
The other way to solve this is to abstractly noop all possible visitor types:
public class BodyPart { // could have been abstract class
public void followBodyPart(BodyPart part) { }
public void followBodyPart(Head part) { }
public void followBodyPart(Arm part) { }
public void followBodyPart(Foot part) { }
public void followBodyPart(Toe part) { }
}
public class Head { ... /* only implements Head, BodyPart, others error */ }
public class Arm { ... /* only implements Arm, Abdomen, etc */ }
Now the visitor invoker will staticly choose the correct method at compile time. But it needs more plumbing in each implementation because it needs to decide how to properly handle all the other input types. But that's a good thing - it removes ambiguity.

Categories