设计模式之策略模式

来源:互联网 发布:iphone吉他独奏软件 编辑:程序博客网 时间:2024/06/05 19:40

定义:定义一系列的算法,把它们一个个封装起来,并且使它们可互相替换,策略模式使得算法的变化可独立于使用它的客户。

类图:

    

说明:Context表示环境类,它通过ConcreteStrategy对象配置其执行环境,并维护一个对Strategy的引用实例,可以定义一个接口Strategy存取其数据;Strategy表示抽象策略类,它定义一个公共的接口给所有支持的算法,Context可以使用这个接口调用ConcreteStrategy定义的算法;ConcreteStrategyA和ConcreteStrategyB表示具体策略类,它们实现Strategy接口定义的算法。

优点:

①.提供了对开闭原则的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活的增加新的算法或行为

②.提供了管理相关的算法的办法

③.提供了一种可以替换继承关系的办法

④.可以避免多重条件选择语句

⑤.提供了一种算法的复用机制,不同的环境类可以方便地复用策略类。

缺点:

①.客户端必须知道所有的策略类,并自行决定使用哪一个策略类

②.将造成系统产生很多具体策略类

③.无法同时在客户端使用多个策略类

适用环境:

①.一个系统需要动态地在几种算法中选择一种

②.避免使用难以维护的多重条件选择语句

③.不希望客户端知道复杂的、与算法相关的数据结构,提高算法的保密性与安全性。

实例场景:策略模式实例值电影票打折,某电影院售票系统为不同类型的用户提供了不同的打折方式(Discount),学生凭学生证可享受8折优惠(StudentDiscount),儿童可享受减免10元的优惠(ChildrenDiscount),VIP用户处享受半价优惠外还可以进行积分(VIPDiscount)。

实例类图:

           

实例代码:

/** * 折扣类:抽象策略类 * @author fly * */public interface Discount{public double calculate(double price);}
/** * 学生折扣价:具体策略类 * @author fly * */public class StudentDiscount implements Discount{@Overridepublic double calculate(double price) {// TODO Auto-generated method stubreturn price*0.8;}}
/** * 儿童折扣价:具体策略类 * @author fly * */public class ChildrenDiscount implements Discount{@Overridepublic double calculate(double price) {// TODO Auto-generated method stubreturn price-10;}}
/** * VIP会员折扣类:具体策略类 * @author fly * */public class VIPDiscount implements Discount{@Overridepublic double calculate(double price) {// TODO Auto-generated method stubSystem.out.println("增加积分");return price*0.5;}}
//电影票类:环境类

/** * 电影票类:环境类 *  * @author fly *  */class MovieTicket {private double price;private Discount discount;public double getPrice() {return discount.calculate(price);}public void setPrice(double price) {this.price = price;}public void setDiscount(Discount discount) {this.discount = discount;}}
//客户端测试类:

public class Client {public static void main(String[] args) {MovieTicket mt = new MovieTicket();mt.setPrice(50.00);double currentPrice;Discount obj;obj = new StudentDiscount();//可以通过配置文件实现mt.setDiscount(obj);currentPrice = mt.getPrice();System.out.println("折后价为:"+currentPrice);System.out.println("-----------------------------------------");obj = new VIPDiscount();mt.setDiscount(obj);currentPrice = mt.getPrice();System.out.println("折后价为:"+currentPrice);}}
//运行结果:


0 0