使用Python实现策略模式的步骤

2023-04-04 00:00:00 模式 策略 步骤

策略模式是一种设计模式,它允许在运行时选择算法的不同实现。它的核心思想是将算法实现和调用代码分离,使得它们可以独立地进行变化和扩展。在Python中,实现策略模式的步骤如下:

定义策略接口
定义一个策略接口,它包含一个执行算法的方法。在本例中,我们将定义一个名为TextFormatter的接口,并在其中定义一个名为format_text的方法:

class TextFormatter:
    def format_text(self, text):
        pass

实现具体策略
定义具体的策略类来实现TextFormatter接口。在本例中,我们将定义两个具体的策略类,一个用于将文本转换为小写,另一个用于将文本转换为大写:

class LowercaseFormatter(TextFormatter):
    def format_text(self, text):
        return text.lower()

class UppercaseFormatter(TextFormatter):
    def format_text(self, text):
        return text.upper()

创建上下文类
创建一个上下文类,它包含一个策略对象,并在其__init__方法中将其初始化为默认值。在本例中,我们将创建一个名为TextContext的类:

class TextContext:
    def __init__(self, formatter=LowercaseFormatter()):
        self._formatter = formatter

    def format_text(self, text):
        return self._formatter.format_text(text)

使用上下文类

现在我们可以创建一个TextContext对象,并调用它的format_text方法来执行所选的算法。在本例中,我们将创建一个名为text的字符串,并将其传递给TextContext对象的format_text方法:

text = "pidancode.com"
lowercase_context = TextContext(LowercaseFormatter())
uppercase_context = TextContext(UppercaseFormatter())

print(lowercase_context.format_text(text))  # pidancode.com
print(uppercase_context.format_text(text))  # PIDANCODE.COM

完整的代码示例:

class TextFormatter:
    def format_text(self, text):
        pass


class LowercaseFormatter(TextFormatter):
    def format_text(self, text):
        return text.lower()


class UppercaseFormatter(TextFormatter):
    def format_text(self, text):
        return text.upper()


class TextContext:
    def __init__(self, formatter=LowercaseFormatter()):
        self._formatter = formatter

    def format_text(self, text):
        return self._formatter.format_text(text)


text = "pidancode.com"
lowercase_context = TextContext(LowercaseFormatter())
uppercase_context = TextContext(UppercaseFormatter())

print(lowercase_context.format_text(text))  # pidancode.com
print(uppercase_context.format_text(text))  # PIDANCODE.COM

可选:使用工厂函数

如果有多个具体的策略类,每次创建TextContext对象并传递策略对象可能会很麻烦。这时可以使用一个工厂函数来创建TextContext对象,它将根据传递的参数返回正确的策略对象。在本例中,我们将创建一个名为create_text_context的工厂函数:

def create_text_context(formatter_type):
    if formatter_type == "lowercase":
        return TextContext(LowercaseFormatter())
    elif formatter_type == "uppercase":
        return TextContext(UppercaseFormatter())
    else:
        raise ValueError("Invalid formatter type")

使用工厂函数创建上下文类

现在我们可以使用工厂函数来创建TextContext对象,并根据需要传递格式化程序的类型。在本例中,我们将创建一个名为text的字符串,并使用工厂函数create_text_context创建两个TextContext对象:

text = "pidancode.com"
lowercase_context = create_text_context("lowercase")
uppercase_context = create_text_context("uppercase")

print(lowercase_context.format_text(text))  # pidancode.com
print(uppercase_context.format_text(text))  # PIDANCODE.COM

完整的代码示例:

class TextFormatter:
    def format_text(self, text):
        pass


class LowercaseFormatter(TextFormatter):
    def format_text(self, text):
        return text.lower()


class UppercaseFormatter(TextFormatter):
    def format_text(self, text):
        return text.upper()


class TextContext:
    def __init__(self, formatter=LowercaseFormatter()):
        self._formatter = formatter

    def format_text(self, text):
        return self._formatter.format_text(text)


def create_text_context(formatter_type):
    if formatter_type == "lowercase":
        return TextContext(LowercaseFormatter())
    elif formatter_type == "uppercase":
        return TextContext(UppercaseFormatter())
    else:
        raise ValueError("Invalid formatter type")


text = "pidancode.com"
lowercase_context = create_text_context("lowercase")
uppercase_context = create_text_context("uppercase")

print(lowercase_context.format_text(text))  # pidancode.com
print(uppercase_context.format_text(text))  # PIDANCODE.COM

使用装饰器
除了使用工厂函数外,还可以使用装饰器来实现策略模式。装饰器是Python的一个强大功能,它允许我们通过修改函数或类的行为来改变它们的功能。

在本例中,我们将使用一个装饰器来修改TextContext类的行为,以便在运行时更改它的格式化程序。我们将创建一个名为formatter的装饰器,它将接受一个格式化程序对象并将其分配给类的_formatter属性。然后,我们可以使用这个装饰器来创建两个不同格式化程序的TextContext对象。

def formatter(formatter_cls):
    def wrapper(text_context_cls):
        text_context_cls._formatter = formatter_cls()
        return text_context_cls
    return wrapper


class TextFormatter:
    def format_text(self, text):
        pass


class LowercaseFormatter(TextFormatter):
    def format_text(self, text):
        return text.lower()


class UppercaseFormatter(TextFormatter):
    def format_text(self, text):
        return text.upper()


@formatter(LowercaseFormatter)
class TextContext:
    def format_text(self, text):
        return self._formatter.format_text(text)


@formatter(UppercaseFormatter)
class TextContext2:
    def format_text(self, text):
        return self._formatter.format_text(text)


text = "pidancode.com"
lowercase_context = TextContext()
uppercase_context = TextContext2()

print(lowercase_context.format_text(text))  # pidancode.com
print(uppercase_context.format_text(text))  # PIDANCODE.COM

完整的代码示例:

def formatter(formatter_cls):
    def wrapper(text_context_cls):
        text_context_cls._formatter = formatter_cls()
        return text_context_cls
    return wrapper


class TextFormatter:
    def format_text(self, text):
        pass


class LowercaseFormatter(TextFormatter):
    def format_text(self, text):
        return text.lower()


class UppercaseFormatter(TextFormatter):
    def format_text(self, text):
        return text.upper()


@formatter(LowercaseFormatter)
class TextContext:
    def format_text(self, text):
        return self._formatter.format_text(text)


@formatter(UppercaseFormatter)
class TextContext2:
    def format_text(self, text):
        return self._formatter.format_text(text)


text = "pidancode.com"
lowercase_context = TextContext()
uppercase_context = TextContext2()

print(lowercase_context.format_text(text))  # pidancode.com
print(uppercase_context.format_text(text))  # PIDANCODE.COM

使用枚举类

在Python中,我们可以使用enum模块创建枚举类型。使用枚举类,我们可以将不同的策略实现定义为不同的枚举成员。在这种情况下,我们可以将不同的文本格式化器定义为枚举成员,并将它们分配给TextContext对象。

import enum


class Formatter(enum.Enum):
    LOWERCASE = 1
    UPPERCASE = 2


class TextContext:
    def __init__(self, formatter):
        self._formatter = formatter

    def format_text(self, text):
        if self._formatter == Formatter.LOWERCASE:
            return text.lower()
        elif self._formatter == Formatter.UPPERCASE:
            return text.upper()


text = "pidancode.com"
lowercase_context = TextContext(Formatter.LOWERCASE)
uppercase_context = TextContext(Formatter.UPPERCASE)

print(lowercase_context.format_text(text))  # pidancode.com
print(uppercase_context.format_text(text))  # PIDANCODE.COM

完整的代码示例:

import enum


class Formatter(enum.Enum):
    LOWERCASE = 1
    UPPERCASE = 2


class TextContext:
    def __init__(self, formatter):
        self._formatter = formatter

    def format_text(self, text):
        if self._formatter == Formatter.LOWERCASE:
            return text.lower()
        elif self._formatter == Formatter.UPPERCASE:
            return text.upper()


text = "pidancode.com"
lowercase_context = TextContext(Formatter.LOWERCASE)
uppercase_context = TextContext(Formatter.UPPERCASE)

print(lowercase_context.format_text(text))  # pidancode.com
print(uppercase_context.format_text(text))  # PIDANCODE.COM

使用函数映射表

在Python中,我们可以使用函数映射表来实现策略模式。函数映射表是一个字典,它将不同的策略实现映射到不同的函数上。在这种情况下,我们可以将不同的文本格式化器定义为函数,并将它们分配给函数映射表。

def lowercase_formatter(text):
    return text.lower()


def uppercase_formatter(text):
    return text.upper()


formatter_map = {
    "lowercase": lowercase_formatter,
    "uppercase": uppercase_formatter,
}


class TextContext:
    def __init__(self, formatter_name):
        self._formatter = formatter_map[formatter_name]

    def format_text(self, text):
        return self._formatter(text)


text = "pidancode.com"
lowercase_context = TextContext("lowercase")
uppercase_context = TextContext("uppercase")

print(lowercase_context.format_text(text))  # pidancode.com
print(uppercase_context.format_text(text))  # PIDANCODE.COM

完整的代码示例:

def lowercase_formatter(text):
    return text.lower()


def uppercase_formatter(text):
    return text.upper()


formatter_map = {
    "lowercase": lowercase_formatter,
    "uppercase": uppercase_formatter,
}


class TextContext:
    def __init__(self, formatter_name):
        self._formatter = formatter_map[formatter_name]

    def format_text(self, text):
        return self._formatter(text)


text = "pidancode.com"
lowercase_context = TextContext("lowercase")
uppercase_context = TextContext("uppercase")

print(lowercase_context.format_text(text))  # pidancode.com
print(uppercase_context.format_text(text))  # PIDANCODE.COM

相关文章