I want to override method from class that's already assigned to a variable.
For example:
inventory = new Inventory( );
/* Some code here that changes how inventory
must behave or whatever */
inventory
{
#Override ...
}
Is it possible ???
Maybe you think of something like this (instead of the null-if you could implement a default strategy to make it more clean):
public interface Strategy {
public void doSomething();
}
public class Inventory {
Strategy strategy;
public Inventory() {
// ...
}
public void doSomething() {
if (strategy == null) {
System.out.println("strategy is empty");
} else {
strategy.doSomething();
}
}
public Strategy getStrategy() {
return strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
}
Then this
Inventory inventory = new Inventory();
inventory.doSomething();
inventory.setStrategy(new Strategy() {
#Override
public void doSomething() {
System.out.println("strategy is now something different");
}
});
inventory.doSomething();
shows this:
strategy is empty
strategy is now something different
For a more elaborated version you can take a look at the strategy pattern.
Composition would definitely help here. Rather than overriding a method to change the behavior of Inventory, pass it the method:
class Inventory {
private MyMethod method;
public void setMethod(MyMethod method) {
this.method = method;
}
public void doSomething() {
method.doSomething();
}
}
interface MyMethod {
void doSomething();
}
You can now switch the implementation of MyMethod via setMethod:
Inventory inv = new Inventory();
//...
inv.setMethod(() -> {
//write method here
});
If you aren't using Java 8, you'll have to subclass MyMethod:
inv.setMethod(new MyMethod() {
public void doSomething() {
}
});
Related
I'm trying to write a generic code. Here is my scenario.
class AEvent {
public void onAEventCreate( A event){
//do something
}
}
class BEvent {
public void onBEventCreate (B event) {
//do something
}
}
I want to have some generic class which could do the operation of method onAEventCreate and onBEventCreate on one single method. Now the catch is I do not want to change the classes AEvent and BEvent . Is there a way I can listen to the two methods? or is there some kind of design pattern maybe like observer which can help me achieve this.
There are a lot of ways to do this, if you want to use the Observe Pattern an example would be :
You create an ObserverEvent class
class EventObserver {
private AEvent aEvent;
private BEvent bEvent;
public EventObserver(AEvent aEvent, BEvent bEvent) {
this.aEvent = aEvent;
this.bEvent = bEvent;
aEvent.setObserver(this);
bEvent.setObserver(this);
}
public void onEventCreated() {
if (aEvent.isAEventCreated && bEvent.isBEventCreated) {
onBothEventsCreated();
}
}
public void onBothEventsCreated() {
//this method will be called when both events are created
}
}
Then you need to adapt your classes to this :
class BEvent {
private boolean isBEventCreated = false;
private EventObserver observer;
public void setObserver(EventObserver observer) {
this.observer = observer;
}
public void onBEventCreated() {
this.isBEventCreated = true;
observer.onEventCreated();
}
}
And the same with AEvent.
I have a code block like below:
public Interface ISupClass{
void call();
void call1();
...
}
public class NormalClass implements ISupClass{
void call(){
....operations...
}
void call1(){
....operations...
}
...
}
public class DailyClass implements ISupClass{
void call(){
....operations...
}
void call1(){
....operations...
}
...
}
Then I call them from main service like that;
Instances:
private INormalClass dailyClass = new DailyClass();
private INormalClass normalClass = new NormalClass();
Method:
public void call(int type, boolean isDaily){
if(type == 0) {
if(isDaily){
dailyClass.call();
}
else{
normalClass.call();
}
}
if(type == 1) {
if(isDaily){
dailyClass.call1();
}
else{
normalClass.call1();
}
}
...
}
Is there a way to escape from isDaily check in above code block? Or how can I implement it effectively? I have just tried to implement with Java Generics but this doesn't look possible?
I know this looks like related with polimorfizm. But I wonder somethink like about it;
public Interface ISupClass<E>
call(E type)
...
public class NormalClass implements ISupClass<Boolen.FALSE>
...
public class DailyClass implements ISupClass<Boolen.TRUE>
...
public void call(int type, boolean isDaily){
supClass.call(isDaily);
(In case I understood what is the question)
This is the point of using interfaces. Simply do something like this:
public class Example {
public static interface ISupClass {
void doSomething();
}
public static class NormalClass implements ISupClass {
#Override
public void doSomething() {
System.out.println("I am a normal class.");
}
}
public static class DailyClass implements ISupClass {
#Override
public void doSomething() {
System.out.println("I am a daily class.");
}
}
public static void doSomething(ISupClass clazz) {
clazz.doSomething();
}
public static void main(String[] args) {
doSomething(new DailyClass());
doSomething(new NormalClass());
}
}
So, in your case instead of passing boolean isDaily, pass argument ISupClass in call method.
public void call(int type, ISupClass caller) {
caller.call();
}
Now, generics is a totally different story and I am not able to see how it is related to the question.
From what I understand, public void call(int type, boolean isDaily){...} is an orchestrator/mediator method that manipulates the one or the other instance according to the flags received in the parameters.
In this case, why not use a Map<Boolean, INormalClass> to store the two instances in a way where you can retrieve them from a boolean key :
Map<Boolean, INormalClass> map = new HashMap<>();
map.put(Boolean.TRUE, new DailyClass());
map.put(Boolean.FALSE, new NormalClass());
//...
public void call(int type, boolean isDaily){
INormalClass obj = map.get(isDaily);
if(type == 0) {
obj.call();
}
if(type == 1) {
obj.call1();
}
}
You could add default method to the interface:
public interface ISupClass {
default void call(int type) {
if (type == 0) {
call();
} else if(type == 1) {
call1();
}
}
void call();
void call1();
}
It leads you to following code:
public static void call(int type, boolean isDaily) {
if (isDaily) {
dailyClass.call(type);
} else {
normalClass.call(type);
}
}
I'm trying to get rid of big switch statement from my code and I thought that Strategy pattern based on my existing enum would be nice. The concept is like:
public class MyStrategy {
public MyStrategy() {
Option.Option1.setMethodToExecute(this::action1);
Option.Option2.setMethodToExecute(this::action2);
}
public void executeChoosenMethod(int i) {
Option.values()[i].execute();
// instead of
// switch(convertItoOption()) {
// case Option1:...
// case Option2:...
// }
}
private void action1() {
System.out.println("action1");
}
private void action2() {
System.out.println("action2");
}
private enum Option {
Option1, Option2;
private InvokeAction methodToExecute;
public void setMethodToExecute(InvokeAction methodToExecute) {
this.methodToExecute = methodToExecute;
}
public void execute() {
methodToExecute.execute();
}
}
#FunctionalInterface
private interface InvokeAction {
void execute();
}
}
so I can use it like:
public class StrategyTest {
public static void main(String[] args) {
MyStrategy strategy = new MyStrategy();
//user choose 0 or 1
strategy.executeChoosenMethod(0);
strategy.executeChoosenMethod(1);
}
}
but I don't like this part with Option.Option1.setMethodToExecute(this::action1); since my enum has more and more options and I would like to have all of this inside enum. What would be perfect is something like this:
public class MyStrategy {
public void executeChoosenMethod(int i) {
Option.values()[i].execute();
}
private void action1() {
System.out.println("action1");
}
private void action2() {
System.out.println("action2");
}
private enum Option {
Option1(MyStrategy.this::action1),
Option2(MyStrategy.this::action2);
private InvokeAction methodToExecute;
private Option(InvokeAction method) {
methodToExecute = method;
}
public void execute() {
methodToExecute.execute();
}
}
#FunctionalInterface
private interface InvokeAction {
void execute();
}
}
but this is impossible since enum is static and I don't have access to enclosing instance by MyStrategy.this. I need enum, because I have set of options and it is convenient to use methods like values() or valueOf(), but what I would like to have is single line invoke instead of growing switch.
Do you have any ideas how to achieve sometghing like this or is there any workaround to make this enum constructor call possible Option1(MyStrategy.this::action1) ?
With enums you could implement it like this:
public class MyStrategy {
public void executeChoosenMethod(int i) {
Option.values()[i].execute(this);
}
private void action1() {
System.out.println("action1");
}
private void action2() {
System.out.println("action2");
}
private enum Option {
Option1(MyStrategy::action1),
Option2(MyStrategy::action2);
private InvokeAction methodToExecute;
private Option(InvokeAction method) {
methodToExecute = method;
}
public void execute(MyStrategy s) {
methodToExecute.execute(s);
}
}
#FunctionalInterface
private interface InvokeAction {
void execute(MyStrategy s);
}
}
This uses the fact the with lambdas you can make method references to arbitrary instance methods and call them on a specific instance by passing in the instance as first parameter.
you're right. This isn't possible with enum. But why not just use a good old class:
public class MyStrategy {
public MyStrategy() {
buildUp();
}
public void executeChoosenMethod(int i) {
actions.get(i).execute();
}
private void action1() {
System.out.println("action1");
}
private void action2() {
System.out.println("action2");
}
private List<InvokeAction> actions = new ArrayList<>();
private void buildUp() {
actions.add(this::action1);
actions.add(this::action2);
}
#FunctionalInterface
private interface InvokeAction {
void execute();
}
}
Consider a method
public void doSomething(String actionID){
switch (actionID){
case "dance":
System.out.print("I'm dancing");
break;
case "sleep":
System.out.print("I'm sleeping");
break;
default:
System.out.print("I've no idea what I'm doing");
}
The implementation of the method depends on the value of the parameter. Is there a more elegant way to do this, or a different design pattern to replicate the behaviour?
If the caller decides what logic is executed by passing different strings, then why not just have them call different methods:
public void doSomething(String actionID) {...}
...
doSomething("dance");
doSomething("sleep");
VS.:
public void dance() {...}
public void sleep() {...}
...
dance();
sleep();
It seems like you're unnecessarily funnelling all the calls into doSomething
But the strings might not always be literals. What if you're taking them from the console?
You could provide static mappings from the strings to the corresponding functions:
class MyClass {
private static final Map<String, Consumer<MyClass>> map = new HashMap<>();
static {
map.put("sleep", MyClass::sleep);
map.put("dance", MyClass::dance);
}
public void doSomething(String actionID) {
map.getOrDefault(actionID, MyClass::doNothing).accept(this);
}
public void dance() {
System.out.print("I'm dancing");
}
public void sleep() {
System.out.print("I'm sleeping");
}
private void doNothing() {
System.out.println("I've no idea what I'm doing");
}
}
This makes scenarios where you have a lot of switch cases a lot cleaner.
Introduce an interface, e.g.
public interface HumanState {
public void tellMeWhatYouAreDoing();
}
encapsulate the logic in different implementations
public class DancingState implements HumanState {
#Override
public void tellMeWhatYouAreDoing() {
System.out.println("I'm dancing");
}
}
public class SleepingState implements HumanState {
#Override
public void tellMeWhatYouAreDoing() {
System.out.println("I'm sleeping");
}
}
public class UnknownState implements HumanState {
#Override
public void tellMeWhatYouAreDoing() {
System.out.println("I've no idea what I'm doing");
}
}
and use a map. E.g.
public class HumanStateExample {
public static void main(String[] args) {
HumanStateExample humanStateExample = new HumanStateExample();
humanStateExample.doSomething("dance");
humanStateExample.doSomething("sleep");
humanStateExample.doSomething("unknown");
}
private final HashMap<String, HumanState> humanStateMap;
public HumanStateExample(){
humanStateMap = new HashMap<String, HumanState>();
humanStateMap.put("dance", new DancingState());
humanStateMap.put("sleep", new SleepingState());
}
public void doSomething(String action) {
HumanState humanState = humanStateMap.get(action);
if(humanState == null){
humanState = new UnknownState();
}
humanState.tellMeWhatYouAreDoing();
}
}
I'm not sure how the pattern is called, but it is very useful if you need to delegate the method call based on more than one parameter:
Create a lot of handlers where each one knows when it is responsible for handling a call. Then just loop through them and invoke the first one matching the parameter.
edit: I renamed the class from FancyParameterActionFactory to FancyParameterActionUtility: it is not a factory, the name was misleading
//Your method, but this time with a complex object, not with a simple string.
public void doSomething(FancyParameterObject fpo){
FancyParameterActionUtility.invokeOn(fpo);
}
//The utility which can handle the complex object and decides what to do.
public class FancyParameterActionUtility{
public Interface FPAHandler{
void invoke(FancyParameterObject fpo);
boolean handles(FancyParameterObject fpo);
}
//Omitted: Different implementations of FPAHandler
public static List<FPAHandler> handlers = new LinkedList<>();
static{
handlers.add(new DanceHandler());
handlers.add(new SleepHandler());
//Omitted: Different implementations of FPAHandler
}
public static void invokeOn(FancyParameterObject fpo){
for(FPAHandler handler:handlers){
if (handler.handles(fpo)){
handler.invoke(fpo);
return;
}
}
//Default-Behavior
}
}
Here is a simple implementation of the command pattern based your sample problem. I define a general AbstractCommand abstract class which contains two methods. The first method, createCommand(), instantiates a command class based on an input string name. This is how you can delegate your string input to create the right type of command. The second method is doAction(), and this is left undefined, to be implemented later on by specific concrete command classes.
public abstract class AbstractCommand {
public static AbstractCommand createCommand(String name) {
try {
String clsName = name + "Command";
Class<?> cls = Class.forName(clsName);
AbstractCommand command = (AbstractCommand) cls.newInstance();
return command;
}
catch (Exception e) {
System.out.println("Something went wrong.");
}
}
public abstract void doAction();
}
public class DanceCommand extends AbstractCommand {
public void doAction() {
System.out.println("I'm dancing");
}
}
public class TestCommandPattern {
public void doSomething(String actionID) {
AbstractCommand cmd = AbstractCommand.createCommand(actionID);
cmd.doAction();
}
public static void main(String[] args) {
TestCommandPattern test = new TestCommandPattern();
test.doSomething("Dance"); // should print "I'm dancing"
}
}
Now that this framework has been setup, you could easily add other commands for the various types of actions in your original problem. For example, you could create a SleepCommand class which would output I'm sleeping, or do whatever action you wish.
This question already has an answer here:
Methods in Enums [duplicate]
(1 answer)
Closed 8 years ago.
Right now, I have an enum for a variety of values, and I was wondering if there is any way I would be able to store a method in an enum. For example:
public enum myEnum{
one("first", callFirstMethod),
two("second", callSecondMethod),
three("last", callThirdMethod);
public String message;
public Method met;
myEnum(String m, Method meth){
message = m;
met = meth;
}
}
public class myMethods{
public void callFirstMethod(){
System.out.println("First!");
}
public void callSecondMethod(){
System.out.println("Second!");
}
public void callThirdMethod(){
System.out.println("Third!");
}
}
Then by using something like:
Method method = myEnum.one.callFirstMethod();
To call the method. Is something like this possible? I've tried playing around/looking around on google, and nothing is really turning up. Thank you for the help!
Use an interface and have the interface instance as the second enum parameter, or give it an abstract method that is implemented in the instance. For instance:
enum MyEnum {
ONE("first", new MyInterface() {
#Override
public void commonMethod() {
System.out.println("First!");
}
}) {
#Override
public void abstractEnumMethod() {
System.out.println("abstract enum meuthod, first!");
}
},
TWO("second", new MyInterface() {
#Override
public void commonMethod() {
System.out.println("Second!");
}
}) {
#Override
public void abstractEnumMethod() {
System.out.println("abstract enum meuthod, second!");
}
},
THREE("last", new MyInterface() {
#Override
public void commonMethod() {
System.out.println("Third!");
}
}) {
#Override
public void abstractEnumMethod() {
System.out.println("abstract enum meuthod, third!");
}
};
private String message;
private MyInterface myType;
private MyEnum(String m, MyInterface myType) {
message = m;
this.myType = myType;
}
public String getMessage() {
return message;
}
public MyInterface getMyType() {
return myType;
}
public void enumMethod() {
System.out.println(message);
}
public abstract void abstractEnumMethod();
}
interface MyInterface {
void commonMethod();
}
The answer all depends on what it's you want to achieve. For example, you could provide a common method within you enum and inspect the instance of the enum calling it...
public class TestEnum {
public static void main(String[] args) {
MyEnum.ONE.doStuff();
MyEnum.TWO.doStuff();
MyEnum.THREE.doStuff();
}
public enum MyEnum {
ONE("first"),
TWO("second"),
THREE("last");
public String message;
MyEnum(String m) {
message = m;
}
public void doStuff() {
System.out.println(name());
if (ONE.equals(this)) {
System.out.println("...Do stuff for one");
} else if (TWO.equals(this)) {
System.out.println("...Do stuff for two");
} else if (THREE.equals(this)) {
System.out.println("...Do stuff for three");
}
}
}
}
Which outputs...
one
...Do stuff for one
two
...Do stuff for two
three
...Do stuff for three