zoukankan      html  css  js  c++  java
  • 策略模式与简单工厂模式的结合使用

      Java设计模式中的策略模式(Strategy Patten)定义了一组算法,将每个算法都封装起来,并且可使它们之间可以相互替换,在客户端调用它们时可以互不影响。

    策略模式主要由三个角色组成

    1、抽象策略角色:通常是一个接口或抽象类实现,我们的具体策略类就是继承或实现这个抽象角色。

    2、具体策略角色:我们在这些类中写策略和算法,继承或实现抽象策略角色。

    3、环境角色:环境角色中拥有一个抽象策略角色的引用,供客户端调用,该角色把客户端跟策略类的实现分离。

    从上面的三个策略模式的角色中,我们就大概可以知道策略模式的编写步骤,这里以实现简单的四则运算为例。

    1、定义抽象策略角色,也就是定义一个公共的抽象类(也可以是接口)

     1 package strategy;
     2 /**
     3  * 
     4  * @author CIACs
     5  *定义抽象策略角色
     6  */
     7 public abstract class Strategy {
     8     //定义抽象策略的方法
     9     public abstract int strategy(int a,int b);
    10 
    11 }

    2、编写策略类,该类实现上面定义的抽象类

     1 package strategy;
     2 /**
     3  * 
     4  * @author CIACs
     5  * AddStrategy
     6  */
     7 public class AddStrategy extends Strategy {
     8     //定义实现加法的策略方法
     9     public int strategy(int a, int b)
    10     {
    11         return a+b;
    12     }
    13 
    14 }
     1 package strategy;
     2 /**
     3  * 
     4  * @author CIACs
     5  *    SubStrategy
     6  */
     7 public class SubStrategy extends Strategy {
     8     //定义减法的策略方法
     9     public int strategy(int a, int b)
    10     {
    11         return a-b;
    12     }
    13 
    14 }
     1 package strategy;
     2 /**
     3  * 
     4  * @author CIACs
     5  *    MultiplyStrategy
     6  */
     7 public class MultiplyStrategy extends Strategy {
     8     //定义乘法的策略方法
     9     public int strategy(int a,int b)
    10     {
    11         return a*b;
    12     }
    13 }
     1 package strategy;
     2 /**
     3  * 
     4  * @author CIACs
     5  *    DivStrategy
     6  */
     7 public class DivStrategy extends Strategy {
     8     //定义除法的策略方法,这里为了简单就不考虑除数为零的情况了
     9     public int strategy(int a,int b)
    10     {
    11         return a/b;
    12     }
    13 }

    3、编写环境角色,其中持有一个抽象策略类的引用

     1 package strategy;
     2 /**
     3  * 
     4  * @author CIACs
     5  *    Context
     6  */
     7 public class Context {
     8     //持有抽象策略角色的引用,用于客户端调用
     9     private Strategy strategy;
    10     //获得策略类
    11     public Strategy getStrategy() {
    12         return strategy;
    13     }
    14     //设置所需策略
    15     public void setStrategy(Strategy strategy) {
    16         this.strategy = strategy;
    17         
    18     }
    19     //根据设置的策略类返回对应的结果
    20     public int getResult(int a,int b)
    21     {
    22         return strategy.strategy(a, b);
    23     }
    24 
    25 }

    4、编写客户端

     1 package strategy;
     2 /**
     3  * 
     4  * @author CIACs
     5  *    Client
     6  */
     7 public class Client {
     8     public static void main(String[] args) {
     9         
    10         Context context = new Context();
    11         
    12         int result;
    13         
    14         context.setStrategy(new SubStrategy());
    15         
    16         result = context.getResult(9, 3);
    17         
    18         System.out.println("sub: "+result);
    19         
    20         context.setStrategy(new AddStrategy());
    21         
    22         result =context.getResult(9, 3);
    23         
    24         System.out.println("add: "+result);
    25         
    26         context.setStrategy(new DivStrategy());
    27         
    28         result = context.getResult(9, 3);
    29         
    30         System.out.println("div: "+result);
    31         
    32         context.setStrategy(new MultiplyStrategy());
    33         
    34         result = context.getResult(9, 3);
    35         
    36         System.out.println("mul: "+result);
    37     }
    38 }

    输出结果:

    上面只是用到策略模式,下面加上简单工厂模式

    工厂类

     1 package strategy;
     2 /**
     3  * 
     4  * @author CIACs
     5  *    Factory
     6  */
     7 public class Factory {
     8     public Strategy createStrategy(String str)
     9     {
    10         if("AddStrategy".equalsIgnoreCase(str))
    11         {
    12             return new AddStrategy();
    13         }
    14         else
    15             if("SubStrategy".equalsIgnoreCase(str))
    16             {
    17                 return new SubStrategy();
    18             }
    19             else
    20                 if("DivStrategy".equalsIgnoreCase(str))
    21                 {
    22                     return new DivStrategy();
    23                 }
    24                 else
    25                     if("MultiplyStrategy".equalsIgnoreCase(str))
    26                     {
    27                         return new MultiplyStrategy();
    28                     }
    29                     else
    30                         return null;
    31     }
    32 
    33 }

    客户端类

     1 package strategy;
     2 /**
     3  * 
     4  * @author CIACs
     5  *    Client
     6  */
     7 public class Client {
     8     public static void main(String[] args) {
     9      
    10         Context context = new Context();
    11         int result;
    12         Strategy strategy;
    13         Factory fac = new Factory();
    14         strategy = fac.createStrategy("AddStrategy");
    15         context.setStrategy(strategy);
    16             result = context.getResult(9, 3);
    17         System.out.println(result);
    18     }
    19 }

    输出结果:

    当然这里的工厂类中的if-else的使用是不太好的,简单工厂模式把生成策略类与客户端分离。

    总结:

      策略模式使开发人员能够开发出很多可替换的组件,而组件间是弱连接的,体现了代码的可重用行,弱连接也为以后开发新的组件打下了基础,具有较强的可扩展性,易于维护。策略模式是对算法的封装它把算法的责任和算法本身分割开委派给别的对象管理客户端决定应该使用什么策略,因此客户端需要理解所有具体策略类之间的区别,这也增加了客户端的使用难度。

  • 相关阅读:
    关于C++类中的静态数据成员
    关于C++中char,sizeof,strlen,string
    C++学习笔记(7)
    C++学习笔记(6)
    C++学习笔记(指针)
    C++学习笔记(4)
    UVA 10780
    UVA 531
    HDU, 3579 Hello Kiki
    UVA, 10413 Crazy Savages
  • 原文地址:https://www.cnblogs.com/zhi-hao/p/4025981.html
Copyright © 2011-2022 走看看