设计模式 - 策略模式

177 阅读4分钟

小知识,大挑战!本文正在参与 “程序员必备小知识” 创作活动

初衷 :因架构(开发)场景(需求)而使用设计模式,莫为了使用设计模式而设计架构场景!

设计模式共23种,分为三种类型

  • 创建型模式:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式
  • 结构型模式:代理模式、装饰模式、外观模式、享元模式、桥接模式、组合模式、适配器模式
  • 行为型模式:观察者模式、策略模式、中介者模式、模版方法模式、命令模式、迭代器模式、职责链模式(责任链模式)、备忘录模式、解释器模式(Interpreter模式)、状态模式、访问者模式

基础概念

策略模式遵循了开闭原则,增加新的类不需要修改原有的代码,只需实现接口或者继承抽象类;
同时策略模式也遵循了里氏替换原则,具体的策略类都有相同的接口,只要在有父类出现的地方都可以使用子类替代 ~

策略模式是一种对算法封装的行为模式,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换,同时只适用管理一组同类型的算法,并且这些算法是完全互斥的情况;简而言之就是同一方法 - 不同承载类 - 不同实现方式,其还有以下特点

  • 多个具体策略的区别,主要在于其内部表现行为不同
  • 在使用策略模式时动态选择具体要执行的策略 ,需要在不同情况下使用不同的策略(算法)
  • 对客户隐藏具体策略(算法)的实现细节,彼此完全独立
角色分配

抽象策略者 Strategy

根据目标,定义共性方法

具体策略者 ConcreteStrategy

共性方法之下每个策略者各自执行逻辑

环境类 Context

上下文类 - 达到承上启下,统一出口,便于管理

优缺点

优点

  • 切换自由,使用方便,扩展性强
  • 减少多重场景判断,遵循开闭原则

缺点

  • 策略类均对外暴露
  • 一般超过4个具体策略者不太利于维护,就需要考虑使用混合模式
  • 复用性低
模式之间的区别

与工厂模式的区别

工厂模式是创建型模式 ,它关注对象创建,提供创建对象的接口,让对象的创建与具体的使用客户无关。 策略模式是对象行为型模式 ,它关注行为和算法的封装

与状态模式的区别

策略模式只是条件选择方法,只执行一次方法,而状态模式是随着状态的改变不停地更改执行方法

案例讲解

马上过年了,回家后长辈一般都会问小辈从事什么工作?可能问到你,也可能问到其他的亲朋好友 ~

针对这种场景我们分析后发现

  • 从事的职业范围就是一个抽象策略者
  • 每个人回答自己的职业内容就是一个具体策略者
  • 假若长辈通过亲戚的口中询问任意哪一位兄弟姐妹,我们使用一个上下文类,也就是这里实现了出口统一
代码实现

抽象策略者

Strategy

package nkwl.com.propertyfactory;

/**
 * @author MrLiu
 * @date 2020/1/9
 * desc
 */
public interface Strategy {
    void job();
}

具体策略者

ConcreteJobA

package nkwl.com.propertyfactory;

import android.util.Log;

/**
 * @author MrLiu
 * @date 2020/1/9
 * desc
 */
public class ConcreteJobA implements Strategy {

    @Override
    public void job() {
        Log.e("tag", "A的工作:程序员");
    }
}

ConcreteJobB

package nkwl.com.propertyfactory;

import android.util.Log;

/**
 * @author MrLiu
 * @date 2020/1/9
 * desc
 */
public class ConcreteJobB implements Strategy {

    @Override
    public void job() {
        Log.e("tag", "B的工作:设计师");
    }
}

ConcreteJobC

package nkwl.com.propertyfactory;

import android.util.Log;

/**
 * @author MrLiu
 * @date 2020/1/9
 * desc
 */
public class ConcreteJobC implements Strategy {

    @Override
    public void job() {
        Log.e("tag", "C的工作:产品经理");
    }
}

上下文类

Context

package nkwl.com.propertyfactory;

/**
 * @author MrLiu
 * @date 2020/1/9
 * desc
 */
public class Context {
    public Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void jobStrategy() {
    	//共性方法,不同行为
        strategy.job();
    }
}
调用场景
package nkwl.com.propertyfactory;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Context jobA = new Context(new ConcreteJobA());
        jobA.jobStrategy();
        
        Context jobB = new Context(new ConcreteJobB());
        jobB.jobStrategy();
        
        Context jobC = new Context(new ConcreteJobC());
        jobC.jobStrategy();
    }
}
实现结果

在这里插入图片描述