研磨设计模式 - 策略模式

本文探讨了策略模式在解决复杂报价管理问题时的优势,通过实例展示了如何将不同的定价策略封装为独立的算法,提高了代码的可维护性和扩展性。通过策略模式,实现了对普通客户、老客户和大客户的差异化定价策略,以及根据不同场景动态调整报价的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

策略模式(Strategy)

1  场景问题

1.1  报价管理

        向客户报价,对于销售部门的人来讲,这是一个非常重大、非常复杂的问题,对不同的客户要报不同的价格,比如:
  • 对普通客户或者是新客户报的是全价
  • 对老客户报的价格,根据客户年限,给予一定的折扣
  • 对大客户报的价格,根据大客户的累计消费金额,给予一定的折扣
  • 还要考虑客户购买的数量和金额,比如:虽然是新用户,但是一次购买的数量非常大,或者是总金额非常高,也会有一定的折扣
  • 还有,报价人员的职务高低,也决定了他是否有权限对价格进行一定的浮动折扣
        甚至在不同的阶段,对客户的报价也不同,一般情况是刚开始比较高,越接近成交阶段,报价越趋于合理。           总之,向客户报价是非常复杂的,因此在一些CRM(客户关系管理)的系统中,会有一个单独的报价管理模块,来处理复杂的报价功能。           为了演示的简洁性,假定现在需要实现一个简化的报价管理,实现如下的功能:              (1)对普通客户或者是新客户报全价              (2)对老客户报的价格,统一折扣5%              (3)对大客户报的价格,统一折扣10%           该怎么实现呢?

1.2  不用模式的解决方案

        要实现对不同的人员报不同的价格的功能,无外乎就是判断起来麻烦点,也不多难,很快就有朋友能写出如下的实现代码,示例代码如下:
 
 
/**    
* 价格管理,主要完成计算向客户所报价格的功能    
*/    
public      class Price {    
    /**    
    * 报价,对不同类型的,计算不同的价格    
    * @param goodsPrice 商品销售原价    
    * @param customerType 客户类型    
    * @return 计算出来的,应该给客户报的价格    
    */    
    public double quote(double goodsPrice,String customerType){    
       if(customerType.equals("普通客户       ")){    
           System.out.println("对于新客户或者是普通客户,没有折扣       ");    
           return goodsPrice;    
       }else if(customerType.equals("老客户       ")){    
           System.out.println("对于老客户,统一折扣       5%");    
           return goodsPrice*(1-0.05);    
       }else if(customerType.equals("大客户       ")){    
           System.out.println("对于大客户,统一折扣       10%");    
           return goodsPrice*(1-0.1);             
       }    
       //其余人员都是报原价    
       return goodsPrice;    
    }    
}    
 

1.3  有何问题

        上面的写法是很简单的,也很容易想,但是仔细想想,这样实现,问题可不小,比如:
  • 第一个问题:价格类包含了所有计算报价的算法,使得价格类,尤其是报价这个方法比较庞杂,难以维护。
        有朋友可能会想,这很简单嘛,把这些算法从报价方法里面拿出去,形成独 立的方法不就可以解决这个问题了吗?据此写出如下的实现代码,示例代码如下:
 
 
/**    
* 价格管理,主要完成计算向客户所报价格的功能    
*/    
public      class Price {    
    /**    
    * 报价,对不同类型的,计算不同的价格    
    * @param goodsPrice 商品销售原价    
    * @param customerType 客户类型    
    * @return 计算出来的,应该给客户报的价格    
    */    
    public double quote(double goodsPrice,String customerType){    
       if(customerType.equals("普通客户       ")){    
           return this.calcPriceForNormal(goodsPrice);    
       }else if(customerType.equals("老客户       ")){    
           return this.calcPriceForOld(goodsPrice);    
       }else if(customerType.equals("大客户       ")){    
           return this.calcPriceForLarge(goodsPrice);            
       }    
       //其余人员都是报原价    
       return goodsPrice;    
    }    
    /**    
    * 为新客户或者是普通客户计算应报的价格    
    * @param goodsPrice 商品销售原价    
    * @return 计算出来的,应该给客户报的价格    
    */    
    private double calcPriceForNormal(double goodsPrice){    
       System.out.println("对于新客户或者是普通客户,没有折扣       ");    
       return goodsPrice;    
    }    
    /**    
    * 为老客户计算应报的价格    
    * @param goodsPrice 商品销售原价    
    * @return 计算出来的,应该给客户报的价格    
    */    
    private double calcPriceForOld(double goodsPrice){    
       System.out.println("对于老客户,统一折扣       5%");    
       return goodsPrice*(1-0.05);    
    }    
    /**    
    * 为大客户计算应报的价格    
    * @param goodsPrice 商品销售原价    
    * @return 计算出来的,应该给客户报的价格    
    */    
    private double calcPriceForLarge(double goodsPrice){    
       System.out.println("对于大客户,统一折扣       10%");    
       return goodsPrice*(1-0.1);      
    }    
}    
 
        这样看起来,比刚开始稍稍好点,计算报价的方法会稍稍简单一点,这样维护起来也稍好一些,某个算法发生了变化,直接修改相应的私有方法就可以了。扩展起来也容易一点,比如要增加一个“战略合作客户”的类型,报价为直接8折,就只需要在价格类里面新增加一个私有的方法来计算新的价格,然后在计算报价的方法里面新添一个else-if即可。看起来似乎很不错了。           真的很不错了吗?           再想想,问题还是存在,只不过从计算报价的方法挪动到价格类里面了,假如有100个或者更多这样的计算方式,这会让这个价格类非常庞大,难以维护。而且,维护和扩展都需要去修改已有的代码,这是很不好的,违反了开-闭原则。
 
  • 第二个问题:经常会有这样的需要,在不同的时候,要使用不同的计算方式。
        比如:在公司周年庆的时候,所有的客户额外增加3%的折扣;在换季促销的时候,普通客户是额外增加折扣2%,老客户是额外增加折扣3%,大客户是额外增加折扣5%。这意味着计算报价的方式会经常被修改,或者被切换。           通常情况下应该是被切换,因为过了促销时间,又还回到正常的价格体系上来了。而现在的价格类中计算报价的方法,是固定调用各种计算方式,这使得切换调用不同的计算方式很麻烦,每次都需要修改if-else里面的调用代码。           看到这里,可能有朋友会想,   那么到底应该如何实现,才能够让价格类中的计算报价的算法,能很容易的实现可维护、可扩展,又能动态的切换变化呢?
 

2  解决方案

2.1  策略模式来解决

        用来解决上述问题的一个合理的解决方案就是策略模式。那么什么是策略模式呢?

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

(2)应用策略模式来解决的思路         仔细分析上面的问题,先来把它抽象一下,各种计算报价的计算方式就好比是具体的算法,而使用这些计算方式来计算报价的程序,就相当于是使用算法的客户。         再分析上面的实现方式,为什么会造成那些问题,根本原因,就在于算法和使用算法的客户是耦合的,甚至是密不可分的,在上面实现中,具体的算法和使用算法的客户是同一个类里面的不同方法。         现在要解决那些问题,按照策略模式的方式,应该先把所有的计算方式独 立出来,每个计算方式做成一个单独的算法类,从而形成一系列的算法,并且为这一系列算法定义一个公共的接口,这些算法实现是同一接口的不同实现,地位是平等的,可以相互替换。这样一来,要扩展新的算法就变成了增加一个新的算法实现类,要维护某个算法,也只是修改某个具体的算法实现即可,不会对其它代码造成影响。也就是说这样就解决了可维护、可扩展的问题。         为了实现让算法能独 立于使用它的客户,策略模式引入了一个上下文的对象,这个对象负责持有算法,但是不负责决定具体选用哪个算法,把选择算法的功能交给了客户,由客户选择好具体的算法后,设置到上下文对象里面,让上下文对象持有客户选择的算法,当客户通知上下文对象执行功能的时候,上下文对象会去转调具体的算法。这样一来,具体的算法和直接使用算法的客户是分离的。         具体的算法和使用它的客户分离过后,使得算法可独 立于使用它的客户而变化,并且能够动态的切换需要使用的算法,只要客户端动态的选择使用不同的算法,然后设置到上下文对象中去,实际调用的时候,就可以调用到不同的算法。

2.2  模式结构和说明

        策略模式的结构示意图如图1所示:

图1  策略模式结构示意图

Strategy:         策略接口,用来约束一系列具体的策略算法。Context使用这个接口来调用具体的策略实现定义的算法。 ConcreteStrategy:         具体的策略实现,也就是具体的算法实现。 Context:         上下文,负责和具体的策略类交互,通常上下文会持有一个真正的策略实现,上下文还可以让具体的策略类来获取上下文的数据,甚至让具体的策略类来回调上下文的方法。

2.3  策略模式示例代码

(1)首先来看策略,也就是定义算法的接口,示例代码如下:

 

 

/**

* 策略,定义算法的接口

*/

public interface Strategy {

    /**

    * 某个算法的接口,可以有传入参数,也可以有返回值

    */

    public void algorithmInterface();

}

 

(2)该来看看具体的算法实现了,定义了三个,分别是ConcreteStrategyA、ConcreteStrategyB、ConcreteStrategyC,示例非常简单,由于没有具体算法的实现,三者也就是名称不同,示例代码如下:

 

 

/**

* 实现具体的算法

*/

public class ConcreteStrategyA implements Strategy {

    public void algorithmInterface() {

       //具体的算法实现   

    }

}

/**

* 实现具体的算法

*/

public class ConcreteStrategyB implements Strategy {

    public void algorithmInterface() {

       //具体的算法实现   

    }

}

/**

* 实现具体的算法

*/

public class ConcreteStrategyC implements Strategy {

    public void algorithmInterface() {

       //具体的算法实现   

    }

}

 

(3)再来看看上下文的实现,示例代码如下:

 

 

/**

* 上下文对象,通常会持有一个具体的策略对象

*/

public class Context {

    /**

    * 持有一个具体的策略对象

    */

    private Strategy strategy;

    /**

    * 构造方法,传入一个具体的策略对象

    * @param aStrategy 具体的策略对象

    */

    public Context(Strategy aStrategy) {

       this.strategy = aStrategy;

    }

    /**

    * 上下文对客户端提供的操作接口,可以有参数和返回值

    */

    public void contextInterface() {

       //通常会转调具体的策略对象进行算法运算

       strategy.algorithmInterface();

    }

}

 

2.4  使用策略模式重写示例

        要使用策略模式来重写前面报价的示例,大致有如下改变:

  • 首先需要定义出算法的接口。
  • 然后把各种报价的计算方式单独出来,形成算法类。
  • 对于Price这个类,把它当做上下文,在计算报价的时候,不再需要判断,直接使用持有的具体算法进行运算即可。选择使用哪一个算法的功能挪出去,放到外部使用的客户端去。

        这个时候,程序的结构如图2所示:

图2  使用策略模式实现示例的结构示意图

(1)先看策略接口,示例代码如下:

 

 

/**

* 策略,定义计算报价算法的接口

*/

public interface Strategy {

    /**

    * 计算应报的价格

    * @param goodsPrice 商品销售原价

    * @return 计算出来的,应该给客户报的价格

    */

    public double calcPrice(double goodsPrice);

}

 

(2)接下来看看具体的算法实现,不同的算法,实现也不一样,先看为新客户或者是普通客户计算应报的价格的实现,示例代码如下:

 

 

/**

* 具体算法实现,为新客户或者是普通客户计算应报的价格

*/

public class NormalCustomerStrategy implements Strategy{

    public double calcPrice(double goodsPrice) {

       System.out.println("对于新客户或者是普通客户,没有折扣");

       return goodsPrice;

    }

}

 

再看看为老客户计算应报的价格的实现,示例代码如下:

 

 

/**

* 具体算法实现,为老客户计算应报的价格

*/

public class OldCustomerStrategy implements Strategy{

    public double calcPrice(double goodsPrice) {

       System.out.println("对于老客户,统一折扣5%");

       return goodsPrice*(1-0.05);

    }

}

再看看为大客户计算应报的价格的实现,示例代码如下:

 

 

/**

* 具体算法实现,为大客户计算应报的价格

*/

public class LargeCustomerStrategy implements Strategy{

    public double calcPrice(double goodsPrice) {

       System.out.println("对于大客户,统一折扣10%");

       return goodsPrice*(1-0.1);

    }

}

 

(3)接下来看看上下文的实现,也就是原来的价格类,它的变化比较大,主要有:

  • 原来那些私有的,用来做不同计算的方法,已经去掉了,独 立出去做成了算法类
  • 原来报价方法里面,对具体计算方式的判断,去掉了,让客户端来完成选择具体算法的功能
  • 新添加持有一个具体的算法实现,通过构造方法传入
  • 原来报价方法的实现,变化成了转调具体算法来实现

示例代码如下:

 

 

/**

* 价格管理,主要完成计算向客户所报价格的功能

*/

public class Price {

    /**

    * 持有一个具体的策略对象

    */

    private Strategy strategy = null;

    /**

    * 构造方法,传入一个具体的策略对象

    * @param aStrategy 具体的策略对象

    */

    public Price(Strategy aStrategy){

       this.strategy = aStrategy;

    }  

    /**

    * 报价,计算对客户的报价

    * @param goodsPrice 商品销售原价

    * @return 计算出来的,应该给客户报的价格

    */

    public double quote(double goodsPrice){

       return this.strategy.calcPrice(goodsPrice);

    }

}

(4)写个客户端来测试运行一下,好加深体会,示例代码如下:

 

 

public class Client {

    public static void main(String[] args) {

       //1:选择并创建需要使用的策略对象

       Strategy strategy = new LargeCustomerStrategy ();

       //2:创建上下文

       Price ctx = new Price(strategy);

      

       //3:计算报价

       double quote = ctx.quote(1000);

       System.out.println("向客户报价:"+quote);

    }

}

 

        运行一下,看看效果。         你可以修改使用不同的策略算法具体实现,现在用的是LargeCustomerStrategy,你可以尝试修改成其它两种实现,试试看,体会一下切换算法的容易性。

 

3  模式讲解

3.1  认识策略模式

(1)策略模式的功能         策略模式的功能是把具体的算法实现,从具体的业务处理里面独立出来,把它们实现成为单独的算法类,从而形成一系列的算法,并让这些算法可以相互替换。         策略模式的重心不是如何来实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活、具有更好的维护性和扩展性。

(2)策略模式和if-else语句         看了前面的示例,很多朋友会发现,每个策略算法具体实现的功能,就是原来在if-else结构中的具体实现。 没错,其实多个if-elseif语句表达的就是一个平等的功能结构,你要么执行if,要不你就执行else,或者是elseif,这个时候,if块里面的实现和else块里面的实现从运行地位上来讲就是平等的。         而策略模式就是把各个平等的具体实现封装到单独的策略实现类了,然后通过上下文来与具体的策略类进行交互。 因此多个if-else语句可以考虑使用策略模式。

(3)算法的平等性         策略模式一个很大的特点就是各个策略算法的平等性。对于一系列具体的策略算法,大家的地位是完全一样的,正是因为这个平等性,才能实现算法之间可以相互替换。         所有的策略算法在实现上也是相互独立的,相互之间是没有依赖的。         所以可以这样描述这一系列策略算法:策略算法是相同行为的不同实现

(4)谁来选择具体的策略算法         在策略模式中,可以在两个地方来进行具体策略的选择。         一个是在客户端,在使用上下文的时候,由客户端来选择具体的策略算法,然后把这个策略算法设置给上下文。前面的示例就是这种情况。         还有一个是客户端不管,由上下文来选择具体的策略算法,这个在后面讲容错恢复的时候给大家演示一下。

(5)Strategy的实现方式         在前面的示例中,Strategy都是使用的接口来定义的,这也是常见的实现方式。但是如果多个算法具有公共功能的话,可以把Strategy实现成为抽象类,然后把多个算法的公共功能实现到Strategy里面。

(6)运行时策略的唯一性         运行期间,策略模式在每一个时刻只能使用一个具体的策略实现对象,虽然可以动态的在不同的策略实现中切换,但是同时只能使用一个。

(7)增加新的策略         在前面的示例里面,体会到了策略模式中切换算法的方便,但是增加一个新的算法会怎样呢?比如现在要实现如下的功能:对于公司的“战略合作客户”,统一8折。         其实很简单,策略模式可以让你很灵活的扩展新的算法。具体的做法是:先写一个策略算法类来实现新的要求,然后在客户端使用的时候指定使用新的策略算法类就可以了。         还是通过示例来说明。先添加一个实现要求的策略类,示例代码如下:

 

/**

* 具体算法实现,为战略合作客户客户计算应报的价格

*/

public class CooperateCustomerStrategy implements Strategy{

    public double calcPrice(double goodsPrice) {

       System.out.println("对于战略合作客户,统一8");

       return goodsPrice*0.8;

    }

}

然后在客户端指定使用策略的时候指定新的策略算法实现,示例如下:

 

public class Client2 {

    public static void main(String[] args) {

       //1:选择并创建需要使用的策略对象

       Strategy strategy = new CooperateCustomerStrategy ();

       //2:创建上下文

           Price ctx = new Price(strategy);

      

       //3:计算报价

       double quote = ctx.quote(1000);

       System.out.println("向客户报价:"+quote);

    }

}

 

        除了加粗部分变动外,客户端没有其他的变化。

 

        运行客户端,测试看看,好好体会一下。         除了客户端发生变化外,已有的上下文、策略接口定义和策略的已有实现,都不需要做任何的修改,可见能很方便的扩展新的策略算法。

(8)策略模式调用顺序示意图         策略模式的调用顺序,有两种常见的情况,一种如同前面的示例,具体如下:

  • 先是客户端来选择并创建具体的策略对象
  • 然后客户端创建上下文
  • 接下来客户端就可以调用上下文的方法来执行功能了,在调用的时候,从客户端传入算法需要的参数
  • 上下文接到客户的调用请求,会把这个请求转发给它持有的Strategy

这种情况的调用顺序示意图如图3所示:

图3  策略模式调用顺序示意图一

        策略模式调用还有一种情况,就是把Context当做参数来传递给Strategy,这种方式的调用顺序图,在讲具体的Context和Strategy的关系时再给出。

 

3.2  容错恢复机制

        容错恢复机制是应用程序开发中非常常见的功能。那么什么是容错恢复呢?简单点说就是:程序运行的时候,正常情况下应该按照某种方式来做,如果按照某种方式来做发生错误的话,系统并不会崩溃,也不会就此不能继续向下运行了,而是有容忍出错的能力,不但能容忍程序运行出现错误,还提供出现错误后的备用方案,也就是恢复机制,来代替正常执行的功能,使程序继续向下运行。         举个实际点的例子吧,比如在一个系统中,所有对系统的操作都要有日志记录,而且这个日志还需要有管理界面,这种情况下通常会把日志记录在数据库里面,方便后续的管理,但是在记录日志到数据库的时候,可能会发生错误,比如暂时连不上数据库了,那就先记录在文件里面,然后在合适的时候把文件中的记录再转录到数据库中。         对于这样的功能的设计,就可以采用策略模式,把日志记录到数据库和日志记录到文件当作两种记录日志的策略,然后在运行期间根据需要进行动态的切换。         在这个例子的实现中,要示范由上下文来选择具体的策略算法,前面的例子都是由客户端选择好具体的算法,然后设置到上下文中。         下面还是通过代码来示例一下。 (1)先定义日志策略接口,很简单,就是一个记录日志的方法,示例代码如下:

 

/**

* 日志记录策略的接口

*/

public interface LogStrategy {

    /**

    * 记录日志

    * @param msg 需记录的日志信息

    */

    public void log(String msg);

}

(2)实现日志策略接口,先实现默认的数据库实现,假设如果日志的长度超过长度就出错,制造错误的是一个最常见的运行期错误,示例代码如下:

 

/**

* 把日志记录到数据库

*/

public class DbLog implements LogStrategy{

    public void log(String msg) {     

       //制造错误

       if(msg!=null && msg.trim().length()>5){

           int a = 5/0;

       }

       System.out.println("现在把 '"+msg+"' 记录到数据库中");

    }

}

 

接下来实现记录日志到文件中去,示例代码如下:

 

/**

* 把日志记录到文件

*/

public class FileLog implements LogStrategy{

    public void log(String msg) {

       System.out.println("现在把 '"+msg+"' 记录到文件中");

    }

}

 

(3)接下来定义使用这些策略的上下文,注意这次是在上下文里面实现具体策略算法的选择,所以不需要客户端来指定具体的策略算法了,示例代码如下:

 

(4)看看现在的客户端,没有了选择具体实现策略算法的工作,变得非常简单,故意多调用一次,可以看出不同的效果,示例代码如下:

 

(5)小结一下,通过上面的示例,会看到策略模式的一种简单应用,也顺便了解一下基本的容错恢复机制的设计和实现。在实际的应用中,需要设计容错恢复的系统一般要求都比较高,应用也会比较复杂,但是基本的思路是差不多的。

转载于:https://www.cnblogs.com/heartstage/p/3371385.html

内容简介 · · · · · · 《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,培养正确的“设计观”;中高级内容则深入探讨如何理解这些模式,包括模式中蕴涵什么样的设计思想,模式的本质是什么,模式如何结合实际应用,模式的优缺点以及与其他模式的关系等,以期让读者尽量去理解和掌握每个设计模式的精髓所在。 《研磨设计模式》在内容上深入、技术上实用、和实际开发结合程度很高,书中大部分的示例程序都是从实际项目中简化而来,因此很多例子都可以直接拿到实际项目中使用。如果你想要深入透彻地理解和掌握设计模式,并期望能真正把设计模式应用到项目中去,那么这是你不可错过的一本好书。 《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。也可以作为高效学生深入学习设计模式的参考读物! 作者简介 · · · · · · 陈臣:十年Java/JavaEE开发经验,高级系统架构师,功力深厚,技术精湛,精通Java/JavaEE相关技术和多种开源框架,尤其擅长系统分析和架构设计。从事过专业的中间件研发,包括基于组件的Web页面框架、基于WFMC的工作流中间件、类似于Hibernate的ORM框架等等;参与或主持了多个中大型的企业级应用项目,拥有多年项目经理、技术部经理的管理经验。个人博客:http://www.javass.cn/javapeixunxxyd/index.html 王斌:从事Java/JavaEE开发五年,系统架构师,精通Ejb、Struts、Spring、Hibernate、iBatis等框架技术,擅长设计模式和Eclipse插件开发。作为架构小组骨干,参与了国旅电子商务平台、南王酒庄等多个项目的开发,开发并维护有constance4j、myxstream、SimpleMapping等多个公司内部开源框架,深得多个项目组好评。
本电子书一共两个压缩文档,该文档为part1。 《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,培养正确的“设计观”;中高级内容则深入探讨如何理解这些模式,包括模式中蕴涵什么样的设计思想,模式的本质是什么,模式如何结合实际应用,模式的优缺点以及与其他模式的关系等,以期让读者尽量去理解和掌握每个设计模式的精髓所在。    《研磨设计模式》在内容上深入、技术上实用、和实际开发结合程度很高,书中大部分的示例程序都是从实际项目中简化而来,因此很多例子都可以直接拿到实际项目中使用。如果你想要深入透彻地理解和掌握设计模式,并期望能真正把设计模式应用到项目中去,那么这是你不可错过的一本好书。 《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。也可以作为高效学生深入学习设计模式的参考读物! 第1章 设计模式基础    第2章 简单工厂    第3章 外观模式    第4章 适配器模式(Adapter)    第5章 单例模式(Singleton)    第6章 工厂方法模式(Factory Method)    第7章 抽象工厂模式(Abstract Factory)    第8章 生成器模式(Builder)    第9章 原型模式(Prototype)    第10章 中介者模式(Mediator)    第11章 代理模式(Proxy)    第12章 观察者模式(Observer)    第13章 命令模式(Command)    第14章 迭代器模式(Iterator)    第15章 组合模式(Composite)    第16章 模板方法模式(Template Method)    第17章 策略模式(Strategy)    第18章 状态模式(State)    第19章 备忘录模式(Memento)    第20章 享元模式(Flyweight)    第21章 解释器模式(Interpreter)    第22章 装饰模式(Decorator)    第23章 职责链模式(Chain of Responsibility)    第24章 桥接模式(Bridge)    第25章 访问者模式(Visitor)    附录A常见面向对象设计原则    附录BUML简介    参考文献
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值