Storing Methods in an Enum? [duplicate] - java

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

Related

How to extract the common condition check in a class

If I have a class, where all methods should evaluate only if a boolean attribute is true, what is the best way to define it in terms of best practices?
Is there a way to replace the recurring isEnabled check in all the methods by a single check? The current form works, I'm looking for a way to improve it to not have isEnabled checked in all the methods.
#Singleton
public class SomeClass implements SomeInterface {
EventPublisher eventPubilsher;
boolean isEnabled;
#Inject
public SomeClass(final Decider decider, EventPublisher, eventPublisher) {
this.isEnabled = decider.isSomethingEnabled();
this.eventPublisher = eventPublisher;
}
#Override
public void method1() {
if(isEnabled){
eventPublisher.publishSomething1();
}
}
#Override
public void method2() {
if(isEnabled){
eventPublisher.publishSomething2();
}
}
#Override
public void method3() {
if(isEnabled){
eventPublisher.publishSomething3();
}
}
}
You can have implementation for enabled stuff, and one for disabled stuff. The disabled implementation won't do anything:
public class DisabledSomeClass implements SomeInterface {
#Override
public void method1() {
}
#Override
public void method2() {
}
#Override
public void method3() {
}
}
Enabled one will publish stuff:
public class EnabledSomeClass implements SomeInterface {
EventPublisher eventPublisher;
public EnabledSomeClass(EventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
#Override
public void method1() {
eventPublisher.publishSomething1();
}
#Override
public void method2() {
eventPublisher.publishSomething2();
}
#Override
public void method3() {
eventPublisher.publishSomething3();
}
}
Then extract the logic, if functionality is enabled in new factory class - SomeInterfaceFactory (probably not the best name, but you get the idea), it will return the correct implementation, depending on whether something is enabled.
public class SomeInterfaceFactory {
public static SomeInterface getInstance(Decider decider, EventPublisher eventPublisher) {
if (decider.isSomethingEnabled()) {
return new EnabledSomeClass(eventPublisher);
} else {
return new DisabledSomeClass();
}
}
}
This should work
#Singleton
public class SomeClass implements SomeInterface {
EventPublisher eventPubilsher;
boolean isEnabled;
#Inject
public SomeClass(final Decider decider, EventPublisher, eventPublisher) {
this.isEnabled = decider.isSomethingEnabled();
this.eventPublisher = eventPublisher;
}
#Override
public void method1() {
publish(ep->ep.publishSomething1());
}
#Override
public void method2() {
publish(ep->ep.publishSomething2());
}
#Override
public void method3() {
publish(ep->ep.publishSomething3());
}
private void publish(Consumer<EventPublisher> callback){
if(isEnabled) callback.accept(eventPublished);
}
}
A Runnable interface can receive a lambda without args and run a lambda function with run() method. So, you can create a method inside your Decider class and receive a Runnable as a parameter, like:
class Decider{
private boolean enabled;
//...
public void execute(Runnable runnable){
if(enabled) runnable.run();
}
}
And receive your Decider and do:
//...
EventPublisher eventPubilsher;
Decider decider;
#Inject
public SomeClass(final Decider decider, EventPublisher, eventPublisher) {
this.decider = decider;
this.eventPublisher = eventPublisher;
}
#Override
public void method1() {
Decider.execute(() -> eventPublisher.publishSomething1());
}
//...
You're locking the evaluation of the condition to the constructor. If you want any flexibility, you should pull it out.
public class SomeClass implements SomeInterface {
boolean isEnabled;
public SomeClass(EventPublisher, eventPublisher) {
//
}
public void addDecide(boolean value){
isEnabled = value;
}
boolean getEnabled(){
return isEnabled;
}
#Override
public void method3() {
if(getEnabled()){
eventPublisher.publishSomething3();
}
}
}
You can even go crazy and add a supplier:
public void addDecide(Supplier<Boolean> supplier){
supplier = supplier;
}
boolean getEnabled(){
return supplier.get();
}

Is there a way to give boolean type as generic in Java?

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

Strategy pattern with inner enum

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

Java - Method implementation dependent from parameter value

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.

Create Enum with list of the same object

I would like to create an enum containing one attribut, a list of objects extending the same interface or the same abstract class.
The objective is to have a loop on each list of my enum to call methods dynamically.
public interface Regles {
void verifier();
}
public class Regle01 implements Regles {
#Override
public void verifier() {
}
}
public class Regle02 implements Regles {
#Override
public void verifier() {
}
}
public enum ListRegles {
ENUM1(Arrays.asList(new Regle01(), new Regle02())),
ENUM2(Arrays.asList(new Regle01()))
private List<Regles> regles = new ArrayList<Regles>();
ListRegles(List<Regles> r) {
regles = r;
}
}
how can i do this please ?
enum:
public enum ListRegles {
ENUM1(new Regle01(),new Regle02()),
ENUM2(new Regle01());
private List<Regles> regles ;
ListRegles(Regles... regles) {
this.regles = new ArrayList<>(Arrays.asList(regles));
}
public void verify() {
for (Regles regle : regles) {
regle.verifier();
}
}
}
Will call verifier for Regle01 and Regle02
ListRegles.ENUM1.verify();

Categories