在开发软件应用程序(根据应用程序类型的不同)时,在编写实际代码之前,在开发的设计阶段需要回答问题。这些问题之一是,如何构建我的应用程序?软件设计模式可以帮助回答这个结构问题。设计模式有助于我们以使其可靠,可维护和易于理解的方式构建应用程序。
设计模式是用于修复代码库中与结构有关的问题的高级概念。它们不是特定于语言的,因此您可以使用任何支持对象的编程的语言使用它们。在本文中,我们将了解一种流行的设计模式,称为策略模式。
先决条件
在进行战略模式之前,您需要对面向对象的编程有基本的了解。类和对象是设计模式概念的核心部分。
什么是策略模式?
策略模式是定义算法集合的设计模式,并允许这些算法在运行时可以互换。根据有关设计模式的书,Eric Freeman&Elisabeth Robson的“Head First: Design Patterns”,
策略模式定义了一个算法家族,封装了每种算法,并使其可互换。策略使该算法与使用它的客户的独立性不同。
在某些情况下,您可以拥有多种方法来完成特定任务。这些不同的方式是算法。传统上,您倾向于将有条件的陈述(IF-ELSE)视为确定要使用哪种算法的一种方式。此方法不是编写良好和干净的代码的更好方法。同样,随着算法数量的增加,代码变得更长,更难维护。
在这种情况下,策略模式是一个很好的解决方案。策略模式使您可以定义包含各种算法的实现的称为策略的类。主类有对策略的引用,然后您可以将您的首选策略传递给上下文。让我们看一下策略模式的示例实现。
执行
让我们说我们有一个电子商务应用程序,可以在其中注册产品。在注册这些产品时,我们希望为每个产品生成独特的ID。我们希望能够使用不同的标准和参数生成ID。我们将使用策略设计模式来制定两个可切换策略来生成产品ID。首先,我们有一个RandomStrategy
,该RandomStrategy
将产品ID作为随机字符串生成。相比之下,另一个DerivedStrategy
使用产品的详细信息(例如日期时间,类别和sku。
我们有我们的strategy.py
文件。该文件包含用于生成产品ID及其不同实现的算法家族(在我们的情况下,strategies
)。
from abc import ABC, abstractmethod
from datetime import datetime
import string
import secrets
class ProductIdStrategy(ABC):
"""An interface for strategy type"""
@abstractmethod
def generate_product_id() -> None:
"""Each class will have its own implementation of this function"""
pass
class RandomStrategy(ProductIdStrategy):
def generate_product_id(self) -> str:
limit = 12
product_id = "".join(secrets.choice(
string.ascii_uppercase+string.digits) for i in range(limit))
return product_id
class DerivedStrategy(ProductIdStrategy):
''' The Derived Strategy will derive the product id from the id, category and SKU of the product'''
def __init__(self, product) -> None:
super().__init__()
self.product = product
def generate_product_id(self) -> str:
id = self.product["id"]
# Get the first 3 characters of the category
category = self.product["category"][:3].upper()
sku = self.product["sku"]
# Get the date string and replace remove the hyphens
date = datetime.strptime(self.product["date_added"], "%Y-%m-%d").date().__str__().replace("-", "")
product_id = "".join([category, "-", date, "-", sku, id,])
return product_id
然后我们有一个product.py
文件。在此文件中,我们可以互换实施不同的策略。
from strategy import *
class Product:
_strategy: ProductIdStrategy
def __init__(self, strategy: ProductIdStrategy) -> None:
self._strategy = strategy
def get_product_id(self) -> str:
return self._strategy.generate_product_id()
if __name__ == "__main__":
stock = {
"id": "1",
"name": "Maxi Lotion",
"category": "Skin Care",
"sku": "6134752",
"date_added": "2022-12-28",
}
''' Generating the product id using the random strategy '''
strategy = RandomStrategy()
product = Product(strategy)
print("The product id using the Random Strategy is : " + product.get_product_id())
'''
Generating the product id using the derived strategy
The product is passed into to the strategy so as to extract information from it
'''
strategy = DerivedStrategy(stock)
product = Product(strategy)
print("The product id using the Derived Strategy is : " + product.get_product_id())
结果显示了两个产品ID。一个是使用Random Strategy
生成的,另一个是用Derived Strategy
生成的。
结论
在本文中,我们了解了策略模式是什么以及如何实施它。借助策略设计模式,我们可以在运行时在算法之间切换,而无需更改代码。策略模式可用于选择应用程序的行为,而不是使用条件表达式。
我希望本文向您展示如何实施策略设计模式。您可以在此GitHub存储库中获取示例代码。