combine multiple set functions into one generic setter in java - 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.

Related

How to avoid empty visit functions in visitor pattern?

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...

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);

In Java can I listen for an action to occur in one class then take a parallel action?

I need to monitor for an error that is occurring in a particular method in a Java class that cannot be changed because it is owned by a third party.
This method gets invoked by a particular feature within the system that will end up causing several hoops to be jumped in order to fix it (because only
a generic error is written to the UI and logs - we will pursue getting the owner of the class (an external vendor) to fix it, but it will likely take while).
As a workaround, I have de-compiled the class and added logger statements that print the data elements that are causing the issue. This can be run
externally and only when granted permission to do so, and cannot be put in the Production environment (because of contract and other issues).
Is it possible to "listen" for this method being called without actually editing the original class? Or is there some other suitable workaround I am not thinking of?
EDIT
I agree with Paul Boddington that this might be an XY problem. You can use one of the solutions below, but perhaps you have a different problem than you describe. You might want to reconsider the thing you actually want to achieve.
You have several options:
You can subclass class 'A', and then when the event occurs, notify registered listeners, like this:
public class SubA extends A {
private AListener listener;
public void method1() {
if (this.listener != null) {
this.listener.notifyMethodCall();
}
super.method1();
}
public void setAListener(AListener listener) {
this.listener = listener;
}
}
And the AListener interface:
public interface AListener {
void notifyMethodCall();
}
Class B:
public class B implements AListener {
public B(A a) {
a.setAListener(this);
}
public void notifyMethodCall() {
// Do whatever you want.
}
}
If the method call A.method1() changes an attribute of itself, you could check its value interval-based, for example, each second check its value, but that's generally bad in this context.
It can be that class A cannot be overridden because it is a final class, but that's generally considered as a bad design. The String class is, however, an exception.
Yes, I believe you can also do it with an AOP listener. You can define advice before an event happens, during, or after.

Run extra code for any method in a class

I have some code I want to run every time any method is invoked in a specific Java class, but don't want to touch the actual method bodies. This is because there are a lot of methods that change frequently, and the people programming these methods shouldn't have to worry about adding my code to every method.. even if it is just a single line that calls another method.
I can't think of a way to achieve this with inheritance, so I was wondering if it is possible with reflection? Or even at all?
It's possible to get a list of methods in a class, inspect their properties and even invoke them. But I'm not seeing anything that lets you attach extra code, such as an event handler for example. Maybe Java is the wrong language for something like this..
This is very common behavior, where Aspect Oriented Programming is definitely the right thing to use.
But I also get impressed with how the famous CMS does it.
For each class which contains the concrete method around, you can have a property (List of methods) which contains the code you want to execute before the method call.
You can write a registerBeforeCall(Method m) method which takes a method and adds to teh list.
Your method should contain a for loop at the first line(which goes through the list of methods) and invoke each of the method one by one.
Do not forget to put a try and catch and ignore the exception if there is any in the invocations.
For e.g. :
public void myActualMethod(){
for(Method m : registeredMethodsToCallBeforeActualCode){
m.invoke();
}
//my actual code
// here you can also write a for loop to execute all the methods which you want to call after your actual code is executed.
}
This approach is not very special, but is widely use, when you do not choose AOP.
one way to implement it by inheritance is:
public SuperClass {
public void doSomething() {
doBefore();
doSpecific();
doAfter();
}
protected abstract void doSpecific();
}
public SubClass extends SuperClass {
protected void doSpecific() {
System.out.println("Do specific implementation....");
}
}
public static void main(String[] args) {
SuperClass clazz = new SubClass();
clazz.doSomething();
}

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