美文网首页
设计模式之策略模式

设计模式之策略模式

作者: 零星瓢虫 | 来源:发表于2020-04-15 23:22 被阅读0次

前言

本系列设计模式的剖析主要基于Head First的设计模式这本书,同时加上一些自己的理解,从而希望自己能够对设计模式进行更深入的一层理解,同时希望能给看到此篇文章的同学带来一些帮助;

策略模式

策略模式,听起来就是一种策略;但是是什么样的策略呢?我们就先简单跟随例子分析起来吧;

设想这么一种情况,我们有一款游戏,这款游戏里面有很多种鸭子,而不同的鸭子则有不同的外在(比如:红色,绿色),同时发出的叫声可能也不同,而同时又可能有的会游泳,有的会飞;

那么我们首先会想到如何去实现这个鸭子的结构?
1 定义一个Duck类的父类,定义一些抽象方法;
2 子类集成Duck ,去实现相关的抽象方法;

public abstract class Duck {
    abstract void display();
    
    abstract void swim ();
    
    abstract void quak();

}


public class RedDuck extends Duck{
    
    void display() {
        // TODO Auto-generated method stub
        System.out.print("红鸭子");

    }

    void swim() {
        // TODO Auto-generated method stub
        System.out.print("鸭子去游泳");

    }

    void quak() {
        // TODO Auto-generated method stub
        System.out.print("呱呱交");

    }

}

public class GreenDuck extends Duck {

    void display() {
        // TODO Auto-generated method stub
        System.out.print("绿鸭子");

    }

    void swim() {
        // TODO Auto-generated method stub
        System.out.print("鸭子去游泳");

    }

    void quak() {
        // TODO Auto-generated method stub
        System.out.print("呱呱交");

    }

}
public class HanDuck extends Duck{
    void display() {
        // TODO Auto-generated method stub
        System.out.print("绿鸭子");

    }

    void swim() {
        // TODO Auto-generated method stub
        System.out.print("旱鸭子不会去游泳");

    }

    void quak() {
        // TODO Auto-generated method stub
        System.out.print("呱呱交");

    }

}

上面可以看到定义了Duck父类,并且GreenDuck,RedDuck,HanDuck分别对父类的抽象方法进行了具体化;到这里看到是没有任何问题的。

但是现在需求要变了,会游泳的鸭子逻辑有点变化了,我先要判断这只是是否已经到达1岁了,到达了才让它去有泳;其实我们现实开发中也会有这样可能存在变化的逻辑;我们要去如何处理呢?

public class GreenDuck extends Duck {

    void display() {
        // TODO Auto-generated method stub
        System.out.print("绿鸭子");

    }

    void swim() {
        if(age > 1){
        // TODO Auto-generated method stub
        System.out.print("鸭子去游泳");
        }

    }

    void quak() {
        // TODO Auto-generated method stub
        System.out.print("呱呱交");

    }

}
public class RedDuck extends Duck{
    
    void display() {
        // TODO Auto-generated method stub
        System.out.print("红鸭子");

    }

      void swim() {
        if(age > 1){
        // TODO Auto-generated method stub
        System.out.print("鸭子去游泳");
        }

    }

    void quak() {
        // TODO Auto-generated method stub
        System.out.print("呱呱交");

    }

}

类似于上面,正常情况我们想的是把对应的实现方法修改即可。在这里我们只有一个子类,但是如果在现实中我们有许多子类,那样岂不是意见很麻烦的事情,于是我们把对应的容易改变的行为,做成一个接口,这样我们将动作委托给接口,改动的时候就会变得简单了许多;

我们先对动作定义接口:

public  interface SwimInterface {
    void swim();

}

然后具体对不同鸭子游泳方式的实现:

public class CanSwim implements SwimInterface {
    @Override
    public void swim() {
        // TODO Auto-generated method stub
        if(duck.age > 1){
            System.out.print("去游泳");
        }   
    }
}
public class NoSwim implements SwimInterface {

    public void swim() {
        // TODO Auto-generated method stub
        System.out.print("不会游泳啊啊");
    }
}

这里我们针对不同的游泳方式实现了游泳动作的接口,NoSwim 和CanSwim 分别代表不会游泳和会游泳的类;接下来我们就应该把鸭子的游泳方式委托给接口类来做;

public abstract class Duck {
    
    SwimInterface swimInterface;
    
    public Duck(){
        
    }
    
    
    abstract void display();
    
     void swim (){
         if(swimInterface != null){
             swimInterface.swim();
         }
     }
    
    abstract void quak();

}
public class GreenDuck extends Duck {

    void display() {
        // TODO Auto-generated method stub
        System.out.print("绿鸭子");

    }
    public GreenDuck(){
        swimInterface = new NoSwim();
    }


    void quak() {
        // TODO Auto-generated method stub
        System.out.print("呱呱交");

    }

}

public class HanDuck extends Duck{
    
    public HanDuck(){
        swimInterface = new CanSwim();
    }
    
    void display() {
        // TODO Auto-generated method stub
        System.out.print("绿鸭子");

    }


    void quak() {
        // TODO Auto-generated method stub
        System.out.print("呱呱交");

    }

}

这样我们就把游泳这个动作委托出去了,从而当某个游泳方式发生改变的时候,我们只需要修改实现类中的方法即可,比如我现在需要大于2岁才可以去游泳;

public class CanSwim implements SwimInterface {
    @Override
    public void swim() {
        // TODO Auto-generated method stub
        if(duck.age > 2){
            System.out.print("去游泳");
        }   
    }
}

只需要改变CanSwim 类中的实现方式即可,任何调用这个方法的同时会被改变;

public class Main {
    public static void main(String [] args){
        Duck duck = new HanDuck();
        duck.swim();
    }
}

打印日志;

去游泳
public abstract class Duck {
    
    SwimInterface swimInterface;
    
    public Duck(){
        
    }
    
    public void setSwimInterface(SwimInterface swimInterface){
        this.swimInterface = swimInterface;
    }
    
    
    abstract void display();
    
     void swim (){
         if(swimInterface != null){
             swimInterface.swim();
         }
     }
    
    abstract void quak();

}

同时我们可以提供ser方法来进行接口的动态设置;

这样,策略模式就这样诞生;其中心思想就是对于可能会经常变化的东西,我们尽量使用接口来进行编程;满足我们“多用组合,少用继承”的设计原则,可以在运行时候动态地去改变行为;

最后我们对应来看一下策略模式的UML图形:

窝藏大莴笋_001.png

相关文章

  • PHP设计模式之策略模式

    PHP设计模式之策略模式

  • PHP设计模式之策略模式

    PHP设计模式之策略模式

  • 简说设计模式之策略模式

    前言:对于设计模式基础概念可以去看[简说设计模式之设计模式概述] 一、什么是策略模式 策略(Strategy)模式...

  • 策略模式

    参考资料:漫话:如何给女朋友解释什么是策略模式? 设计模式之策略模式(实例+Demo) Java设计模式(8)——...

  • 学习Head First设计模式Day1

    Java设计模式之设计模式 策略模式:策略模式定义了算法簇,分别封装起来,让他们之间可以互相替换,此设计模式让算法...

  • 策略模式 2018-11-04

    设计模式之策略模式 官方说明设计模式的3个角色: 环境角色:context , 持有一个策略的引用 抽象策略角色,...

  • Java设计模式——策略模式

    Java设计模式之策略模式 这期分享的模式是策略模式是程序设计中最常用的了,因为开发工作中总是会使用到策略模式。 ...

  • 策略模式

    本文参考自: 《JAVA设计模式》之策略模式(Strategy) 1. 作用 策略模式属于对象的行为模式。其用意是...

  • 设计模式(Swift) - 单例模式、备忘录模式和策略模式

    设计模式(Swift) - 单例模式、备忘录模式和策略模式 设计模式(Swift) - 单例模式、备忘录模式和策略模式

  • 设计模式之策略模式总结

    再上一篇文章《设计模式之策略模式》中,我们通过模拟鸭子项目,了解了什么是策略模式,怎么使用策略模式。本文将通过鸭子...

网友评论

      本文标题:设计模式之策略模式

      本文链接:https://www.haomeiwen.com/subject/krvxvhtx.html