首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

设计方式一:策略模式(Strategy Pattern)

2012-10-26 
设计模式一:策略模式(Strategy Pattern)今天从图书馆借了本 Head First设计模式,小看了一章,感觉挺不错的

设计模式一:策略模式(Strategy Pattern)
   今天从图书馆借了本 Head First设计模式,小看了一章,感觉挺不错的所以写下来当作备忘:

   书里关于这个模式的定义是:定义了算法族,分别封闭起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户.以下是一个简单的实例,具体的流程是:

   先把公共的信息定义在一个父类或者是父接口中,该父类或者父接口中的变量用的都是接口类型(这些接口类型都有其实现的具体子类,暂称为a吧),然后在实现或者继承了父接口或者父类的子类(暂称为b)中针对的是父类或者父接口中的接口进行编程,最后在测试类或者是具体功能类中只需实例化a后赋给针对接口类型编程的地方,这样一来就可以实现具体算法与具体用户之间的独立和替换;

首先是父接口:

 

package com.jie.pattern;public interface Duck {public IFly fly=null;  //这里两个都是接口类型public ICry cry=null;  //    public void display();}


接着是两个接口的定义:

 
package com.jie.pattern;public interface IFly {public void fly();}

 package com.jie.pattern;public interface ICry {public void cry();}

然后是实现了父接口的子类:

 package com.jie.pattern;public class FlyDuck implements Duck{public IFly fly=null;public FlyDuck(){}public void setFly(IFly fly){this.fly=fly;}public void fly(){fly.fly();}public void display(){System.out.println("Fly's duck...");}}


然后是实现了接口的具体类:

 package com.jie.pattern;public class FlyDuck implements Duck{public IFly fly=null;public FlyDuck(){}public void setFly(IFly fly){this.fly=fly;}public void fly(){fly.fly();}public void display(){System.out.println("Fly's duck...");}}


最后当然少不了一个测试类:

 
package com.jie.pattern;public class Test {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubFlyDuck flyDuck=new FlyDuck();flyDuck.setFly(new SubFly());//这里可以用实现了接口的具体类的实例来进行替代;flyDuck.fly();}}


public class DiscountTest extends TestCase { public void testMain() { //总额百分比 策略 NoDiscountStrategy discountStrategy = new NoDiscountStrategy(32.5, 24);// //固定折扣额 策略// FlatRateStrategy discountStrategy = new FlatRateStrategy(32.5, 24);// discountStrategy.setAmmount(2);// //总额百分比 策略// PercentageStrategy discountStrategy = new PercentageStrategy(32.5,24);// discountStrategy.setPercent(0.85); double discount = discountStrategy.calculateDiscount(); System.out.println(discountStrategy.getClass().getName() + " 折扣额为 : " + discount); }}


感觉 用的 有点 心虚 。 不知道 哪位知道 地道的用法 。


根据类图,作出下面个的观察总结与理解:

策略模式, 具体策略类ConcreteStrategyA 、ConcreteStrategyB、。。。。他们都有同名同参数的方法,
仅实现不同。

在Context类中,需要给它注入(或生成)策略对象( 即ConcreteStrategyA 、ConcreteStrategyB、。。。。的对象
concreteStrategyA 、concreteStrategyB、。。。。) .


在Context类中,再使用这些具体策略类对象的方法。

从实现角度上总结:类对象注入(或生成)。与所注入的对象相对应的类 仅仅是封装了相同形式但不同算法罢了。没有什么好神秘的。

一种运用场景, 根据不同条件,运用不同的策略.如:游戏中,如果是怕火的人,就用火攻的策略,如果是怕毒的人,就用毒气。 如果用伪java解说,则如下:

  public class ConcreteStrategy {          puvlic void 攻击(){};           }   public class ConcreteStrategy火 extends ConcreteStrategy {          puvlic void 攻击(){             //发出三昧真火          };           }    public class ConcreteStrategy毒 extends ConcreteStrategy {          puvlic void 攻击(){             //发出唐门无色无味,闻着倒          };           }   public class content {              public void 战场( String 敌人特征){           if (敌人特征==("怕火")){                ConcreteStrategy 自已的策略= new  ConcreteStrategy火();                自已的策略.攻击();           }           if (敌人特征=="怕毒"){                ConcreteStrategy 自已的策略= new  ConcreteStrategy毒();                自已的策略.攻击();           }       }    }   


说明: 1 上面不是java语言,为了解说而使用类似java语法的形式说明。其中<敌人特征==("怕火")>中,关于字符串用等于符号,在java中是非常不对的。
      2  上面的例子还有很强的耦合。为了解耦,请使用类反射器解耦。

根据类图,作出下面个的观察总结与理解:

策略模式, 具体策略类ConcreteStrategyA 、ConcreteStrategyB、。。。。他们都有同名同参数的方法,
仅实现不同。

在Context类中,需要给它注入(或生成)策略对象( 即ConcreteStrategyA 、ConcreteStrategyB、。。。。的对象
concreteStrategyA 、concreteStrategyB、。。。。) .


在Context类中,再使用这些具体策略类对象的方法。

从实现角度上总结:类对象注入(或生成)。与所注入的对象相对应的类 仅仅是封装了相同形式但不同算法罢了。没有什么好神秘的。

一种运用场景, 根据不同条件,运用不同的策略.如:游戏中,如果是怕火的人,就用火攻的策略,如果是怕毒的人,就用毒气。 如果用伪java解说,则如下:

  public class ConcreteStrategy {          puvlic void 攻击(){};           }   public class ConcreteStrategy火 extends ConcreteStrategy {          puvlic void 攻击(){             //发出三昧真火          };           }    public class ConcreteStrategy毒 extends ConcreteStrategy {          puvlic void 攻击(){             //发出唐门无色无味,闻着倒          };           }   public class content {              public void 战场( String 敌人特征){           if (敌人特征==("怕火")){                ConcreteStrategy 自已的策略= new  ConcreteStrategy火();                自已的策略.攻击();           }           if (敌人特征=="怕毒"){                ConcreteStrategy 自已的策略= new  ConcreteStrategy毒();                自已的策略.攻击();           }       }    }   


说明: 1 上面不是java语言,为了解说而使用类似java语法的形式说明。其中<敌人特征==("怕火")>中,关于字符串用等于符号,在java中是非常不对的。
      2  上面的例子还有很强的耦合。为了解耦,请使用类反射器解耦。

这位同学讲的在理。 幽默啊!

19 楼 nba520pz 2009-01-24   建议看看《深入浅出设计模式》! 20 楼 nba520pz 2009-01-24   package com.jie.pattern;  
 
public interface Duck {  
      
    public IFly fly=null;  //这里两个都是接口类型  
     public ICry cry=null;  //  
      
    public void display();  


这个接口中放两个常量干嘛?这两个默认的可是static final类型的,
不需要的!

热点排行