Фабричный метод (Factory Method) — это порождающий паттерн проектирования, который предоставляет интерфейс для создания объектов в суперклассе, позволяя подклассам изменять тип создаваемых объектов. Этот паттерн используется, когда классу заранее неизвестно, объекты каких классов ему нужно создавать, либо он хочет дать возможность своим подклассам выбирать тип создаваемых объектов.
Паттерн включает в себя следующие компоненты:
from abc import ABC, abstractmethod
# Продукт
class Transport(ABC):
@abstractmethod
def deliver(self) -> str:
pass
# Конкретные продукты
class Truck(Transport):
def deliver(self) -> str:
return "Deliver by land in a box."
class Ship(Transport):
def deliver(self) -> str:
return "Deliver by sea in a container."
# Создатель
class Logistics(ABC):
@abstractmethod
def create_transport(self) -> Transport:
pass
def plan_delivery(self) -> str:
transport = self.create_transport()
return transport.deliver()
# Конкретные создатели
class RoadLogistics(Logistics):
def create_transport(self) -> Transport:
return Truck()
class SeaLogistics(Logistics):
def create_transport(self) -> Transport:
return Ship()
# Использование
def client_code(logistics: Logistics):
print(logistics.plan_delivery())
if __name__ == "__main__":
print("App: Launched with the RoadLogistics.")
client_code(RoadLogistics())
print("\nApp: Launched with the SeaLogistics.")
client_code(SeaLogistics())
Преимущества:
Недостатки:
Паттерн "Фабричный метод" позволяет создавать объекты через интерфейс, делегируя создание конкретных объектов подклассам, что делает код более гибким и расширяемым.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤1
Паттерн "Прототип" (Prototype) — это порождающий паттерн проектирования, который позволяет копировать объекты, не прибегая к их конкретным классам. Он предоставляет механизм для создания новых объектов путем клонирования уже существующих экземпляров-прототипов. Этот паттерн полезен, когда создание объектов требует больших затрат (например, вычислительных или временных), и проще клонировать существующий объект.
Паттерн включает в себя следующие компоненты:
import copy
from abc import ABC, abstractmethod
# Прототип
class Prototype(ABC):
@abstractmethod
def clone(self):
pass
# Конкретный прототип
class ConcretePrototype1(Prototype):
def __init__(self, field):
self.field = field
def clone(self):
return copy.deepcopy(self)
def __str__(self):
return f"ConcretePrototype1 with field: {self.field}"
class ConcretePrototype2(Prototype):
def __init__(self, field):
self.field = field
def clone(self):
return copy.deepcopy(self)
def __str__(self):
return f"ConcretePrototype2 with field: {self.field}"
# Использование
if __name__ == "__main__":
prototype1 = ConcretePrototype1("Value1")
prototype2 = ConcretePrototype2("Value2")
clone1 = prototype1.clone()
clone2 = prototype2.clone()
print(prototype1) # ConcretePrototype1 with field: Value1
print(clone1) # ConcretePrototype1 with field: Value1
print(prototype2) # ConcretePrototype2 with field: Value2
print(clone2) # ConcretePrototype2 with field: Value2
Преимущества:
Недостатки:
Паттерн "Прототип" позволяет быстро и эффективно создавать новые объекты путем клонирования существующих, что упрощает процесс создания сложных объектов и экономит ресурсы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Структурные паттерны (Structural Patterns) — это шаблоны проектирования, которые помогают создавать удобные в поддержке структуры путем установления связей между классами и объектами. Эти паттерны обеспечивают создание гибких и эффективных структур, упрощают проектирование, увеличивают масштабируемость и повторное использование кода.
class OldPrinter:
def print_old(self, text):
print(f"OldPrinter: {text}")
class NewPrinterInterface:
def print(self, text):
pass
class PrinterAdapter(NewPrinterInterface):
def __init__(self, old_printer):
self.old_printer = old_printer
def print(self, text):
self.old_printer.print_old(text)
old_printer = OldPrinter()
adapter = PrinterAdapter(old_printer)
adapter.print("Hello, world!")
class DrawingAPI(ABC):
@abstractmethod
def draw_circle(self, x, y, radius):
pass
class DrawingAPI1(DrawingAPI):
def draw_circle(self, x, y, radius):
print(f"API1.circle at {x}:{y} radius {radius}")
class DrawingAPI2(DrawingAPI):
def draw_circle(self, x, y, radius):
print(f"API2.circle at {x}:{y} radius {radius}")
class Circle:
def __init__(self, x, y, radius, drawing_api):
self.x = x
self.y = y
self.radius = radius
self.drawing_api = drawing_api
def draw(self):
self.drawing_api.draw_circle(self.x, self.y, self.radius)
circle1 = Circle(1, 2, 3, DrawingAPI1())
circle2 = Circle(5, 7, 11, DrawingAPI2())
circle1.draw()
circle2.draw()
class Employee:
def __init__(self, name, position):
self.name = name
self.position = position
self.subordinates = []
def add(self, employee):
self.subordinates.append(employee)
def remove(self, employee):
self.subordinates.remove(employee)
def display(self, indent=0):
print(" " * indent + f"{self.position}: {self.name}")
for subordinate in self.subordinates:
subordinate.display(indent + 2)
ceo = Employee("John", "CEO")
head_sales = Employee("Robert", "Head of Sales")
sales_exec1 = Employee("Laura", "Sales Executive")
sales_exec2 = Employee("Bob", "Sales Executive")
ceo.add(head_sales)
head_sales.add(sales_exec1)
head_sales.add(sales_exec2)
ceo.display()
Структурные паттерны проектирования помогают организовать классы и объекты в крупные структуры, повышая гибкость и расширяемость системы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤2🔥2
Паттерн "Адаптер" (Adapter) — это структурный паттерн проектирования, который позволяет объектам с несовместимыми интерфейсами работать вместе. Он служит посредником, преобразуя интерфейс одного класса в интерфейс, который ожидает клиентский код.
Паттерн включает следующие компоненты:
# Целевой интерфейс (Target)
class PrinterInterface:
def print(self, text):
pass
# Адаптируемый класс (Adaptee)
class OldPrinter:
def print_old(self, text):
print(f"OldPrinter: {text}")
# Адаптер (Adapter)
class PrinterAdapter(PrinterInterface):
def __init__(self, old_printer):
self.old_printer = old_printer
def print(self, text):
self.old_printer.print_old(text)
# Клиентский код
def client_code(printer: PrinterInterface):
printer.print("Hello, world!")
# Использование
old_printer = OldPrinter()
adapter = PrinterAdapter(old_printer)
client_code(adapter)
Преимущества:
Недостатки:
Класс-адаптер:
class OldPrinter:
def print_old(self, text):
print(f"OldPrinter: {text}")
class PrinterAdapter(OldPrinter, PrinterInterface):
def print(self, text):
self.print_old(text)
# Использование
adapter = PrinterAdapter()
client_code(adapter)
Объект-адаптер:
class PrinterAdapter(PrinterInterface):
def __init__(self, old_printer):
self.old_printer = old_printer
def print(self, text):
self.old_printer.print_old(text)
# Использование
old_printer = OldPrinter()
adapter = PrinterAdapter(old_printer)
client_code(adapter)
Паттерн "Адаптер" является мощным инструментом для интеграции старых систем с новыми требованиями, обеспечивая гибкость и повторное использование существующих классов без изменения их исходного кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤2
Паттерн "Мост" (Bridge) — это структурный паттерн проектирования, который разделяет абстракцию и её реализацию так, чтобы они могли изменяться независимо друг от друга. Он используется для разделения сложных систем на части, которые можно развивать, изменять и использовать независимо.
Паттерн включает следующие компоненты:
from abc import ABC, abstractmethod
# Интерфейс реализации
class DrawingAPI(ABC):
@abstractmethod
def draw_circle(self, x, y, radius):
pass
# Конкретные реализации
class DrawingAPI1(DrawingAPI):
def draw_circle(self, x, y, radius):
print(f"API1.circle at {x}:{y} radius {radius}")
class DrawingAPI2(DrawingAPI):
def draw_circle(self, x, y, radius):
print(f"API2.circle at {x}:{y} radius {radius}")
# Абстракция
class Shape(ABC):
def __init__(self, drawing_api):
self.drawing_api = drawing_api
@abstractmethod
def draw(self):
pass
@abstractmethod
def resize(self, factor):
pass
# Расширенная абстракция
class CircleShape(Shape):
def __init__(self, x, y, radius, drawing_api):
super().__init__(drawing_api)
self.x = x
self.y = y
self.radius = radius
def draw(self):
self.drawing_api.draw_circle(self.x, self.y, self.radius)
def resize(self, factor):
self.radius *= factor
# Использование
circle1 = CircleShape(1, 2, 3, DrawingAPI1())
circle2 = CircleShape(5, 7, 11, DrawingAPI2())
circle1.draw()
circle2.draw()
circle1.resize(2)
circle1.draw()
Преимущества:
Недостатки:
Паттерн "Мост" обеспечивает гибкость в проектировании сложных систем, разделяя их на независимые части, что облегчает их развитие и поддержку.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Паттерн "Компоновщик" (Composite) — это структурный паттерн проектирования, который позволяет сгруппировать объекты в древовидные структуры для представления иерархий "часть-целое". Этот паттерн позволяет клиенту одинаково работать как с отдельными объектами, так и с группами объектов.
Паттерн включает следующие компоненты:
from abc import ABC, abstractmethod
# Компонент
class Employee(ABC):
@abstractmethod
def show_details(self):
pass
# Лист
class Developer(Employee):
def __init__(self, name, position):
self.name = name
self.position = position
def show_details(self):
print(f"{self.position}: {self.name}")
class Designer(Employee):
def __init__(self, name, position):
self.name = name
self.position = position
def show_details(self):
print(f"{self.position}: {self.name}")
# Контейнер
class Organization(Employee):
def __init__(self):
self.employees = []
def add(self, employee):
self.employees.append(employee)
def remove(self, employee):
self.employees.remove(employee)
def show_details(self):
for employee in self.employees:
employee.show_details()
# Использование
dev1 = Developer("John Doe", "Senior Developer")
dev2 = Developer("Jane Smith", "Junior Developer")
designer = Designer("Emily Davis", "Senior Designer")
org = Organization()
org.add(dev1)
org.add(dev2)
org.add(designer)
org.show_details()
Преимущества:
Недостатки:
Паттерн "Компоновщик" является мощным инструментом для работы с древовидными структурами данных, позволяя легко манипулировать и управлять как отдельными объектами, так и их группами.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Паттерн "Фасад" (Facade) — это структурный паттерн проектирования, который предоставляет унифицированный интерфейс для взаимодействия с набором интерфейсов в подсистеме. Фасад определяет высокоуровневый интерфейс, упрощающий работу с более сложной подсистемой.
Паттерн включает следующие компоненты:
class Amplifier:
def on(self):
print("Amplifier on")
def set_volume(self, volume):
print(f"Amplifier volume set to {volume}")
def off(self):
print("Amplifier off")
class DVDPlayer:
def on(self):
print("DVD Player on")
def play(self, movie):
print(f"Playing movie: {movie}")
def stop(self):
print("DVD Player stopped")
def off(self):
print("DVD Player off")
class Projector:
def on(self):
print("Projector on")
def set_input(self, input):
print(f"Projector input set to {input}")
def off(self):
print("Projector off")
# Фасад
class HomeTheaterFacade:
def __init__(self, amp, dvd, projector):
self.amp = amp
self.dvd = dvd
self.projector = projector
def watch_movie(self, movie):
print("Get ready to watch a movie...")
self.amp.on()
self.amp.set_volume(5)
self.dvd.on()
self.dvd.play(movie)
self.projector.on()
self.projector.set_input("DVD")
def end_movie(self):
print("Shutting movie theater down...")
self.amp.off()
self.dvd.stop()
self.dvd.off()
self.projector.off()
# Использование
amp = Amplifier()
dvd = DVDPlayer()
projector = Projector()
home_theater = HomeTheaterFacade(amp, dvd, projector)
home_theater.watch_movie("Inception")
home_theater.end_movie()
Преимущества:
Недостатки:
Паттерн "Фасад" является полезным инструментом для упрощения взаимодействия с сложными подсистемами, скрывая их внутреннюю сложность и предоставляя удобный интерфейс для клиентов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Паттерн "Приспособленец" (Flyweight) — это структурный паттерн проектирования, который позволяет эффективно поддерживать большое количество мелких объектов, минимизируя использование памяти. Это достигается путем совместного использования общего состояния объектов, вместо хранения одинаковых данных в каждом объекте.
Паттерн "Приспособленец" разделяет состояние объекта на:
class Flyweight:
def __init__(self, intrinsic_state):
self.intrinsic_state = intrinsic_state
def operation(self, extrinsic_state):
print(f"Flyweight: Intrinsic state = {self.intrinsic_state}, Extrinsic state = {extrinsic_state}")
class FlyweightFactory:
_flyweights = {}
def get_flyweight(self, intrinsic_state):
if intrinsic_state not in self._flyweights:
self._flyweights[intrinsic_state] = Flyweight(intrinsic_state)
return self._flyweights[intrinsic_state]
# Клиентский код
factory = FlyweightFactory()
# Создание и использование приспособленцев
flyweight1 = factory.get_flyweight("Shared State A")
flyweight1.operation("Unique State 1")
flyweight2 = factory.get_flyweight("Shared State B")
flyweight2.operation("Unique State 2")
flyweight3 = factory.get_flyweight("Shared State A")
flyweight3.operation("Unique State 3")
# Проверка совместного использования приспособленцев
print(flyweight1 is flyweight3) # True
Преимущества:
производительности: Снижение затрат на создание и хранение объектов может улучшить общую производительность системы.
Недостатки:
Паттерн "Приспособленец" является мощным инструментом для оптимизации использования памяти и повышения производительности в системах, работающих с большим количеством однотипных объектов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Anonymous Quiz
14%
Класс, который наследует другие классы
17%
Класс, который не может быть инстанциирован
60%
Класс, из которого создаются другие классы
10%
Класс, который используется для работы с базами данных
🎉3
Паттерн "Заместитель" (Proxy) — это структурный паттерн проектирования, который предоставляет суррогатный или заместительный объект для другого объекта с целью контроля доступа к нему. Заместитель выполняет функции обёртки или посредника, передавая вызовы к реальному объекту и добавляя к ним дополнительную логику.
Паттерн "Заместитель" включает следующие компоненты:
from abc import ABC, abstractmethod
# Интерфейс (Subject)
class Subject(ABC):
@abstractmethod
def request(self):
pass
# Реальный субъект (RealSubject)
class RealSubject(Subject):
def request(self):
print("RealSubject: Handling request.")
# Заместитель (Proxy)
class Proxy(Subject):
def __init__(self, real_subject):
self._real_subject = real_subject
def request(self):
if self.check_access():
self._real_subject.request()
self.log_access()
def check_access(self):
print("Proxy: Checking access prior to firing a real request.")
return True
def log_access(self):
print("Proxy: Logging the time of request.")
# Клиентский код
def client_code(subject: Subject):
subject.request()
# Использование
real_subject = RealSubject()
proxy = Proxy(real_subject)
client_code(proxy)
Преимущества:
Недостатки:
Паттерн "Заместитель" является мощным инструментом для управления доступом к объектам, добавления логики и улучшения производительности в определённых сценариях.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1
Поведенческие паттерны (Behavioral Patterns) — это шаблоны проектирования, которые определяют способы взаимодействия объектов и классов, эффективное распределение обязанностей между ними и упрощают коммуникацию. Эти паттерны фокусируются на алгоритмах и потоках управления в системе, обеспечивая гибкость и расширяемость программного кода.
class Handler(ABC):
def __init__(self, successor=None):
self._successor = successor
@abstractmethod
def handle(self, request):
pass
class ConcreteHandler1(Handler):
def handle(self, request):
if request == "Condition1":
print("Handled by ConcreteHandler1")
elif self._successor:
self._successor.handle(request)
class ConcreteHandler2(Handler):
def handle(self, request):
if request == "Condition2":
print("Handled by ConcreteHandler2")
elif self._successor:
self._successor.handle(request)
# Использование
handler = ConcreteHandler1(ConcreteHandler2())
handler.handle("Condition2")
class Command(ABC):
@abstractmethod
def execute(self):
pass
class Light:
def on(self):
print("Light is ON")
def off(self):
print("Light is OFF")
class LightOnCommand(Command):
def __init__(self, light):
self._light = light
def execute(self):
self._light.on()
class LightOffCommand(Command):
def __init__(self, light):
self._light = light
def execute(self):
self._light.off()
# Использование
light = Light()
light_on = LightOnCommand(light)
light_off = LightOffCommand(light)
light_on.execute()
light_off.execute()
class Iterator(ABC):
@abstractmethod
def next(self):
pass
@abstractmethod
def has_next(self):
pass
class ConcreteIterator(Iterator):
def __init__(self, collection):
self._collection = collection
self._index = 0
def next(self):
item = self._collection[self._index]
self._index += 1
return item
def has_next(self):
return self._index < len(self._collection)
# Использование
collection = [1, 2, 3, 4]
iterator = ConcreteIterator(collection)
while iterator.has_next():
print(iterator.next())
Поведенческие паттерны проектирования определяют способы взаимодействия объектов и классов, упрощая коммуникацию и обеспечивая гибкость и расширяемость программного кода. Они позволяют эффективно распределять обязанности между объектами и обеспечивать упорядоченный поток управления в системе.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Цепочка ответственности (Chain of Responsibility) — это поведенческий паттерн проектирования, который позволяет передавать запросы последовательно по цепочке обработчиков. Каждый обработчик решает, может ли он обработать запрос самостоятельно, либо передает его следующему обработчику в цепочке.
Паттерн включает следующие компоненты:
from abc import ABC, abstractmethod
# Абстрактный обработчик
class Handler(ABC):
def __init__(self, successor=None):
self._successor = successor
@abstractmethod
def handle(self, request):
pass
# Конкретный обработчик 1
class ConcreteHandler1(Handler):
def handle(self, request):
if request == "Condition1":
print("Handled by ConcreteHandler1")
elif self._successor:
self._successor.handle(request)
# Конкретный обработчик 2
class ConcreteHandler2(Handler):
def handle(self, request):
if request == "Condition2":
print("Handled by ConcreteHandler2")
elif self._successor:
self._successor.handle(request)
# Клиентский код
def client_code(handler, request):
handler.handle(request)
# Создание цепочки обработчиков
handler1 = ConcreteHandler1()
handler2 = ConcreteHandler2(handler1)
# Использование
client_code(handler2, "Condition1") # Handled by ConcreteHandler1
client_code(handler2, "Condition2") # Handled by ConcreteHandler2
client_code(handler2, "Condition3") # Ничего не происходит, так как запрос не обработан
Паттерн "Цепочка ответственности" является мощным инструментом для гибкого и динамичного распределения обязанностей по обработке запросов в системе.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤1
Anonymous Quiz
30%
asyncio
20%
multiprocessing
49%
threading
2%
concurrent
Паттерн "Команда" (Command) — это поведенческий паттерн проектирования, который превращает запросы в объекты, позволяя передавать их как аргументы при вызове методов, ставить запросы в очередь, логировать их и поддерживать отмену операций.
Паттерн включает следующие компоненты:
execute
.from abc import ABC, abstractmethod
# Интерфейс команды
class Command(ABC):
@abstractmethod
def execute(self):
pass
# Получатель
class Light:
def on(self):
print("Light is ON")
def off(self):
print("Light is OFF")
# Конкретная команда включения света
class LightOnCommand(Command):
def __init__(self, light):
self._light = light
def execute(self):
self._light.on()
# Конкретная команда выключения света
class LightOffCommand(Command):
def __init__(self, light):
self._light = light
def execute(self):
self._light.off()
# Отправитель
class RemoteControl:
def __init__(self):
self._commands = {}
def set_command(self, button, command):
self._commands[button] = command
def press_button(self, button):
if button in self._commands:
self._commands[button].execute()
else:
print("No command assigned to this button")
# Клиентский код
light = Light()
light_on = LightOnCommand(light)
light_off = LightOffCommand(light)
remote = RemoteControl()
remote.set_command("ON", light_on)
remote.set_command("OFF", light_off)
remote.press_button("ON") # Light is ON
remote.press_button("OFF") # Light is OFF
remote.press_button("UNASSIGNED") # No command assigned to this button
Паттерн "Команда" является мощным инструментом для управления действиями и их инкапсуляции, обеспечивая гибкость и расширяемость системы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3👀1
Паттерн "Интерпретатор" (Interpreter) — это поведенческий паттерн проектирования, который предоставляет способ определить грамматику для определенного языка и интерпретировать предложения на этом языке. Паттерн используется для анализа и выполнения структурированных текстов, таких как математические выражения, команды или сценарии.
Паттерн включает следующие компоненты:
from abc import ABC, abstractmethod
# Контекст (необязательный компонент)
class Context:
pass
# Абстрактное выражение
class Expression(ABC):
@abstractmethod
def interpret(self, context):
pass
# Терминальное выражение (число)
class Number(Expression):
def __init__(self, value):
self.value = value
def interpret(self, context):
return self.value
# Нетерминальное выражение (сложение)
class Add(Expression):
def __init__(self, left, right):
self.left = left
self.right = right
def interpret(self, context):
return self.left.interpret(context) + self.right.interpret(context)
# Нетерминальное выражение (вычитание)
class Subtract(Expression):
def __init__(self, left, right):
self.left = left
self.right = right
def interpret(self, context):
return self.left.interpret(context) - self.right.interpret(context)
# Клиентский код
def main():
# Построение выражения: 1 + 2 - 3
expression = Subtract(Add(Number(1), Number(2)), Number(3))
context = Context() # Контекст может использоваться для передачи информации
result = expression.interpret(context)
print(result) # 0
if __name__ == "__main__":
main()
Паттерн "Интерпретатор" является мощным инструментом для определения и интерпретации грамматик, позволяя легко анализировать и выполнять структурированные тексты.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🤔3
Паттерн "Посредник" (Mediator) — это поведенческий паттерн проектирования, который позволяет уменьшить зависимости между объектами, упрощая их взаимодействие. Посредник инкапсулирует способ взаимодействия множества объектов, предотвращая их прямые ссылки друг на друга, что уменьшает связность системы и улучшает её модульность.
Паттерн включает следующие компоненты:
from abc import ABC, abstractmethod
# Посредник
class Mediator(ABC):
@abstractmethod
def notify(self, sender, event):
pass
# Конкретный посредник
class ConcreteMediator(Mediator):
def __init__(self):
self.button = None
self.textbox = None
def set_button(self, button):
self.button = button
def set_textbox(self, textbox):
self.textbox = textbox
def notify(self, sender, event):
if event == "button_clicked":
self.textbox.enable()
elif event == "textbox_filled":
self.button.enable()
# Коллеги
class Button:
def __init__(self, mediator):
self.mediator = mediator
self.enabled = False
def click(self):
print("Button clicked.")
self.mediator.notify(self, "button_clicked")
def enable(self):
self.enabled = True
print("Button enabled.")
class TextBox:
def __init__(self, mediator):
self.mediator = mediator
self.enabled = False
def fill(self):
print("TextBox filled.")
self.mediator.notify(self, "textbox_filled")
def enable(self):
self.enabled = True
print("TextBox enabled.")
# Клиентский код
mediator = ConcreteMediator()
button = Button(mediator)
textbox = TextBox(mediator)
mediator.set_button(button)
mediator.set_textbox(textbox)
button.click() # Button clicked. TextBox enabled.
textbox.fill() # TextBox filled. Button enabled.
Паттерн "Посредник" является мощным инструментом для управления взаимодействиями в системе, улучшая её модульность и уменьшая сложность.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥2
Паттерн "Хранитель" (Memento) — это поведенческий паттерн проектирования, который позволяет сохранять и восстанавливать состояние объекта, не раскрывая его внутреннюю структуру. Это полезно для реализации функций отмены операций, восстановления предыдущих состояний и создания контрольных точек.
Паттерн включает следующие компоненты:
# Хранитель
class Memento:
def __init__(self, state):
self._state = state
def get_state(self):
return self._state
# Создатель
class TextEditor:
def __init__(self):
self._state = ""
def type(self, text):
self._state += text
def save(self):
return Memento(self._state)
def restore(self, memento):
self._state = memento.get_state()
def get_state(self):
return self._state
# Опекун
class History:
def __init__(self):
self._mementos = []
def save(self, memento):
self._mementos.append(memento)
def undo(self):
if not self._mementos:
return None
return self._mementos.pop()
# Клиентский код
editor = TextEditor()
history = History()
# Пользователь вводит текст
editor.type("Hello, ")
editor.type("world!")
print(editor.get_state()) # Hello, world!
# Сохранение состояния
history.save(editor.save())
# Продолжение ввода текста
editor.type(" How are you?")
print(editor.get_state()) # Hello, world! How are you?
# Восстановление состояния
editor.restore(history.undo())
print(editor.get_state()) # Hello, world!
Паттерн "Хранитель" является мощным инструментом для управления состоянием объектов, предоставляя возможность сохранять и восстанавливать состояния без раскрытия внутренней структуры объекта.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥1
Паттерн "Наблюдатель" (Observer) — это поведенческий паттерн проектирования, который определяет зависимость "один ко многим" между объектами. Когда состояние одного объекта изменяется, все его зависимые объекты автоматически оповещаются и обновляются. Этот паттерн позволяет объектам подписываться на события, происходящие в другом объекте.
Паттерн включает следующие компоненты:
from abc import ABC, abstractmethod
# Интерфейс наблюдателя
class Observer(ABC):
@abstractmethod
def update(self, temperature):
pass
# Конкретный наблюдатель
class TemperatureDisplay(Observer):
def update(self, temperature):
print(f"Temperature Display: Temperature updated to {temperature}°C")
class TemperatureAlert(Observer):
def update(self, temperature):
if temperature > 30:
print("Temperature Alert: Temperature is too high!")
# Субъект
class WeatherStation:
def __init__(self):
self._observers = []
self._temperature = None
def add_observer(self, observer):
self._observers.append(observer)
def remove_observer(self, observer):
self._observers.remove(observer)
def set_temperature(self, temperature):
self._temperature = temperature
self.notify_observers()
def notify_observers(self):
for observer in self._observers:
observer.update(self._temperature)
# Клиентский код
weather_station = WeatherStation()
display = TemperatureDisplay()
alert = TemperatureAlert()
weather_station.add_observer(display)
weather_station.add_observer(alert)
weather_station.set_temperature(25) # Temperature Display: Temperature updated to 25°C
weather_station.set_temperature(35) # Temperature Display: Temperature updated to 35°C
# Temperature Alert: Temperature is too high!
Паттерн "Наблюдатель" является мощным инструментом для управления зависимостями и оповещением в системе, упрощая взаимодействие между объектами и улучшая модульность кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1
Паттерн "Состояние" (State) — это поведенческий паттерн проектирования, который позволяет объекту изменять свое поведение в зависимости от его внутреннего состояния. Внешне это выглядит так, как будто объект изменил свой класс. Этот паттерн особенно полезен, когда объект может находиться в нескольких состояниях, каждое из которых определяет его поведение.
Паттерн включает следующие компоненты:
from abc import ABC, abstractmethod
# Интерфейс состояния
class State(ABC):
@abstractmethod
def insert_coin(self, context):
pass
@abstractmethod
def press_button(self, context):
pass
@abstractmethod
def dispense(self, context):
pass
# Конкретные состояния
class NoCoinState(State):
def insert_coin(self, context):
print("Coin inserted.")
context.state = context.has_coin_state
def press_button(self, context):
print("Insert coin first.")
def dispense(self, context):
print("Insert coin first.")
class HasCoinState(State):
def insert_coin(self, context):
print("Coin already inserted.")
def press_button(self, context):
print("Button pressed.")
context.state = context.sold_state
def dispense(self, context):
print("Press button to dispense.")
class SoldState(State):
def insert_coin(self, context):
print("Wait! Dispensing in progress.")
def press_button(self, context):
print("Wait! Dispensing in progress.")
def dispense(self, context):
print("Ticket dispensed.")
context.state = context.no_coin_state
# Контекст
class TicketMachine:
def __init__(self):
self.no_coin_state = NoCoinState()
self.has_coin_state = HasCoinState()
self.sold_state = SoldState()
self.state = self.no_coin_state
def insert_coin(self):
self.state.insert_coin(self)
def press_button(self):
self.state.press_button(self)
def dispense(self):
self.state.dispense(self)
# Клиентский код
machine = TicketMachine()
machine.insert_coin() # Coin inserted.
machine.press_button() # Button pressed.
machine.dispense() # Ticket dispensed.
machine.press_button() # Insert coin first.
machine.insert_coin() # Coin inserted.
machine.dispense() # Press button to dispense.
machine.press_button() # Button pressed.
machine.dispense() # Ticket dispensed.
расходы: Частые изменения состояния могут привести к дополнительным накладным расходам.
Паттерн "Состояние" является мощным инструментом для управления состояниями объекта и изменением его поведения в зависимости от этих состояний, что упрощает код и улучшает его структуру.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍1👀1
Паттерн "Стратегия" (Strategy) — это поведенческий паттерн проектирования, который определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Паттерн "Стратегия" позволяет изменять алгоритмы независимо от клиентов, которые их используют.
Паттерн включает следующие компоненты:
from abc import ABC, abstractmethod
# Интерфейс стратегии
class Strategy(ABC):
@abstractmethod
def sort(self, data):
pass
# Конкретные стратегии
class BubbleSortStrategy(Strategy):
def sort(self, data):
print("Sorting using Bubble Sort")
for i in range(len(data)):
for j in range(0, len(data)-i-1):
if data[j] > data[j+1]:
data[j], data[j+1] = data[j+1], data[j]
class QuickSortStrategy(Strategy):
def sort(self, data):
print("Sorting using Quick Sort")
self.quick_sort(data, 0, len(data) - 1)
def quick_sort(self, data, low, high):
if low < high:
pi = self.partition(data, low, high)
self.quick_sort(data, low, pi - 1)
self.quick_sort(data, pi + 1, high)
def partition(self, data, low, high):
pivot = data[high]
i = low - 1
for j in range(low, high):
if data[j] <= pivot:
i = i + 1
data[i], data[j] = data[j], data[i]
data[i + 1], data[high] = data[high], data[i + 1]
return i + 1
# Контекст
class SortingContext:
def __init__(self, strategy: Strategy):
self._strategy = strategy
def set_strategy(self, strategy: Strategy):
self._strategy = strategy
def sort(self, data):
self._strategy.sort(data)
# Клиентский код
data = [5, 2, 9, 1, 5, 6]
context = SortingContext(BubbleSortStrategy())
context.sort(data)
print(data) # [1, 2, 5, 5, 6, 9]
context.set_strategy(QuickSortStrategy())
data = [3, 7, 8, 5, 2, 1, 9, 5, 4]
context.sort(data)
print(data) # [1, 2, 3, 4, 5, 5, 7, 8, 9]
Недостатки:
Паттерн "Стратегия" является мощным инструментом для управления алгоритмами и их выбора в зависимости от конкретной ситуации, улучшая гибкость и расширяемость кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1🤔1👾1