设计模式之策略模式

一、什么是策略模式

策略模式,定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。

策略模式,属于对象行为型模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派诶不同的对象对这些算法进行管理。

二、策略模式类图

设计模式之策略模式插图

三、策略模式角色

  • 抽象策略角色(Strategy): 定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
  • 具体策略角色(ConcreteStrategy):实现了抽象策略定义的接口,提供具体的算法实现。
  • 环境角色(Context): 持有一个策略类的引用,最终给客户端调用。

四、策略模式优缺点

优点:

  1. 避免出现多重条件语句,更易维护。
  2. 提供一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
  3. 可以提供相同行为的不同实现,客户可以根据需要自行选择。
  4. 新增算法时,不会修改原有代码,满足开闭原则。
  5. 把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者分离。

缺点:

  1. 客户端必须理解所有策略算法,以便选择恰当的算法类。
  2. 产生了很多的策略类,一定程度上增加了维护难度。

五、策略模式demo示例

1、Demo需求

下班了,乘坐什么交通工具回家呢?可以选择打车、坐地铁、乘公交,请使用策略模式实现此需求。

2、代码实现

 /**
  * 抽象策略角色:下班回家乘坐交通工具
  */ public abstract class Transportation {
 
     /**
      * 回家乘坐交通工具
      */     public abstract void goHome();
 }
/**
  * 具体策略角色:出租车
  */ public class TaxiTransportation extends Transportation {

     @Override
     public void goHome() {
         System.out.println("下班,打出租车回家");
     }
 }
/**
  * 具体策略角色:地铁
  */ public class SubwayTransportation extends Transportation {

     @Override
     public void goHome() {
         System.out.println("下班,乘坐地铁回家");
     }
 }
/**
  * 具体策略角色:公交车
  */ public class BusTransportation extends Transportation {

     @Override
     public void goHome() {
         System.out.println("下班,乘公交车回家");
     }
 }
/**
  * 环境角色:下班回家乘坐交通工具
  */ public class OffDutyContext {
 
     private Transportation transportation;
 
     public void setTransportation(Transportation transportation) {
         this.transportation = transportation;
     }
 
     /**
      * 回家啦
      */     public void go() {
         transportation.goHome();
     }
 }

3、测试

/**
  * 策略模式-客户端测试类
  */ public class Client {
 
     public static void main(String[] args) {
         OffDutyContext offDuty = new OffDutyContext();
         // 1.乘坐出租车回家
         offDuty.setTransportation(new TaxiTransportation());
         offDuty.go();
         System.out.println("==============================");
         // 2.乘坐地铁回家
         offDuty.setTransportation(new SubwayTransportation());
         offDuty.go();
         System.out.println("==============================");
         // 3.乘坐公交车回家
         offDuty.setTransportation(new BusTransportation());
         offDuty.go();
         System.out.println("==============================");
 
     }
 }

控制台输出日志:

下班,打出租车回家
==============================
下班,乘坐地铁回家
==============================
下班,乘公交车回家
==============================

发表评论