zoukankan      html  css  js  c++  java
  • Java设计模式—策略模式

         

    1、策略模式(Strategy Pattern)是一种比较简单的模式,也叫做政策模式(PolicyPattern)。

    定义如下:
        Define a family of algorithms,encapsulate each one,and make them interchangeable.

       (定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。)


    策略模式的通用类图如下所示:

    策略模式的三个角色:

    ● Context                        封装角色

    它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。


    ● Strategy                      抽象策略角色

    策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性、


    ● Concrete Strategy      具体策略角色

    实现抽象策略中的操作,该类含有具体的算法。

     

    策略模式即在封装角色的构造函数中将某个具体策略传入,然后执行这个策略。


    策略模式通用源码如下: 

    public class Test3 {
    	public static void main(String[] args) {
    			
    		//声明一个具体的策略
    		 Strategy strategy = new ConcreteStrategy1();
    		 //声明上下文对象
    		 Context context = new Context(strategy);
    		 //执行封装后的方法
    		 context.doAnythinig();
    
    
    		
    	}
    }
    
    interface Strategy {
        //策略模式的运算法则
        public void doSomething();
    }
    
    class ConcreteStrategy1 implements Strategy {
    	
        public void doSomething() {
                System.out.println("具体策略1的运算法则");
        }
    }
    class ConcreteStrategy2 implements Strategy {   
    	
    	public void doSomething() {
                System.out.println("具体策略2的运算法则");
        }
    }
    
    class Context {
        //抽象策略
        private Strategy strategy;  
        //构造函数设置具体策略
        public Context(Strategy _strategy){
                this.strategy = _strategy;
        }
        //封装后的策略方法
        public void doAnythinig(){
                this.strategy.doSomething();
        }
    }
    
    
    
    
    
    


    策略模式的优点:


    ● 算法可以自由切换
         这是策略模式本身定义的,只要实现抽象策略,它就成为策略家族的一个成员,通过封装角色对其进行封装,保证对外提供“可自由切换”的策略。


    避免使用多重条件判断
        如果没有策略模式,我们想想看会是什么样子?一个策略家族有5个策略算法,一会要使用A策略,一会要使用
    B策略,怎么设计呢?使用多重的条件语句?多重条件语句不易维护,而且出错的概率大大增强。使用策略模式后,可以由其他模块决定采用何种策略,策略家族对外提供的访问接口就是封装类,简化了操作,同时避免了条件语句判断。


    扩展性良好
        这甚至都不用说是它的优点,因为它太明显了。在现有的系统中增加一个策略太容易了,只要实现接口就可以了,其他都不用修改,类似于一个可反复拆卸的插件,这大大地符合了OCP原则。


    策略模式的缺点:

    策略类数量增多    每一个策略都是一个类,复用的可能性很小,类数量增多。
    所有的策略类都需要对外暴露

     

    策略模式的使用场景:
    ● 多个类只有在算法或行为上稍有不同的场景。

    ● 算法需要自由切换的场景。
    ● 需要屏蔽算法规则的场景。


    2、策略模式的扩展—策略枚举

     

    策略枚举定义如下:
    ● 它是一个枚举。
    ● 它是一个浓缩了的策略模式的枚举。

    示例如下:

    题目:输入3个参数,进行加减法运算,参数中两个是int型的,剩下的一个参数是String型的,只有“+”、“-”两个符号可以选择,不要考虑什么复杂的校验,我们做的是白箱测试,输入的就是标准的int类型和合规的String类型。

    import java.util.Arrays;
    
    
    public class Test3 {
    	public static void main(String[] args) {
    			
    		//输入的两个参数是数字
    		int a = Integer.parseInt(args[0]);
    		String symbol = args[1]; //符号
    		int b = Integer.parseInt(args[2]);
    		System.out.println("输入的参数为:"+Arrays.toString(args));
    		System.out.println("运行结果为:"+a+symbol+b+"="+Calculator.ADD.exec(a,b));
    
    
    
    		
    	}
    }
    enum Calculator {
        //加法运算
        ADD("+"){
                public int exec(int a,int b){
                       return a+b;
                }
        },
        //减法运算
        SUB("-"){
                public int exec(int a,int b){
                       return a - b;
                }
        };
        String value = "";
       
        //定义成员值类型
        private Calculator(String _value){
                this.value = _value;
        }     
        
        //获得枚举成员的值
        public String getValue(){
                return this.value;
        }
        //声明一个抽象函数
        public abstract int exec(int a,int b);
    }


     

  • 相关阅读:
    LA 2038 Strategic game(最小点覆盖,树形dp,二分匹配)
    UVA 10564 Paths through the Hourglass(背包)
    Codeforces Round #323 (Div. 2) D 582B Once Again...(快速幂)
    UVALive 3530 Martian Mining(贪心,dp)
    UVALive 4727 Jump(约瑟夫环,递推)
    UVALive 4731 Cellular Network(贪心,dp)
    UVA Mega Man's Mission(状压dp)
    Aizu 2456 Usoperanto (贪心)
    UVA 11404 Plalidromic Subsquence (回文子序列,LCS)
    Aizu 2304 Reverse Roads(无向流)
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6467300.html
Copyright © 2011-2022 走看看