小知识,大挑战!本文正在参与 “程序员必备小知识” 创作活动
初衷 :因架构(开发)场景(需求)而使用设计模式,莫为了使用设计模式而设计架构场景!
设计模式共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();
}
}