??發(fā)現(xiàn)寶藏
前些天發(fā)現(xiàn)了一個(gè)巨牛的人工智能學(xué)習(xí)網(wǎng)站,通俗易懂,風(fēng)趣幽默,忍不住分享一下給大家。【點(diǎn)擊進(jìn)入巨牛的人工智能學(xué)習(xí)網(wǎng)站】。
Python中的設(shè)計(jì)模式與最佳實(shí)踐
在軟件開發(fā)中,設(shè)計(jì)模式是一種解決常見問題的經(jīng)過驗(yàn)證的解決方案。Python作為一種流行的編程語言,具有豐富的庫和靈活的語法,使其成為實(shí)現(xiàn)設(shè)計(jì)模式的理想選擇。本文將介紹幾種常見的設(shè)計(jì)模式,并提供相應(yīng)的Python示例代碼,以便讀者了解如何在Python中應(yīng)用這些設(shè)計(jì)模式。
1. 單例模式(Singleton Pattern)
單例模式確保一個(gè)類只有一個(gè)實(shí)例,并提供全局訪問點(diǎn)。
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
# 示例
singleton1 = Singleton()
singleton2 = Singleton()
print(singleton1 is singleton2) # Output: True
2. 工廠模式(Factory Pattern)
工廠模式用于創(chuàng)建對(duì)象的接口,但允許子類決定實(shí)例化哪個(gè)類。它將實(shí)例化邏輯委托給子類。
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Dog(Animal):
def sound(self):
return "Woof!"
class Cat(Animal):
def sound(self):
return "Meow!"
class AnimalFactory:
def get_animal(self, animal_type):
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
else:
raise ValueError("Invalid animal type")
# 示例
factory = AnimalFactory()
dog = factory.get_animal("dog")
cat = factory.get_animal("cat")
print(dog.sound()) # Output: Woof!
print(cat.sound()) # Output: Meow!
3. 觀察者模式(Observer Pattern)
觀察者模式定義了對(duì)象之間的一對(duì)多依賴關(guān)系,使得當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生變化時(shí),其所有依賴項(xiàng)都會(huì)收到通知并自動(dòng)更新。
class Observer:
def update(self, message):
pass
class Subject:
def __init__(self):
self._observers = []
def add_observer(self, observer):
self._observers.append(observer)
def remove_observer(self, observer):
self._observers.remove(observer)
def notify_observers(self, message):
for observer in self._observers:
observer.update(message)
class MessagePublisher(Subject):
def publish_message(self, message):
self.notify_observers(message)
class MessageSubscriber(Observer):
def __init__(self, name):
self.name = name
def update(self, message):
print(f"{self.name} received message: {message}")
# 示例
publisher = MessagePublisher()
subscriber1 = MessageSubscriber("Subscriber 1")
subscriber2 = MessageSubscriber("Subscriber 2")
publisher.add_observer(subscriber1)
publisher.add_observer(subscriber2)
publisher.publish_message("Hello, observers!")
# Output:
# Subscriber 1 received message: Hello, observers!
# Subscriber 2 received message: Hello, observers!
4. 策略模式(Strategy Pattern)
策略模式定義了一系列算法,并將每個(gè)算法封裝起來,使它們可以相互替換。該模式可以使算法的變化獨(dú)立于使用它們的客戶端。
from abc import ABC, abstractmethod
class Strategy(ABC):
@abstractmethod
def execute(self, a, b):
pass
class AddStrategy(Strategy):
def execute(self, a, b):
return a + b
class SubtractStrategy(Strategy):
def execute(self, a, b):
return a - b
class Context:
def __init__(self, strategy):
self._strategy = strategy
def execute_strategy(self, a, b):
return self._strategy.execute(a, b)
# 示例
add_strategy = AddStrategy()
subtract_strategy = SubtractStrategy()
context = Context(add_strategy)
result1 = context.execute_strategy(5, 3) # Output: 8
context = Context(subtract_strategy)
result2 = context.execute_strategy(5, 3) # Output: 2
5. 裝飾器模式(Decorator Pattern)
裝飾器模式允許向一個(gè)對(duì)象動(dòng)態(tài)地添加新功能,同時(shí)不改變其結(jié)構(gòu)。它是一種以透明、動(dòng)態(tài)方式擴(kuò)展對(duì)象的功能。
def make_bread(func):
def wrapper():
print("Mixing ingredients")
func()
print("Baking the bread")
return wrapper
@make_bread
def make_sandwich():
print("Making sandwich")
make_sandwich()
# Output:
# Mixing ingredients
# Making sandwich
# Baking the bread
6. 原型模式(Prototype Pattern)
原型模式用于創(chuàng)建對(duì)象的一種模式,通過復(fù)制現(xiàn)有對(duì)象來創(chuàng)建新對(duì)象,從而避免了使用復(fù)雜的構(gòu)造函數(shù)。
import copy
class Prototype:
def __init__(self):
self._objects = {}
def register_object(self, name, obj):
self._objects[name] = obj
def unregister_object(self, name):
del self._objects[name]
def clone(self, name, **attrs):
obj = copy.deepcopy(self._objects.get(name))
obj.__dict__.update(attrs)
return obj
# 示例
class Car:
def __init__(self):
self.make = "Toyota"
self.model = "Corolla"
self.year = "2022"
car_prototype = Car()
prototype = Prototype()
prototype.register_object("car", car_prototype)
car = prototype.clone("car", year="2023")
這段代碼展示了原型模式(Prototype Pattern)的實(shí)現(xiàn)。原型模式用于創(chuàng)建對(duì)象的一種模式,它允許通過復(fù)制現(xiàn)有對(duì)象來創(chuàng)建新對(duì)象,而不是通過實(shí)例化類來創(chuàng)建。讓我們來解析一下:
-
Prototype類:
-
__init__
方法初始化一個(gè)空字典_objects
,用于存儲(chǔ)注冊(cè)的對(duì)象。 -
register_object
方法用于注冊(cè)對(duì)象,將對(duì)象存儲(chǔ)在_objects
字典中,以便稍后克隆使用。 -
unregister_object
方法用于注銷對(duì)象,從_objects
字典中刪除特定名稱的對(duì)象。 -
clone
方法用于克隆對(duì)象。它接受一個(gè)名稱參數(shù),指定要克隆的對(duì)象的名稱,并且可以接受額外的關(guān)鍵字參數(shù)來更新克隆對(duì)象的屬性。它使用copy.deepcopy
創(chuàng)建對(duì)象的深層副本,以避免對(duì)象間共享狀態(tài)的問題。然后通過更新克隆對(duì)象的__dict__
屬性來應(yīng)用任何額外的屬性更改,然后返回克隆后的對(duì)象。
-
-
示例類 Car:
- 定義了一個(gè)簡(jiǎn)單的 Car 類,具有 make、model 和 year 屬性。這是我們要克隆的對(duì)象的示例。
-
使用原型模式:
- 創(chuàng)建了一個(gè) Car 類的實(shí)例
car_prototype
。 - 創(chuàng)建了一個(gè) Prototype 實(shí)例
prototype
。 - 使用
register_object
方法將car_prototype
注冊(cè)到原型中,名稱為 “car”。 - 使用
clone
方法從原型中克隆一個(gè) Car 對(duì)象,名為 “car”,并且更新了 year 屬性為 “2023”。
- 創(chuàng)建了一個(gè) Car 類的實(shí)例
總之,這段代碼演示了如何使用原型模式創(chuàng)建和管理對(duì)象的實(shí)例,以及如何在創(chuàng)建新對(duì)象時(shí)進(jìn)行自定義屬性更新。
7. 建造者模式(Builder Pattern)
建造者模式用于創(chuàng)建復(fù)雜對(duì)象,它將對(duì)象的構(gòu)建過程與其表示分離,從而可以按照不同的方式構(gòu)建對(duì)象。
class Computer:
def __init__(self, cpu, memory, storage):
self.cpu = cpu
self.memory = memory
self.storage = storage
class ComputerBuilder:
def __init__(self):
self._computer = Computer("", "", "")
def set_cpu(self, cpu):
self._computer.cpu = cpu
return self
def set_memory(self, memory):
self._computer.memory = memory
return self
def set_storage(self, storage):
self._computer.storage = storage
return self
def build(self):
return self._computer
# 示例
builder = ComputerBuilder()
computer = builder.set_cpu("Intel").set_memory("8GB").set_storage("256GB SSD").build()
8. 命令模式(Command Pattern)
命令模式將請(qǐng)求封裝為對(duì)象,以便可以參數(shù)化其他對(duì)象對(duì)請(qǐng)求的執(zhí)行、將請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可撤銷的操作。
from abc import ABC, abstractmethod
class Command(ABC):
@abstractmethod
def execute(self):
pass
class Light:
def turn_on(self):
print("Light is on")
def turn_off(self):
print("Light is off")
class LightOnCommand(Command):
def __init__(self, light):
self._light = light
def execute(self):
self._light.turn_on()
class LightOffCommand(Command):
def __init__(self, light):
self._light = light
def execute(self):
self._light.turn_off()
class RemoteControl:
def __init__(self):
self._commands = {}
def set_command(self, slot, command):
self._commands[slot] = command
def press_button(self, slot):
if slot in self._commands:
self._commands[slot].execute()
# 示例
light = Light()
light_on = LightOnCommand(light)
light_off = LightOffCommand(light)
remote = RemoteControl()
remote.set_command(1, light_on)
remote.set_command(2, light_off)
remote.press_button(1) # Output: Light is on
remote.press_button(2) # Output: Light is off
這段代碼展示了命令模式(Command Pattern)的實(shí)現(xiàn),用于將請(qǐng)求封裝成對(duì)象,從而使你能夠參數(shù)化客戶端對(duì)象以在不同的請(qǐng)求之間進(jìn)行參數(shù)化?,F(xiàn)在讓我們來解析它:
-
Command 類:
- 是一個(gè)抽象基類 (Abstract Base Class, ABC),其中定義了一個(gè)抽象方法
execute()
,它將在具體命令類中實(shí)現(xiàn)。所有具體命令類都必須實(shí)現(xiàn)這個(gè)方法。
- 是一個(gè)抽象基類 (Abstract Base Class, ABC),其中定義了一個(gè)抽象方法
-
Light 類:
- 定義了一種名為 Light 的簡(jiǎn)單設(shè)備,具有兩種操作:
turn_on()
和turn_off()
。
- 定義了一種名為 Light 的簡(jiǎn)單設(shè)備,具有兩種操作:
-
具體命令類 LightOnCommand 和 LightOffCommand:
- 這兩個(gè)類實(shí)現(xiàn)了 Command 類。它們分別將 Light 對(duì)象作為參數(shù),在
execute()
方法中調(diào)用了 Light 對(duì)象的turn_on()
和turn_off()
方法,實(shí)現(xiàn)了對(duì) Light 設(shè)備的控制。
- 這兩個(gè)類實(shí)現(xiàn)了 Command 類。它們分別將 Light 對(duì)象作為參數(shù),在
-
RemoteControl 類:
- 這是一個(gè)遙控器類,其中包含一個(gè)字典
_commands
,用于存儲(chǔ)命令對(duì)象。 -
set_command()
方法用于將命令對(duì)象與特定的槽位關(guān)聯(lián)起來。 -
press_button()
方法用于按下特定槽位的按鈕,如果有與該槽位關(guān)聯(lián)的命令對(duì)象,則執(zhí)行該命令。
- 這是一個(gè)遙控器類,其中包含一個(gè)字典
-
示例:
- 創(chuàng)建了一個(gè) Light 對(duì)象。
- 創(chuàng)建了兩個(gè)具體命令對(duì)象,分別用于打開和關(guān)閉 Light。
- 創(chuàng)建了一個(gè) RemoteControl 對(duì)象,并將這兩個(gè)具體命令對(duì)象分別與槽位 1 和槽位 2 關(guān)聯(lián)。
- 通過按下不同槽位的按鈕來測(cè)試遙控器。按下槽位 1 會(huì)打印 “Light is on”,按下槽位 2 會(huì)打印 “Light is off”。
這段代碼演示了如何使用命令模式來實(shí)現(xiàn)一個(gè)簡(jiǎn)單的遙控器系統(tǒng),其中遙控器的按鈕與具體的操作(命令)相關(guān)聯(lián),從而實(shí)現(xiàn)了解耦和可擴(kuò)展性。
9. 狀態(tài)模式(State Pattern)
狀態(tài)模式允許對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變其行為,使對(duì)象看起來好像修改了其類。
from abc import ABC, abstractmethod
class State(ABC):
@abstractmethod
def handle(self):
pass
class StateContext:
def __init__(self, state):
self._state = state
def set_state(self, state):
self._state = state
def request(self):
self._state.handle()
class ConcreteStateA(State):
def handle(self):
print("Handling request in State A")
# State A transitions to State B
context.set_state(ConcreteStateB())
class ConcreteStateB(State):
def handle(self):
print("Handling request in State B")
# State B transitions to State A
context.set_state(ConcreteStateA())
# 示例
context = StateContext(ConcreteStateA())
context.request() # Output: Handling request in State A
context.request() # Output: Handling request in State B
10. 中介者模式(Mediator Pattern)
中介者模式用于減少對(duì)象之間的直接依賴關(guān)系,通過引入中介者對(duì)象來集中控制對(duì)象之間的交互。
class Mediator:
def __init__(self):
self._colleagues = []
def add_colleague(self, colleague):
self._colleagues.append(colleague)
def send_message(self, message, colleague):
for col in self._colleagues:
if col != colleague:
col.receive_message(message)
class Colleague:
def __init__(self, mediator):
self._mediator = mediator
def send_message(self, message):
self._mediator.send_message(message, self)
def receive_message(self, message):
print(f"Received message: {message}")
# 示例
mediator = Mediator()
colleague1 = Colleague(mediator)
colleague2 = Colleague(mediator)
mediator.add_colleague(colleague1)
mediator.add_colleague(colleague2)
colleague1.send_message("Hello from colleague 1")
colleague2.send_message("Hi from colleague 2")
# Output:
# Received message: Hello from colleague 1
# Received message: Hi from colleague 2
這段代碼展示了中介者模式(Mediator Pattern)的實(shí)現(xiàn),該模式用于減少對(duì)象之間的直接通信,而是通過一個(gè)中介對(duì)象來協(xié)調(diào)對(duì)象之間的交互。現(xiàn)在讓我們解析代碼:
-
Mediator 類:
-
__init__
方法初始化了一個(gè)空列表_colleagues
,用于存儲(chǔ)參與通信的同事對(duì)象。 -
add_colleague
方法用于向中介者中添加同事對(duì)象。 -
send_message
方法用于發(fā)送消息給其他同事對(duì)象,它會(huì)遍歷_colleagues
列表,并調(diào)用每個(gè)同事對(duì)象的receive_message
方法,除了消息的發(fā)送者自身。
-
-
Colleague 類:
-
__init__
方法接受一個(gè)中介者對(duì)象作為參數(shù),并將其保存在_mediator
屬性中。 -
send_message
方法用于向中介者發(fā)送消息,它將消息和發(fā)送者自身作為參數(shù)傳遞給中介者的send_message
方法。 -
receive_message
方法用于接收來自中介者的消息,并打印消息內(nèi)容。
-
-
示例:
- 創(chuàng)建了一個(gè) Mediator 對(duì)象。
- 創(chuàng)建了兩個(gè) Colleague 對(duì)象,并將它們注冊(cè)到中介者中。
- 同事對(duì)象通過調(diào)用自己的
send_message
方法來發(fā)送消息給其他同事對(duì)象,實(shí)際上是通過中介者來進(jìn)行通信。 - 兩個(gè)同事對(duì)象收到了對(duì)方發(fā)送的消息,并打印出來。
通過中介者模式,對(duì)象之間的通信被解耦,每個(gè)對(duì)象只需與中介者對(duì)象通信,而不需要直接與其他對(duì)象通信,從而降低了對(duì)象之間的耦合度,提高了系統(tǒng)的可維護(hù)性和擴(kuò)展性。
適配器模式(Adapter Pattern)
適配器模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,用于將一個(gè)類的接口轉(zhuǎn)換成客戶端所期望的另一個(gè)接口。在軟件開發(fā)中,經(jīng)常會(huì)遇到需要使用已有的類,但是其接口與所需接口不匹配的情況。這時(shí)候就可以使用適配器模式來解決這一問題。
例如,假設(shè)有一個(gè)現(xiàn)有的類提供了特定功能,但是其方法命名或參數(shù)形式與新的需求不匹配。為了在不修改原有類的情況下與新的需求兼容,可以創(chuàng)建一個(gè)適配器類,該適配器類將新的需求接口轉(zhuǎn)換為現(xiàn)有類的接口。
適配器模式通常包括三個(gè)角色:
- 目標(biāo)接口(Target):客戶端所期待的接口,適配器會(huì)實(shí)現(xiàn)這個(gè)接口。
- 適配者類(Adaptee):已經(jīng)存在的類,其中包含客戶端希望使用的功能,但其接口與目標(biāo)接口不匹配。
- 適配器類(Adapter):通過實(shí)現(xiàn)目標(biāo)接口并持有適配者對(duì)象,將客戶端的請(qǐng)求轉(zhuǎn)發(fā)給適配者對(duì)象。
適配器模式的優(yōu)點(diǎn)包括:
- 使得客戶端能夠使用已有的類,無需修改原有代碼。
- 提高代碼的復(fù)用性和靈活性,適配器將現(xiàn)有類與新的需求解耦。
然而,適配器模式也有一些缺點(diǎn):
- 增加了系統(tǒng)的復(fù)雜性,引入了額外的類和對(duì)象。
- 過多的適配器可能導(dǎo)致系統(tǒng)難以維護(hù)和理解。
在設(shè)計(jì)和應(yīng)用適配器模式時(shí),需要根據(jù)具體情況權(quán)衡利弊,確保使用適配器的同時(shí)保持代碼的清晰和簡(jiǎn)潔。
外觀模式(Facade Pattern)
外觀模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,旨在為復(fù)雜系統(tǒng)提供一個(gè)簡(jiǎn)化的接口,以便客戶端更容易地使用系統(tǒng)。在軟件開發(fā)中,經(jīng)常會(huì)遇到需要訪問多個(gè)子系統(tǒng)或復(fù)雜接口的情況,這時(shí)候可以使用外觀模式來隱藏系統(tǒng)的復(fù)雜性,提供一個(gè)統(tǒng)一的接口供客戶端使用。
外觀模式通常包括以下角色:
- 外觀類(Facade):為客戶端提供簡(jiǎn)單的接口,隱藏了子系統(tǒng)的復(fù)雜性,負(fù)責(zé)處理客戶端的請(qǐng)求并將其委派給子系統(tǒng)處理。
- 子系統(tǒng)(Subsystem):包含多個(gè)相關(guān)的類或模塊,負(fù)責(zé)實(shí)現(xiàn)系統(tǒng)的各種功能。
外觀模式的優(yōu)點(diǎn)包括:
- 簡(jiǎn)化了客戶端的調(diào)用過程,減少了客戶端與子系統(tǒng)之間的耦合度。
- 提高了代碼的可維護(hù)性和可擴(kuò)展性,客戶端無需了解子系統(tǒng)的內(nèi)部實(shí)現(xiàn)細(xì)節(jié)。
然而,外觀模式也有一些缺點(diǎn):
- 過度使用外觀模式可能導(dǎo)致系統(tǒng)的接口過于臃腫,難以維護(hù)。
- 外觀類成為了系統(tǒng)的唯一入口,一旦外觀類出現(xiàn)問題,整個(gè)系統(tǒng)的功能都將受到影響。
在設(shè)計(jì)和應(yīng)用外觀模式時(shí),需要根據(jù)系統(tǒng)的復(fù)雜性和需求來決定是否使用,以及如何設(shè)計(jì)外觀類的接口,以確保系統(tǒng)的易用性和可維護(hù)性。
總結(jié)
設(shè)計(jì)模式在軟件開發(fā)中起著至關(guān)重要的作用,它們?yōu)殚_發(fā)人員提供了解決常見問題的有效工具和方法。本文介紹了兩種常見的設(shè)計(jì)模式:適配器模式和外觀模式。
適配器模式允許將一個(gè)類的接口轉(zhuǎn)換成客戶端所期望的另一個(gè)接口,從而使得原本不兼容的接口能夠一起工作。通過適配器模式,我們可以在不修改原有類的情況下,使其與新的需求兼容,提高了代碼的復(fù)用性和靈活性。
外觀模式為復(fù)雜系統(tǒng)提供了一個(gè)簡(jiǎn)化的接口,隱藏了系統(tǒng)內(nèi)部的復(fù)雜性,使客戶端能夠更輕松地使用系統(tǒng)。通過外觀模式,我們可以將多個(gè)子系統(tǒng)或復(fù)雜接口封裝起來,提供一個(gè)統(tǒng)一的接口給客戶端,減少了客戶端與子系統(tǒng)之間的耦合度,提高了代碼的可維護(hù)性和可擴(kuò)展性。文章來源:http://www.zghlxwxcb.cn/news/detail-856165.html
綜上所述,設(shè)計(jì)模式是軟件開發(fā)中不可或缺的一部分,它們?yōu)殚_發(fā)人員提供了解決問題的方法和思路,能夠幫助我們編寫更具有可讀性、可維護(hù)性和可擴(kuò)展性的代碼。在實(shí)際項(xiàng)目中,根據(jù)具體需求和場(chǎng)景選擇合適的設(shè)計(jì)模式,并結(jié)合最佳實(shí)踐,將有助于開發(fā)出高質(zhì)量的軟件產(chǎn)品。文章來源地址http://www.zghlxwxcb.cn/news/detail-856165.html
到了這里,關(guān)于Python中的設(shè)計(jì)模式與最佳實(shí)踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!