zoukankan      html  css  js  c++  java
  • JAVA设计模式之策略模式

    策略模式将可变的部分从程序中抽象分离成算法接口,在该接口下分别封装一系列算法实现,并使它们可以互相替换,从而导致客户端程序独立于算法的改变。

    复合优先于继承,多用组合,少用继承

    在类中增加一个私有域,引用另一个已有的类的实例,通过调用引用实例的方法从而获得新的功能,这种设计被称作组合。

    组合:将飞行行为抽象为接口,在父类中持有该接口,并由该接口代替飞行行为

    面向接口编程,而不是面向实现编程

    多用组合,少用继承

    策略模式的实现

    1. 通过分离变化得出策略接口Strategy
    2. Strategy的实现类
    3. 客户程序有一个Strategy
    4. 在客户程序中选择/组装正确的Strategy实现

    策略模式优点

    1. 使用了组合,是架构更加灵活
    2. 富有弹性,可以较好的对应变化(开-闭原则)
    3. 更好的代码复用性(相对于继承)
    4. 消除大量的条件语句

    策略模式缺点

    1. 客户代码需要了解每个策略实现的细节
    2. 增加了对象的数目

    策略模式的适用场景

    1. 许多相关的类仅仅是行为差异
    2. 运行时选取不同的算法变体
    3. 通过条件语句在多个分支中选取一

    鸭子代码实现策略模式示例

     1 /**
     2  * 超类,所有的鸭子都有继承此类
     3  * 抽象了鸭子的行为:显示和鸣叫
     4  * */
     5 public abstract class Duck {
     6 /*
     7  * 鸭子发出叫声
     8  * 通用行为,由超类实现
     9  * */
    10     public void quack(){
    11         System.out.println("嘎嘎。。。。");
    12     }
    13     /*
    14      * 显示鸭子的外观
    15      * 鸭子的外观各不相同,声明外abstract,由子类实现**/
    16     public abstract void display();
    17     
    18     /** 组合:将飞行行为抽象为接口,在父类中持有该接口,并由该接口代替飞行行为*/
    19     @SuppressWarnings("unused")
    20     private FlyingStragety flyingStragety;
    21     public void setFlyingStragety(FlyingStragety flyingStragety){
    22         this.flyingStragety = flyingStragety;
    23     }
    24     public void fly(){
    25         flyingStragety.performFly();
    26     }
    27 }
    1.创建父类
    1 /**
    2  * 策略接口,实现鸭子的飞行行为
    3  **/
    4 public interface FlyingStragety {
    5     void performFly();
    6 }
    2.创建飞行接口
     1 public class FlyWithRocket implements FlyingStragety{
     2     @Override
     3     public void performFly() {
     4         System.out.println("我用火箭飞行");
     5     }
     6 }
     7 public class FlyWithWin implements FlyingStragety{
     8     @Override
     9     public void performFly() {
    10         System.out.println("振翅高飞");    
    11     }
    12 }
    13 public class FlyNoWay implements FlyingStragety{
    14     @Override
    15     public void performFly() {
    16         System.out.println("我不会飞行");    
    17     }
    18 }
    3.实现飞行接口
     1 public class MallardDuck extends Duck{
     2     public MallardDuck(){
     3         super();
     4         super.setFlyingStragety(new FlyWithWin());
     5     }
     6     @Override
     7     public void display() {
     8         System.out.println("我的脖子是绿色的");    
     9     }
    10 }
    11 public class RedheadDuck extends Duck{
    12 
    13     public RedheadDuck(){
    14         super();
    15         super.setFlyingStragety(new FlyWithWin());
    16     }
    17     @Override
    18     public void display() {
    19         System.out.println("我的头是红色的");    
    20     }
    21 }
    22 public class SpaceDuck extends Duck{
    23     public SpaceDuck(){
    24         super();
    25         super.setFlyingStragety(new FlyWithRocket());
    26     }
    27     @Override
    28     public void display() {
    29         System.out.println("我是太空鸭子");    
    30     }
    31     public void quack() {
    32         System.out.println("无线电通讯");
    33     }
    34 }
    35 public class RubberDuck extends Duck{
    36     public RubberDuck(){    
    37         super();//调用父类的构造函数
    38         super.setFlyingStragety(new FlyNoWay());
    39     }
    40     @Override
    41     public void display() {
    42         System.out.println("我的橡胶鸭子");    
    43     }
    44     public void quack() {
    45         System.out.println("瑟瑟。。。");
    46     }
    47 }
    48 public class BigYellowDuck extends Duck{
    49     public BigYellowDuck(){
    50         super();
    51         super.setFlyingStragety(new FlyNoWay());
    52     }
    53     @Override
    54     public void display() {
    55         System.out.println("我是大黄鸭子");    
    56     }
    57     public void quack() {
    58     }
    59 }
    4.创建子类,并决定飞行方式,及其叫声(覆盖父类方法)
     1 public class Test {
     2     public static void main(String[] args) {
     3         Duck duck =null;
     4         duck = new MallardDuck();
     5         duck.display();
     6         duck.quack();
     7         duck.fly();
     8         System.out.println("**************");
     9         duck = new RedheadDuck();
    10         duck.display();
    11         duck.quack();
    12         duck.fly();
    13         System.out.println("*****************");
    14         duck = new RubberDuck();
    15         duck.display();
    16         duck.quack();
    17         duck.fly();
    18         System.out.println("*****************");
    19         duck = new BigYellowDuck();
    20         duck.display();
    21         duck.quack();
    22         duck.fly();
    23         System.out.println("*****************");
    24         duck = new SpaceDuck();
    25         duck.display();
    26         duck.quack();
    27         duck.fly();
    28     }
    29 }
    5.测试类
  • 相关阅读:
    无法重用Linq2Entity Query
    The Joel Test
    MSBuilder directly instead of default VSComplie with keyborad shotcut 原创
    客户端缓存(Client Cache)
    关于代码重构和UT的一些想法,求砖头
    ExtJS2.0实用简明教程 应用ExtJS
    Perl information,doc,module document and FAQ.
    使用 ConTest 进行多线程单元测试 为什么并行测试很困难以及如何使用 ConTest 辅助测试
    史上最简单的Hibernate入门简介
    汽车常识全面介绍 传动系统
  • 原文地址:https://www.cnblogs.com/wwzyy/p/4986472.html
Copyright © 2011-2022 走看看