一、设计模式是什么
- 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因
二、设计模式的分类
- 设计模式共23种
- 这些模式可以分为三大类
- 创建型模式(Creational Patterns)
- 结构型模式(Structural Patterns)
- 行为型模式(Behavioral Patterns)
三、策略模式
1.简介
- 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
- 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
2.实现
- 首先创建一个接口
public interface Strategy {
public int doOperation(int num1, int num2);
}
- 创建接口实现类
public class OperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
public class OperationSubtract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
- 创建 Context 类
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
- 使用 Context 来查看当它改变策略 Strategy 时的行为变化
public class StrategyDemo {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubtract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
}
}
3.主要解决
- 在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
4.优缺点
-
优点
- 算法可以自由切换。
- 避免使用多重条件判断。
- 扩展性良好。
-
缺点
- 策略类会增多。
- 所有策略类都需要对外暴露。
5. 注意事项
- 策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题
四、模板模式
1. 简介
- 在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。
2. 实现
- 创建一个抽象类,它的模板方法被设置为 final
public abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
//模板
public final void play(){
//初始化游戏
initialize();
//开始游戏
startPlay();
//结束游戏
endPlay();
}
}
- 继承抽象类,实现抽象方法
public class Cricket extends Game {
@Override
void endPlay() {
System.out.println("Cricket Game Finished!");
}
@Override
void initialize() {
System.out.println("Cricket Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Cricket Game Started. Enjoy the game!");
}
}
public class Football extends Game {
@Override
void endPlay() {
System.out.println("Football Game Finished!");
}
@Override
void initialize() {
System.out.println("Football Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Football Game Started. Enjoy the game!");
}
}
- 调用Game 的模板方法 play()
public class TemplatePatternDemo {
public static void main(String[] args) {
Game game = new Cricket();
game.play();
System.out.println();
game = new Football();
game.play();
}
}
3.主要解决
- 一些方法通用,却在每一个子类都重新写了这一方法。
4.优缺点
-
优点
- 封装不变部分,扩展可变部分。
- 提取公共代码,便于维护。
- 行为由父类控制,子类实现。
-
缺点
- 每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
5. 注意事项
- 为防止恶意操作,一般模板方法都加上 final 关键词
免责声明:上述案例源自菜鸟教程
五、区别
- 策略模式的核心在于使用者的策略,按照自己的策略进行扩展,即横向扩展
- 模板模式的核心在于骨干的定义,父类将执行的流程已经定义好,父类实现通用的逻辑处理,子类通过钩子方法或者父类的抽象方法,对个性化操作进行相应的实现,也就是个性化操作延时到子类实现,即纵向扩展