行为型模式-策略模式
Posted 格林希尔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了行为型模式-策略模式相关的知识,希望对你有一定的参考价值。
行为型模式-策略模式
策略模式(Strategy)
解决算法选择问题
描述
定义了一组算法,并使得它们能够互相替换,从而使得算法的选择能够在运行时进行。这种方式可以使得系统更加灵活、可定制,同时也能够提高代码的复用性和可维护性。
适用环境
当需要在不同的算法之间进行切换时使用;当需要动态地将算法作为一个对象来处理时使用。
优点:
灵活性高,可以在运行期间动态地改变算法实现方法;代码复用度高,避免大量重复的算法代码出现。
缺点:
如果策略过多,会导致类的数量增加,使得系统更加复杂;客户端需要了解所有的策略类,并且自行决定使用哪一个策略类。
违反原则
开放-封闭原则:由于策略模式的特殊性质,新的策略类需要被接受并且应用到上下文中,在这个过程中就可能违反该原则。
代码实现
在销售图书的过程中需要根据不同的促销活动来计算每本书的折扣价格。现在使用传统的if-else语句来实现:
class Book:
def __init__(self, name, price):
self.name = name
self.price = price
def get_discounted_price(self, promotion):
if promotion == 'student_discount':
return self.price * 0.8
elif promotion == 'vip_discount':
return self.price * 0.7
elif promotion == 'new_year_discount':
return self.price * 0.5
else:
return self.price
book1 = Book('Python编程从入门到实践', 68.0)
discounted_price = book1.get_discounted_price('vip_discount')
print(f'book1.name的优惠价格是:discounted_price')
以上代码违反了开闭原则,如果需要添加新的促销活动,就需要修改Book类中的get_discounted_price方法,影响到系统的稳定性和可维护性。可以通过策略模式来解决这个问题,具体实现如下:
# 创建一个抽象类Promotion,定义一个抽象方法get_discounted_price,所有的具体策略类都继承该抽象类,并重写get_discounted_price方法。
from abc import ABC, abstractmethod
class Promotion(ABC):
@abstractmethod
def get_discounted_price(self, price):
pass
# 创建具体的策略类,分别实现不同的促销活动算法。
class StudentDiscount(Promotion):
def get_discounted_price(self, price):
return price * 0.8
class VIPDiscount(Promotion):
def get_discounted_price(self, price):
return price * 0.7
class NewYearDiscount(Promotion):
def get_discounted_price(self, price):
return price * 0.5
# 修改Book类,添加一个set_promotion方法,在该方法中设置促销活动对象
class Book:
def __init__(self, name, price):
self.name = name
self.price = price
self.promotion = None
def set_promotion(self, promotion):
self.promotion = promotion
def get_discounted_price(self):
if self.promotion:
return self.promotion.get_discounted_price(self.price)
else:
return self.price
book1 = Book('Python编程从入门到实践', 68.0)
book1.set_promotion(VIPDiscount())
discounted_price = book1.get_discounted_price()
print(f'book1.name的优惠价格是:discounted_price')
设计模式之策略模式(行为型)
一、模式定义
策略模式:定义一系列算法,然后将每一个算法封装起来,并将它们可以互相替换。也就是将一系列算法封装到一系列策略类里面。策略模式是一种对象行为型模式。策略模式符合“开闭原则“
Strategy Pattern: Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
二、模式角色
- Context :环境类
- Strategy:抽象策略类
- ConcreteStrategy:具体策略类
三、简单实例
不用策略模式的情况:
public class Context
{
……
public void method(String type)
{
......
if(type == "strategyA")
{
//算法A
}
else if(type == "strategyB")
{
//算法B
}
else if(type == "strategyC")
{
//算法C
}
......
}
……
}
抽象策略类:
public abstract class AbstractStrategy
{
public abstract void method();
}
具体策略类:
public class ConcreteStrategyA extends AbstractStrategy
{
public void method()
{
//算法A
}
}
环境类:
public class Context
{
private AbstractStrategy strategy;
public void setStrategy(AbstractStrategy strategy)
{
this.strategy= strategy;
}
public void method()
{
strategy.method();
}
}
客户端调用:
Context context = new Context();
AbstractStrategy strategy;
strategy = new ConcreteStrategyA();
context.setStrategy(strategy);
context.method();
四、策略模式和状态模式对比
相同点:
策略模式和状态模式都是属于行为型设计模式,也同样是对象行为型设计模式,非类行为型设计模式。
策略模式和状态模式有点类似,都符合”闭合原则“
两个设计模式都可以用于减少代码大量的if...else
不同点:
具体使用策略模式还是状态模式,可以通过环境类的状态而定,有很多状态的话,就使用状态模式。
使用策略模式时,环境类需要选择一个确定的策略类,也就是客户端调时需要关心具体状态,根据需要调用;而状态模式是不需要的,在状态模式里,环境类是要放在一个具体状态中的,也就是根据环境类的状态改变进行调用状态类的算法
对状态模式不是很熟悉,可以参考我以前写的一篇博客
https://blog.csdn.net/u014427391/article/details/85219470
以上是关于行为型模式-策略模式的主要内容,如果未能解决你的问题,请参考以下文章