常用设计模式

软件设计的六大原则SOLID:

  • 单一职责:一个类应该只负责一个方面的任务,如果一个类承担了过多的任务,修改其中一部分可能会影响到其它类的功能。
  • 开闭原则:对修改关闭,对扩展开放,类、模块、函数等应该可以在已有代码不被修改的情况下增添新功能。
  • 依赖倒置:鼓励创建抽象类或接口,通过依赖注入的方式,让具体实现类依赖于这些抽象类
  • 接口隔离:将大的接口分成更小更具体的接口,让类只需要关心他们真正需要的接口。
  • 里氏替换:子类对象应该能够替换其父类对象,而不破坏程序的正确性。换句话说,这意味着子类应当遵循父类的行为约定,父类定义的行为在子类中依然成立。
  • 组合优于继承:可以通过包含其它对象来扩展类的行为,通过对象的组合来获得更灵活的代码重用机制,避免继承带来的紧密耦合问题。

常用的设计模式:

工厂模式:旨在将对象的创建过程从其使用过程中分离出来,以提高系统的灵活性和可维护性。在这种模式下,客户端代码不直接实例化具体产品类。相反,它通过使用一个共同的工厂接口,依赖于工厂类来创建具体产品的实例。这种方式允许客户端代码在不知道具体产品类细节的情况下工作,从而使系统更容易扩展和维护。举一个类比,这就像在餐厅点餐时,你不需要知道食物是如何准备的,你只需要从菜单中选择你想要的食物,并等待厨房准备好送到你的桌上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Chart:
def draw(self):
raise NotImplementedError("This method should be overridden by subclasses.")

class ScatterChart(Chart):
def draw(self):
return "Drawing ScatterChart."

class LineChart(Chart):
def draw(self):
return "Drawing LineChart."

class BarChart(Chart):
def draw(self):
return "Drawing BarChart."

class ChartFactory:
def create_chart(self, data_type, data_size, user_preference):
if data_type == 'continuous':
if data_size > 1000:
return ScatterChart()
else:
return LineChart()
elif data_type == 'categorical':
if user_preference == 'detail':
return BarChart()
else:
return LineChart()
# Add more logic as needed
else:
raise ValueError("Unsupported data type or preferences")

# Client code
factory = ChartFactory()
chart = factory.create_chart('continuous', 1200, None)
print(chart.draw())

策略模式:是一种行为模式,它主要关注对象的行为和算法的选择。这个模式允许开发者定义一系列的算法,把它们封装在独立的策略类中,并在运行时确定使用哪一个算法。这样,这种模式使得客户端可以在不同算法间切换,而无需关心算法的具体实现细节。客户端的选择通常基于运行时的条件或者需求变更,而策略模式使得这种选择变得灵活和可扩展。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from abc import ABC, abstractmethod

# 定义策略接口
class RenderStrategy(ABC):
@abstractmethod
def render(self, text):
pass

# 实现文本渲染策略
class TextRenderStrategy(RenderStrategy):
def render(self, text):
return text

# 实现Markdown渲染策略
class MarkdownRenderStrategy(RenderStrategy):
def render(self, text):
return f"**{text}**" # 假设简单地将文本加粗表示Markdown渲染

# 上下文,用于使用策略
class ContentRenderer:
def __init__(self, strategy: RenderStrategy):
self.strategy = strategy

def render(self, text):
return self.strategy.render(text)

# 在运行时根据条件选择策略
if __name__ == "__main__":
# 假设这是根据用户输入或其他条件动态决定的
user_preference = "markdown"

if user_preference == "text":
strategy = TextRenderStrategy()
elif user_preference == "markdown":
strategy = MarkdownRenderStrategy()

renderer = ContentRenderer(strategy)
print(renderer.render("Hello, Strategy Pattern!"))

观察者模式:是一种行为模式,允许观察者对象监听某个被观察者对象的状态变化,当被观察者对象的状态发生变化时,它会自动通知所有注册的观察者,触发他们执行相应的更新操作。这种模式特别是用于创建松耦合的系统。我不清楚上述过程中观察者是如何注册的,并且被观察者如何通知的观察者?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
class Observer:
def update(self, news):
"""接收新闻更新的方法。

该方法应当由继承自Observer类的所有子类实现,以便当新闻发布者有新闻更新时,能够通知所有订阅者。

Args:
news: 一个字符串,表示接收到的新闻内容。
"""
pass

class EmailSubscriber(Observer):
def update(self, news):
"""当新闻更新时,通过电子邮件通知订阅者。

实现Observer类中的update方法,以电子邮件形式接收新闻。

Args:
news: 一个字符串,表示接收到的新闻内容。
"""
print(f"Email Subscriber received news: {news}")

class SMSSubscriber(Observer):
def update(self, news):
"""当新闻更新时,通过短信通知订阅者。

实现Observer类中的update方法,以短信形式接收新闻。

Args:
news: 一个字符串,表示接收到的新闻内容。
"""
print(f"SMS Subscriber received news: {news}")

class NewsPublisher:
def __init__(self):
"""初始化新闻发布者。

创建一个新的新闻发布者实例,该实例可以注册和注销观察者,同时发布新闻给所有注册的观察者。
"""
self.__subscribers = []
self.__latestNews = None

def register(self, subscriber):
"""注册一个新的观察者以接收新闻更新。

Args:
subscriber: 一个Observer类的实例,表示要注册的观察者。
"""
if subscriber not in self.__subscribers:
self.__subscribers.append(subscriber)

def unregister(self, subscriber):
"""注销一个观察者,使其不再接收新闻更新。

Args:
subscriber: 一个Observer类的实例,表示要注销的观察者。
"""
self.__subscribers.remove(subscriber)

def notifySubscribers(self):
"""通知所有注册的观察者最新的新闻。

遍历所有注册的观察者,并调用它们的update方法,传递最新的新闻内容。
"""
for subscriber in self.__subscribers:
subscriber.update(self.__latestNews)

def addNews(self, news):
"""添加新闻并通知所有注册的观察者。

设置最新的新闻内容,并自动调用notifySubscribers方法通知所有观察者。

Args:
news: 一个字符串,表示要发布的新闻内容。
"""
self.__latestNews = news
self.notifySubscribers()

if __name__ == "__main__":
# 创建被观察者
news_publisher = NewsPublisher()

# 创建观察者
email_subscriber = EmailSubscriber()
sms_subscriber = SMSSubscriber()

# 注册观察者
news_publisher.register(email_subscriber)
news_publisher.register(sms_subscriber)

# 添加一条新闻,自动通知所有观察者
news_publisher.addNews("New Python Version Released!")

# 注销一个观察者
news_publisher.unregister(email_subscriber)

# 添加另一条新闻,只有注册的观察者会收到通知
news_publisher.addNews("New Java Version Released!")

单例模式是一种确保类在任何给定时间内只有一个实例的设计模式,并提供一个全局访问点来获取该实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import threading

class SingletonClass:
_instance = None
_lock = threading.Lock()

def __new__(cls, *args, **kwargs):
with cls._lock:
if not cls._instance:
cls._instance=super(SingletonClass, cls).__new__(cls, *args, **kwargs)
return cls._instance

from functools import wraps

def singleton(cls):
instances = {}
lock = threading.Lock()

@wraps(cls)
def wrapper(*args, **kwargs):
if cls not in instances:
with lock:
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper







:D 一言句子获取中...