设计模式之策略模式

对于设计模式,以前虽然看过一些文章,但是总感觉差那么一点,没有系统的去学习深入一下,以致于在脑海中的思路总不是那么清晰,在项目中对于设计模式的带入感很是不强。所以在下准备静下心来好好整理一下。第一篇便是策略模式。

在百度百科上的介绍:

  • 策略模式是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
  • 策略模式的优点有:策略模式提供了管理相关的算法族的办法、策略模式提供了可以替换继承关系的办法、使用策略模式可以避免使用多重条件转移语句。

组成

  • —抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
  • —具体策略角色:包装了相关的算法和行为。
  • —环境角色:持有一个策略类的引用,最终给客户端调用。

概念
Context(应用场景):

  1. 需要使用ConcreteStrategy提供的算法。
  2. 内部维护一个Strategy的实例。
  3. 负责动态设置运行时Strategy具体的实现算法。
  4. 负责跟Strategy之间的交互和数据传递。

Strategy(抽象策略类):

  1. 定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。
  2. ConcreteStrategy(具体策略类):
  3. 实现了Strategy定义的接口,提供具体的算法实现。

以上可能有些不好理解,说得通俗易懂一点,其实策略模式顾名思义,其重点应放在“策略”两个字上,建立一系列备用的“策略”,按功能需要决定使用何种“策略”。如何理解“策略”、建立“策略”,将“策略”运用到代码中呢?在小生的理解来看,主要逻辑在于通用功能与动态改变功能的区分、提取以及抽取。

比如说,老板说我们要生产动物,但是每类动物都要标明其行动方式(行走,飞行,游泳)与进食方式(素食,肉食)。如果目前需求是狗狗,黄雀两种动物,你只用写两个类,每个类里面互不相干,各自实现狗狗与黄雀的共同特征以及不一样的行动方式与进食方式,完美收工。但是...等等,老板说,唉,我们又要增加10类动物,以后还会持续不断新增,这样岂不是每一类都要重复写一次,但是,行走,飞行,素数,肉食等功能对于动物来说都是共通的,只是有或者无的区别,这就是我们所说的“策略”了。将行动和进食抽象出来,各自实现,再按具体需要合理使用,这就是策略模式了。

简单的说,抽象出功能或者算法族的接口,需要一个基类定义好各个接口的对象,接口的具体实现需要子类去确定。

进食接口EatBehavior:

public interface EatBehavior {
    void eat();
}

行为接口MoveBehavior:

public interface MoveBehavior {
    void move();
}

功能接口实现类,这就是所谓的准备好一系列的策略:

public class MeatEat implements EatBehavior{
    public void eat() {
        System.out.println("肉食");
    }
}
public class VegetarianEat implements EatBehavior{

    public void eat() {
        System.out.println("素食");
    }
}
public class FlyMove implements MoveBehavior {
    public void move() {
        System.out.println("飞行");
    }
}
public class WalkMove implements MoveBehavior{
    public void move() {
        System.out.println("步行");
    }
}

最重要的基类Animals,这里就体现了面向对象设计的六大原则之一的里氏代换原则,两个对象的定义为接口的对象,以便于子类可以实现不同的策略组合,两个set方法可以实现子类运行时动态改变其行为方式:

public class Animals {
    //抽象出去的两个会变化行为:进食,行动
    protected EatBehavior eatBehavior;
    protected MoveBehavior moveBehavior;

    public void eat(){
        eatBehavior.eat();
    }

    public void move(){
        moveBehavior.move();
    }

    /**
     * 公共行为属性
     */
    public void smile(){
        System.out.println("微笑,say:hello word");
    }

    public void setEatBehavior(EatBehavior eatBehavior) {
        this.eatBehavior = eatBehavior;
    }

    public void setMoveBehavior(MoveBehavior moveBehavior) {
        this.moveBehavior = moveBehavior;
    }
}

子类黄雀Bird的实现:

主要是
eatBehavior = new VegetarianEat();
moveBehavior = new FlyMove();的策略选择实现确定了黄雀的行为与进食方式

public class Bird extends Animals{
    Bird(){
        eatBehavior = new VegetarianEat();
        moveBehavior = new FlyMove();
    }

    //...
}

子类狗狗Dog的实现:

主要是 eatBehavior = new MeatEat();
moveBehavior = new WalkMove();的实现确定了狗狗的行为与进食方式

public class Dog extends Animals{
    Dog(){
        eatBehavior = new MeatEat();
        moveBehavior = new WalkMove();
    }

    //...
}

万事具备,就差检验结果

public class test {
    public static void main(String[] args) {
        Animals dog = new Dog();
        Animals bird = new Bird();

        //dog与bird共同固定属性
        dog.smile();
        bird.smile();

        System.out.println("dog的进食方式:");
        dog.eat();
        System.out.println("bird的进食方式:");
        bird.eat();

        System.out.println("dog的行动方式:");
        dog.move();
        System.out.println("bird的行动方式:");
        bird.move();

        //运行时动态改变其行为方式
        System.out.println("bird的改变了方式:");
        bird.setEatBehavior(new VegetarianEat());
        bird.eat();
        System.out.println("dog的进化了行动方式:");
        dog.setMoveBehavior(new FlyMove());
        dog.move();

    }
}

打印结果:

微笑,say:hello word
微笑,say:hello word
dog的进食方式:
肉食
bird的进食方式:
素食
dog的行动方式:
步行
bird的行动方式:
飞行
bird的改变了方式:
素食
dog的进化了行动方式:
飞行

以上,策略模式简单使用。

  • 优点:在一些情况下可以复用很多代码,增强代码的扩展行。
  • 缺点:有可造成会有很多策略类的情况,并且策略类的实现,要求基类必须定义好所以接口对象,基类子类不管是否需要,都必须知道所以策略。

仅此记录策略模式的学习笔记。与大家共享,请大家多多建议。

代码传送门:git@github.com:pffo/pattern.git

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容

  • 一、什么是策略模式 策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,...
    雅俗共赏M阅读 460评论 0 0
  • 1. 概述 (1)策略模式的功能 策略模式的功能是把具体的算法实现,从具体的业务处理里面独立出来,把它们实现成为单...
    CrixalisAs阅读 177评论 0 0
  • 策略模式定义: 定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而...
    _凉笙阅读 332评论 0 1
  • Android 架构师之路 目录 1、策略模式概念 1.1 介绍 在策略模式(Strategy Pattern)中...
    香沙小熊阅读 1,069评论 0 1
  • 【原创】思念 2017年3月30日 爷爷 噙着烟锅 看自己垒的墙 爷爷的烟锅杆 是黄铜的 跟我的胳膊一样长 爷爷是...
    浑沌闻溪阅读 261评论 1 2