简体   繁体   中英

Strategy Pattern: How to make classes with constructors as enums?

I'm creating a Strategy pattern in Java.

This is my Strategy Interface ActivationStrategy.java :

public interface Strategy {
    public void strategyAlgo(JTextField textField);
}

I have different classes which implement the Interface. Those classes have a constructor because it's necessary to passing values. For example:

FirstStrategy.java

public class FirstStrategy implements Strategy{
    private JComboBox<String> _comboBox;

    public FirstStrategy(JComboBox<String> comboBox) {
        _comboBox = comboBox;
    }

    public void strategyAlgo(JTextField textField) {
        textField.addKeyListener(new myKeyHandler(_comboBox, textField));
    }

SecondStrategy.java

public class SecondStrategy implements Strategy{
    private JPanel _panel;

    public secondStrategy(JPanel panel) {
        _panel = panel;
    }

    public void strategyAlgo(JTextField textField) {
        addActionHandlerToButton(addButton(_panel));
    }

    public JButton addButton(JPanel panel) {
        JButton button = new JButton("Click me");
        panel.add(button);
        return button;
    }

    public void addActionHandlerToButton(JButton okButton) {
        Action action = new AbstractAction(){    
            public void actionPerformed(ActionEvent e) {
                System.out.println("Hi");           
            }
        };
        button.addActionListener(action);           
    }
}

Now, I would like to make the classes as enums. Something like:

public enum strategies {

    FIRSTSTRATEGIE(){
      @Override
        public void strategyAlgo() {
        ...
        }
    },
    SECONDSTRATEGY(){
      @Override
        public void strategyAlgo() {
        ...
        }
        public JButton addButton(JPanel panel) {
        ...
        }
        public void addActionHandlerToButton(JButton okButton) {
        ...
        }
    };

    public abstract void strategyAlgo();

}

But what about the constructors?

My criteria when enum s are a viable choice?

  1. When the number of instances are determined at compile time.
  2. When the state of each instance is determined at compile time.
  3. When your instances do not hold mutable state.

In your case criterion 2. is not true . Hence in my opinion you should not model your strategies as enum s.

You cannot create an arbitrary instance of an enum at runtime. Therefore, you cannot pass anything to an enum's constructor that is not known at compile time. You can pass dynamic arguments by changing list of arguments in your abstract method.

You can create a constructor in an Enum but it can be private only, so you cannot use it to create an arbitrary instance at runtime. This way it is guaranteed that there is only one instance of a particular enum value.

For example:

public enum Suit {
  SPADES("spades"),
  HEARTS("hearts"),
  CLUBS("clubs"),
  DIAMONDS("diamonds");

  private String label;

  private Suit(String label) {
    this.label = label;
  }

}

BTW, private keyword is optional for a constructor in case of an enum . It's private by default.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM