1. 概述

设计模式是人们在面对同类型软件工程设计问题所总结出的一些有用的经验,模式不是代码,而是某类问题的通用设计或者解决方案。这样说可能比较难以理解我们换一种说法。在我们的工作学习中会使用一个名词来对某一个复杂的现象进行抽象,而这个名词是被所有人熟知的,他的过程可能比较复杂,形容起来比较费力,但是通过这个名词别人就知道你描述的是什么。比如海市蜃楼,让你形容这种现象可能需要很多文字,但是你只需要海市蜃楼四个字别人就可以理解了。

设计模式就是程序员针对日常编码中一些常用的方法的总结,一般常见的是23个,通过名称让彼此知道做的是一件什么事。

设计模式和面向对象是分不开的,面向对象的特点是设计模式的基础。

2. 策略模式的原理

我们都知道在面向对象中,如果对父类做出修改,就会影响子类,也就是会有溢出效应,可以在子类中覆盖这个方法,这样实际上可以实现,但是问题是如果子类过多修改就会比较麻烦,而且这是一个重复的工作,不符合设计原则。或许我们可以想到不要在父类中实现这功能,可以在子类中去实现,这样也会有一个问题,如果需要实现的子类过多,这同样是重复的工作。

继承虽然很方便,但同样的会有溢出效应,超类挖的一个坑,每个子类都要填坑,增加工作量,复杂度O(N^2), 这显然不是一个好的设计。

分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象,原则就是,分离变化部分,封装接口,基于忌口编程各种功能。此模式让行为算法的变化独立于算法的使用者。

白话来讲策略模式就是将变化的部分抽象成接口,然后针对变化对接口进行实现,实现成多个实现类,相同接口的多个实现类就是算法族。比如我们有一个描述声音的接口,要分别实现他的好听声音和不好听声音,这两个声音就是算法族。

interface Voice {
    say() {}
}

class Good implements Voice {
    say() {
        console.log('good voice')
    }
}

class Bad implements Voice {
    say() {
        console.log('bad voice')
    }
}

父类中直接调用song方法,在子类中赋予这个人唱歌是否好听。这样就实现了定制。

class abstract Person {
    song() {
        this.voice.say();
    }
}

class A extends Person {
    constructor() {
        this.voice = new Good();
    }
}

class B extends Person {
    constructor() {
        this.voice = new Bad();
    }
}

A.song();
B.song();

多用组合少用继承,用行为类组合,而不是行为的继承,这样更有弹性。

转载须知

如转载必须标明文章出处文章名称文章作者,格式如下:

转自:【致前端 - https://madaozhijian.com】 策略模式  "隐冬"