Кодовые метрики когезии (cohesion) и связи (coupling) играют ключевую роль в проектировании программного обеспечения. Давайте разберем их более подробно.
Когезия (Cohesion)
Это мера того, насколько сильно элементы внутри модуля связаны друг с другом. Высокая когезия означает, что элементы модуля работают вместе для выполнения одной задачи.
class Utility:
def calculate_tax(self, amount):
# Код для расчета налога
pass
def send_email(self, email, message):
# Код для отправки email
pass
def generate_report(self, data):
# Код для генерации отчета
pass
Этот класс выполняет несколько несвязанных задач, что снижает когезию.
class TaxCalculator:
def calculate_tax(self, amount):
# Код для расчета налога
pass
class EmailSender:
def send_email(self, email, message):
# Код для отправки email
pass
class ReportGenerator:
def generate_report(self, data):
# Код для генерации отчета
pass
Каждый класс выполняет одну четко определенную задачу, что повышает когезию.
Связь (Coupling)
Это мера зависимости между модулями. Низкая связь означает, что изменения в одном модуле минимально влияют на другие модули.
class OrderProcessor:
def __init__(self):
self.tax_calculator = TaxCalculator()
self.email_sender = EmailSender()
def process_order(self, order):
tax = self.tax_calculator.calculate_tax(order.amount)
self.email_sender.send_email(order.customer_email, "Order processed")
OrderProcessor сильно зависит от TaxCalculator и EmailSender.
class OrderProcessor:
def __init__(self, tax_calculator, email_sender):
self.tax_calculator = tax_calculator
self.email_sender = email_sender
def process_order(self, order):
tax = self.tax_calculator.calculate_tax(order.amount)
self.email_sender.send_email(order.customer_email, "Order processed")
В этом примере зависимости инъектируются через конструктор, что уменьшает связь между модулями и позволяет их легче тестировать и заменять.
Когезия делает модули логичными и понятными, а низкая связь позволяет модулям работать независимо друг от друга.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥2❤1
Anonymous Quiz
36%
None
17%
undefined
6%
null
41%
невозможно использовать неинициализированные переменные
Порождающий паттерн (creational pattern) — это тип шаблонов проектирования, который предоставляет различные способы создания объектов, помогая отделить логику создания объектов от их основного использования. Порождающие паттерны помогают сделать систему более гибкой и независимой от конкретных классов, которые она использует.
Гарантирует, что у класса есть только один экземпляр, и предоставляет глобальную точку доступа к этому экземпляру.
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
# Использование
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # True
Определяет интерфейс для создания объектов, но позволяет подклассам изменять тип создаваемых объектов.
from abc import ABC, abstractmethod
class Product(ABC):
@abstractmethod
def operation(self):
pass
class ConcreteProductA(Product):
def operation(self):
return "Result of ConcreteProductA"
class ConcreteProductB(Product):
def operation(self):
return "Result of ConcreteProductB"
class Creator(ABC):
@abstractmethod
def factory_method(self):
pass
def some_operation(self):
product = self.factory_method()
return f"Creator: The same creator's code has just worked with {product.operation()}"
class ConcreteCreatorA(Creator):
def factory_method(self):
return ConcreteProductA()
class ConcreteCreatorB(Creator):
def factory_method(self):
return ConcreteProductB()
# Использование
creator = ConcreteCreatorA()
print(creator.some_operation())
creator = ConcreteCreatorB()
print(creator.some_operation())
Порождающие паттерны проектирования помогают создавать объекты в системе, абстрагируя логику их создания. Они делают код более гибким и независимым от конкретных классов, упрощая поддержку и расширение системы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤1🎉1
Anonymous Quiz
24%
xml.dom
10%
xml.sax
33%
xml.etree.ElementTree
33%
re
👾5❤1
Forwarded from Идущий к IT
10$ за техническое собеседование на английском языке:
1. Отправьте запись технического собеседования на английском языке файлом на этот аккаунт
2. Добавьте ссылку на вакансию или пришлите название компании и должность
3. Напишите номер кошелка USDT (Tether) на который отправить 10$
🛡 Важно:
– Запись будет использована только для сбора данных о вопросах
– Вы останетесь анонимны
– Запись нигде не будет опубликована
🤝 Условия:
– Внятный звук, различимая речь
– Допустимые профессии:
• Любые программисты
• DevOps
• Тестировщики
• Дата сайнтисты
• Бизнес/Системные аналитики
• Прожекты/Продукты
• UX/UI и продукт дизайнеры
1. Отправьте запись технического собеседования на английском языке файлом на этот аккаунт
2. Добавьте ссылку на вакансию или пришлите название компании и должность
3. Напишите номер кошелка USDT (Tether) на который отправить 10$
– Запись будет использована только для сбора данных о вопросах
– Вы останетесь анонимны
– Запись нигде не будет опубликована
– Внятный звук, различимая речь
– Допустимые профессии:
• Любые программисты
• DevOps
• Тестировщики
• Дата сайнтисты
• Бизнес/Системные аналитики
• Прожекты/Продукты
• UX/UI и продукт дизайнеры
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔4👀1
Абстрактная фабрика (Abstract Factory) — это порождающий паттерн проектирования, который предоставляет интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов. Этот паттерн используется, когда система должна быть независимой от способа создания, композиции и представления своих продуктов.
Определяет интерфейсы для создания абстрактных продуктов. Конкретные фабрики реализуют эти интерфейсы, создавая конкретные продукты.
Рассмотрим пример абстрактной фабрики для создания семейств продуктов
Chair
и Sofa
для разных стилей мебели (Modern и Victorian).from abc import ABC, abstractmethod
# Абстрактные продукты
class Chair(ABC):
@abstractmethod
def sit_on(self) -> str:
pass
class Sofa(ABC):
@abstractmethod
def lie_on(self) -> str:
pass
# Конкретные продукты
class ModernChair(Chair):
def sit_on(self) -> str:
return "Sitting on a modern chair."
class VictorianChair(Chair):
def sit_on(self) -> str:
return "Sitting on a Victorian chair."
class ModernSofa(Sofa):
def lie_on(self) -> str:
return "Lying on a modern sofa."
class VictorianSofa(Sofa):
def lie_on(self) -> str:
return "Lying on a Victorian sofa."
# Абстрактная фабрика
class FurnitureFactory(ABC):
@abstractmethod
def create_chair(self) -> Chair:
pass
@abstractmethod
def create_sofa(self) -> Sofa:
pass
# Конкретные фабрики
class ModernFurnitureFactory(FurnitureFactory):
def create_chair(self) -> Chair:
return ModernChair()
def create_sofa(self) -> Sofa:
return ModernSofa()
class VictorianFurnitureFactory(FurnitureFactory):
def create_chair(self) -> Chair:
return VictorianChair()
def create_sofa(self) -> Sofa:
return VictorianSofa()
# Клиентский код
def client_code(factory: FurnitureFactory):
chair = factory.create_chair()
sofa = factory.create_sofa()
print(chair.sit_on())
print(sofa.lie_on())
# Использование
if __name__ == "__main__":
print("Modern furniture:")
client_code(ModernFurnitureFactory())
print("\nVictorian furniture:")
client_code(VictorianFurnitureFactory())
Преимущества:
Недостатки:
Абстрактная фабрика помогает создавать семейств продуктов, делая код более гибким и расширяемым.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3
Паттерн "Построитель" (Builder) — это порождающий паттерн проектирования, который позволяет создавать сложные объекты поэтапно. В отличие от других порождающих паттернов, Builder предоставляет возможность постепенно конструировать объект, контролируя процесс его создания на каждом этапе. Этот паттерн особенно полезен, когда нужно создать объект с различными конфигурациями или когда создание объекта требует много шагов.
Паттерн состоит из следующих компонентов:
from abc import ABC, abstractmethod
# Продукт
class Car:
def __init__(self):
self.parts = []
def add_part(self, part):
self.parts.append(part)
def list_parts(self):
return ", ".join(self.parts)
# Интерфейс Построителя
class CarBuilder(ABC):
@abstractmethod
def produce_engine(self):
pass
@abstractmethod
def produce_wheels(self):
pass
@abstractmethod
def produce_body(self):
pass
# Конкретный Построитель
class SportsCarBuilder(CarBuilder):
def __init__(self):
self.car = Car()
def produce_engine(self):
self.car.add_part("Sport Engine")
def produce_wheels(self):
self.car.add_part("Sport Wheels")
def produce_body(self):
self.car.add_part("Sport Body")
def get_car(self):
return self.car
# Директор
class Director:
def __init__(self, builder: CarBuilder):
self._builder = builder
def construct_sports_car(self):
self._builder.produce_engine()
self._builder.produce_wheels()
self._builder.produce_body()
# Использование
if __name__ == "__main__":
builder = SportsCarBuilder()
director = Director(builder)
director.construct_sports_car()
car = builder.get_car()
print(f"Car parts: {car.list_parts()}")
Преимущества:
Недостатки:
Паттерн "Построитель" помогает управлять сложностью создания объектов и позволяет создавать различные их представления, делая код более гибким и поддерживаемым.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🤔3❤2
Паттерн Заместитель (Proxy) — это структурный шаблон проектирования, который предоставляет объект, управляющий доступом к другому объекту. Этот паттерн создаёт суррогат или заместителя для другого объекта и контролирует доступ к нему.
Паттерн Заместитель используется в следующих случаях:
Заместитель реализует интерфейс основного объекта и перенаправляет вызовы к реальному объекту, добавляя при этом дополнительную функциональность.
Рассмотрим пример с удалённым заместителем, который управляет доступом к удалённому серверу.
from abc import ABC, abstractmethod
class Subject(ABC):
@abstractmethod
def request(self):
pass
class RealSubject(Subject):
def request(self):
print("Реальный объект: Обработка запроса.")
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("Заместитель: Проверка доступа перед выполнением запроса.")
return True
def log_access(self):
print("Заместитель: Логирование времени запроса.")
# Клиентский код
real_subject = RealSubject()
proxy = Proxy(real_subject)
proxy.request()
В этом примере класс
Proxy
контролирует доступ к классу RealSubject
, добавляя проверку доступа и логирование.Паттерн Заместитель управляет доступом к другому объекту, предоставляя дополнительные возможности, такие как контроль доступа, отложенная инициализация, управление ресурсами, логирование и кэширование.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥3❤1
Фабричный метод (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