策略模式
该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。接口隔离
结构
-
抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
-
具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。
-
环境(Context)类:持有一个策略类的引用,最终给客户端调用。
代码
package wnan.strategy;
/*****UTF-8*****
* Description: 抽象策略 折扣接口
* Author: wnan
* Create Date: 2024/10/5 10:38
* Proverbs: 吃得苦中苦,方为人上人
*/
public interface Discount {
void show();
}
package wnan.strategy;
/*****UTF-8*****
* Description: 具体策略角色 折扣A
* Author: wnan
* Create Date: 2024/10/5 10:39
* Proverbs: 吃得苦中苦,方为人上人
*/
public class DiscountA implements Discount{
@Override
public void show() {
System.out.println("买一送一");
}
}
package wnan.strategy;
/*****UTF-8*****
* Description: 具体策略角色 折扣B
* Author: wnan
* Create Date: 2024/10/5 10:40
* Proverbs: 吃得苦中苦,方为人上人
*/
public class DiscountB implements Discount{
@Override
public void show() {
System.out.println("打一折");
}
}
package wnan.strategy;
/*****UTF-8*****
* Description: 环境角色 售货员类
* Author: wnan
* Create Date: 2024/10/5 10:42
* Proverbs: 吃得苦中苦,方为人上人
*/
public class SalesMan {
// 持有抽象策略角色的引用
private Discount discount;
public SalesMan(Discount discount){
this.discount = discount;
}
public void salesManShow(){
System.out.println("售货员介绍折扣:");
discount.show();
}
}
package wnan.strategy;
/*****UTF-8*****
* Description: 策略模式
* Author: wnan
* Create Date: 2024/10/5 10:36
* Proverbs: 吃得苦中苦,方为人上人
*/
public class Client {
public static void main(String[] args) {
// 折扣A
SalesMan man=new SalesMan(new DiscountA());
man.salesManShow();
// 折扣B
SalesMan man1 = new SalesMan(new DiscountB());
man1.salesManShow();
}
}
分析
优点:
策略类之间可以自由切换,由于策略类都实现同一个接口,所以使它们之间可以自由切换。
易于扩展,增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合“开闭原则“
避免使用多重条件选择语句(if-else),充分体现面向对象设计思想。
缺点:
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。