代码之家  ›  专栏  ›  技术社区  ›  user141335

参数化策略模式

  •  6
  • user141335  · 技术社区  · 14 年前

    interface Strategy {
         public data execute(data);
    }
    
    class StrategyA implements Strategy {
         public data execute(data);
    }
    
    class StrategyB implements Strategy {
          public StrategyB(int paramA, int paramB);
          public data execute(data);
    }
    
    class StrategyC implements Strategy {
          public StrategyC(int paramA, String paramB, double paramC);
          public data execute(data);
    }
    

    现在我希望用户可以在某种UI中输入参数。UI应该在运行时选择,即策略应该独立于它。参数对话框不应该是单一的,并且应该有可能使它的行为和每个策略和UI(例如控制台或Swing)的外观不同。

    你将如何解决这个问题?

    4 回复  |  直到 14 年前
        1
  •  4
  •   Eyal Schneider    14 年前

    一种可能的做法是采用类似于生成器设计模式的方法:

    对于每种策略类型,都应该有相应的生成器(一个或多个)。构建器不能作为一个普通的构建器工作,它接收所有的init参数作为方法参数;相反,它应该 直到收到相关的输入。一些构建器将显示一个Swing对话框并等待,其他的将打印到控制台并等待输入,其他的可以从文件中读取,等等。在一个构建器接收到所有输入后,它可以创建策略实例并返回它。

    这样就可以将数据检索逻辑与策略本身分离。

        2
  •  1
  •   Spoike Otávio Décio    14 年前

    这个问题的解决主要取决于什么决定了当前的策略。为了简单起见,我假设所有策略的UI都是相同的。

    interface StrategyPicker {
        public Strategy getStrategy();
    }
    
    // Most likely used in the JFrame it is added to
    class StrategyPickerUI extends JPanel implements StrategyPicker {
        // initialize the panel with all the widgets
        // and implement the getStrategy method. the getStrategy
        // method should be called after the input is done in this
        // panel (such as clicking an Ok or Apply button)
    }
    
    // You can also make one for the console app
    class StrategyPickerSimple implements StrategyPicker {
        // ...
    }
    

    如果你想变得更有趣,你可以创建一个简单的工厂类,将创建的行为移除到它自己的类中:

    public class StrategyFactory() {
        public static Strategy createStrategyFromParameters(StrategyParams sp) {
            // creates the Strategy object... doesn't need to be public static
            // and if it isn't, it will help making unit tests easier
        }
    
        // This nested class could be split up to StrategyAParams, 
        // StrategyBParams, StrategyCParams
        public class StrategyParams {
            data paramA; 
            int paramB_A;
            int paramB_B;
            int paramC_A;
            String paramC_B;
            float paramC_C;
        }
    }
    
    // in StrategyPickerUI class
        public getStrategy() {
            StrategyParams sp = new StrategyParams();
            sp.paramB_A = myJTextFieldParamB_A.getText();
               // and so on...
            return StrategyFactory.createStrategyFromParameters(sp);
        }
    

        3
  •  0
  •   Guillaume    14 年前

    如果参数类包含简单对象(数字、布尔值、日期、字符串),则可以在运行时尝试生成接口。

    为组合对象和参数集合生成UI将更加困难

    看看 Metawidget 它是一个强大的ui生成器。

        4
  •  0
  •   Огњен Шобајић    12 年前

    我建议先搜索“参数化策略模式”。有文章可能正是你要找的 http://www.hillside.net/plop/2010/papers/sobajic.pdf