From ca095408cf4aa8255e1131dfd9475a22e881c829 Mon Sep 17 00:00:00 2001 From: serr Date: Fri, 7 Feb 2025 12:10:20 +0300 Subject: [PATCH] new --- adapter.py | 28 ++++++++++++ bridge.py | 37 ++++++++++++++++ builder.py | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++ chain.py | 32 ++++++++++++++ command.py | 37 ++++++++++++++++ composite.py | 54 +++++++++++++++++++++++ decorator.py | 40 +++++++++++++++++ flyweight.py | 34 ++++++++++++++ iterator.py | 28 ++++++++++++ mediator.py | 48 ++++++++++++++++++++ memento.py | 39 ++++++++++++++++ proxy.py | 25 +++++++++++ singleton.py | 22 ++++++++++ state.py | 81 ++++++++++++++++++++++++++++++++++ visitor.py | 34 ++++++++++++++ 15 files changed, 661 insertions(+) create mode 100644 adapter.py create mode 100644 bridge.py create mode 100644 builder.py create mode 100644 chain.py create mode 100644 command.py create mode 100644 composite.py create mode 100644 decorator.py create mode 100644 flyweight.py create mode 100644 iterator.py create mode 100644 mediator.py create mode 100644 memento.py create mode 100644 proxy.py create mode 100644 singleton.py create mode 100644 state.py create mode 100644 visitor.py diff --git a/adapter.py b/adapter.py new file mode 100644 index 0000000..e4f7a0a --- /dev/null +++ b/adapter.py @@ -0,0 +1,28 @@ +from abc import ABC, abstractmethod +class ITransport(ABC): # Интерфейс для транспорта + @abstractmethod + def drive(self): pass +### +class Auto(ITransport): # класс машины с реализацией метода drive + def drive(self): print("Машина едет по дороге") +### +class Driver: # Класс водителя + def travel(self, transport: ITransport): transport.drive() +### +class IAnimal(ABC): # Интерфейс животного + @abstractmethod + def move(self): pass +### +class Camel(IAnimal): # Класс верблюда + def move(self): print("Верблюд идет по пескам пустыни") +### +class CamelToTransportAdapter(ITransport): # Адаптер от Camel к ITransport + def __init__(self, camel: Camel): self.camel = camel + def drive(self): self.camel.move() + +driver = Driver() # Создаю путешественника +auto = Auto() # Создаю машину +driver.travel(auto) # Отправляемся в путешествие на машине (использует метод drive у транспорта) +camel = Camel() # Встретились пески, надо использовать верблюда +camel_transport = CamelToTransportAdapter(camel) # Используем адаптер, по другому реализующий метод drive +driver.travel(camel_transport) # Продолжаем путь по пескам пустыни на верблюде diff --git a/bridge.py b/bridge.py new file mode 100644 index 0000000..be4cb20 --- /dev/null +++ b/bridge.py @@ -0,0 +1,37 @@ +from abc import ABC, abstractmethod + +class Color(ABC): # реализация (задает общий интерфейс для всех реализаций) + @abstractmethod + def fillColor(self): pass + +class BlackColor(Color): # конкретная реализация + def fillColor(self): print("Filling in black color") + +class GreenColor(Color): # конкретная реализация + def fillColor(self): print("Filling in green color") + +class RedColor(Color): # конкретная реализация + def fillColor(self): print("Filling in red color") + +class Shape(ABC): # абстракция + def __init__(self, color): self.color = color # собственно, мост + @abstractmethod + def draw(self): pass + +class Rectangle(Shape): # клиент (бизнес логика) + def __init__(self, color): super().__init__(color) + def draw(self): + print("Drawing rectangle") + self.color.fillColor() + +class Triangle(Shape): # клиент (бизнес логика) + def __init__(self, color): super().__init__(color) + def draw(self): + print("Drawing triangle") + self.color.fillColor() + +# Пример использования +black, green, red = BlackColor(), GreenColor(), RedColor() # МОСТ ПОЗВОЛИЛ ОТДЕЛЬНО СОЗДАТЬ РЕАЛИЗАЦИИ +rectangle, triangle = Rectangle(black), Triangle(green) +rectangle.draw() +triangle.draw() diff --git a/builder.py b/builder.py new file mode 100644 index 0000000..84b7862 --- /dev/null +++ b/builder.py @@ -0,0 +1,122 @@ +from abc import ABC, abstractmethod + +class Car: + def __init__(self): + self.seats = None + self.engine = None + self.trip_computer = None + self.gps = None + + def __str__(self): + return (f"Car with {self.seats} seats, {self.engine} engine, " + f"trip computer: {self.trip_computer}, GPS: {self.gps}") + +class CarManual: + def __init__(self): + self.seats = None + self.engine = None + self.trip_computer = None + self.gps = None + def __str__(self): + return (f"Car manual:\nSeats: {self.seats}\nEngine: {self.engine}\n" + f"trip computer: {self.trip_computer}\nGPS: {self.gps}") + +class Builder(ABC): + @abstractmethod + def reset(self): + pass + @abstractmethod + def set_seats(self, number): + pass + @abstractmethod + def set_engine(self, engine_type): + pass + @abstractmethod + def set_trip_computer(self, has_trip_computer): + pass + @abstractmethod + def set_gps(self, has_gps): + pass + @abstractmethod + def get_result(self): + pass + +class CarBuilder(Builder): + def __init__(self): + self.reset() + def reset(self): + self._car = Car() + return self + def set_seats(self, number): + self._car.seats = number + return self + def set_engine(self, engine_type): + self._car.engine = engine_type + return self + def set_trip_computer(self, has_trip_computer): + self._car.trip_computer = has_trip_computer + return self + def set_gps(self, has_gps): + self._car.gps = has_gps + return self + def get_result(self): + car = self._car + self.reset() + return car + +class CarManualBuilder(Builder): + def __init__(self): + self.reset() + def reset(self): + self._manual = CarManual() + return self + def set_seats(self, number): + self._manual.seats = f"{number} seats" + return self + def set_engine(self, engine_type): + self._manual.engine = f"engine type: {engine_type}" + return self + def set_trip_computer(self, has_trip_computer): + self._manual.trip_computer = "Equipped with a trip computer" if has_trip_computer else "No trip computer" + return self + def set_gps(self, has_gps): + self._manual.gps = "includes GPS navigation" if has_gps else "No GPS navigation" + return self + def get_result(self): + manual = self._manual + self.reset() + return manual + +class Director: + def __init__(self, builder: Builder): + self._builder = builder + def set_builder(self, builder: Builder): + self._builder = builder + def construct_sport_car(self): + self._builder.reset() + self._builder.set_seats(2) + self._builder.set_engine("V8") + self._builder.set_trip_computer(True) + self._builder.set_gps(True) + def construct_suv(self): + self._builder.reset() + self._builder.set_seats(7) + self._builder.set_engine("V6") + self._builder.set_trip_computer(True) + self._builder.set_gps(False) + +director = Director(CarBuilder()) +director.construct_sport_car() +print(director._builder.get_result()) + +director.set_builder(CarManualBuilder()) +director.construct_sport_car() +print(director._builder.get_result()) + +director.set_builder(CarBuilder()) +director.construct_suv() +print(director._builder.get_result()) + +director.set_builder(CarManualBuilder()) +director.construct_suv() +print(director._builder.get_result()) diff --git a/chain.py b/chain.py new file mode 100644 index 0000000..198a55f --- /dev/null +++ b/chain.py @@ -0,0 +1,32 @@ +from abc import ABC, abstractmethod + +class Handler(ABC): + def __init__(self, successor=None): self.successor = successor # Следующий обработчик в цепи + @abstractmethod + def handle_request(self, request): pass + +class ConcreteHandlerA(Handler): + def handle_request(self, request): + if request == "A": + return f"Handler A handled the request: {request}" + elif self.successor: + return self.successor.handle_request(request) + return "Request not handled" + +class ConcreteHandlerB(Handler): + def handle_request(self, request): + if request == "B": + return f"Handler B handled the request: {request}" + elif self.successor: + return self.successor.handle_request(request) + return "Request not handled" + +class ConcreteHandlerC(Handler): + def handle_request(self, request): + if request == "C": return f"Handler C handled the request: {request}" + elif self.successor: return self.successor.handle_request(request) + return "Request not handled" + +handler_chain = ConcreteHandlerA(ConcreteHandlerB(ConcreteHandlerC())) # Цепочка обработчиков +requests = ["A", "B", "C", "D"] # Примеры запросов +for req in requests: print(handler_chain.handle_request(req)) diff --git a/command.py b/command.py new file mode 100644 index 0000000..384d09e --- /dev/null +++ b/command.py @@ -0,0 +1,37 @@ +from abc import ABC, abstractmethod +class Command(ABC): + @abstractmethod + def execute(self): pass +# Команда для включения света +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 Light: + def turn_on(self): print("Свет включен.") + def turn_off(self): print("Свет выключен.") +# Класс-отправитель (Invoker), который инициирует команды +class RemoteControl: + def __init__(self): self.commands = [] + def set_command(self, command): self.commands.append(command) + def press_button(self): + if self.commands: + command = self.commands.pop(0) # Извлекаем и выполняем первую команду + command.execute() + else: print("Нет доступных команд.") + +light = Light() +light_on, light_off = LightOnCommand(light), LightOffCommand(light) # Создаем команды +# Создаем пульт управления (invoker, который инициирует команды) +remote = RemoteControl() +# Устанавливаем команды +remote.set_command(light_on) +remote.set_command(light_off) +# Выполнение установленных команд +remote.press_button() # Включает свет +remote.press_button() # Выключает свет +remote.press_button() # Нет доступных команд diff --git a/composite.py b/composite.py new file mode 100644 index 0000000..65fb23f --- /dev/null +++ b/composite.py @@ -0,0 +1,54 @@ +class Component: + """Абстрактный класс для всех компонентов.""" + def operation(self): + raise NotImplementedError("Метод operation должен быть переопределен.") + + +class Leaf(Component): + """Листовой элемент, который не имеет подкомпонентов.""" + def __init__(self, name): + self.name = name + + def operation(self): + return f"Leaf: {self.name}" + + +class Composite(Component): + """Композитный элемент, который может содержать другие компоненты.""" + def __init__(self, name): + self.name = name + self.children = [] + + def add(self, component): + self.children.append(component) + + def remove(self, component): + self.children.remove(component) + + def operation(self): + results = [f"Composite: {self.name}"] + for child in self.children: + results.append(child.operation()) + return "\n".join(results) + + +# Пример использования +if __name__ == "__main__": + # Создаем листья + leaf1 = Leaf("Leaf 1") + leaf2 = Leaf("Leaf 2") + leaf3 = Leaf("Leaf 3") + + # Создаем композиты + composite1 = Composite("Composite 1") + composite2 = Composite("Composite 2") + + # Добавляем листья в композиты + composite1.add(leaf1) + composite1.add(leaf2) + + composite2.add(leaf3) + composite2.add(composite1) # Вложение composite1 в composite2 + + # Выполняем операции + print(composite2.operation()) diff --git a/decorator.py b/decorator.py new file mode 100644 index 0000000..1162725 --- /dev/null +++ b/decorator.py @@ -0,0 +1,40 @@ +from abc import ABC, abstractmethod + +class IBeverage(ABC): + @abstractmethod + def getDescriprion(self) -> str: pass + @abstractmethod + def getCost(self) -> int: pass + +class Coffe(IBeverage): + def getDescriprion(self) -> str: return "Coffee" + def getCost(self) -> int: return 100 + +class Tea(IBeverage): + def getDescriprion(self) -> str: return "Tea" + def getCost(self) -> int: return 100 + +class MilkShake(IBeverage): + def getDescriprion(self) -> str: return "Milk Shake" + def getCost(self) -> int: return 250 + +class ToppingDecorator(IBeverage): + def __init__(self, beverage: IBeverage): self._beverage = beverage + def getDescriprion(self) -> str: return f"{self._beverage.getDescriprion()}, {self.getToppingDescription()}" + def getCost(self) -> int: return self._beverage.getCost() + self.getToppingCost() + @abstractmethod + def getToppingDescription(self) -> str: pass + @abstractmethod + def getToppingCost(self) -> int: pass + +class Cinnamon(ToppingDecorator): + def getToppingDescription(self) -> str: return "Cinnamon" + def getToppingCost(self) -> int: return 30 + +class Ice(ToppingDecorator): + def getToppingDescription(self) -> str: return "Ice" + def getToppingCost(self) -> int: return 15 + +coffee, tea, milkshake = Coffe(), Tea(), MilkShake() +beverages = [Ice(Cinnamon(coffee)), Cinnamon(tea), Cinnamon(milkshake)] +for beverage in beverages: print(f"{beverage.getDescriprion()} - Cost: {beverage.getCost()}") \ No newline at end of file diff --git a/flyweight.py b/flyweight.py new file mode 100644 index 0000000..a95b414 --- /dev/null +++ b/flyweight.py @@ -0,0 +1,34 @@ +from abc import ABC, abstractmethod + +class Flyweight(ABC): + """Абстрактный класс Легковеса.""" + @abstractmethod + def operation(self, extrinsic_state): pass + +"""Конкретный Легковес, который хранит внутреннее состояние.""" +class ConcreteFlyweight(Flyweight): + def __init__(self, intrinsic_state): self.intrinsic_state = intrinsic_state + def operation(self, extrinsic_state): + return f"Легковес с внутренним состоянием: {self.intrinsic_state}, и адресом: {extrinsic_state}" + +class FlyweightFactory: + """Фабрика Легковесов, которая управляет созданием и хранением Легковесов.""" + def __init__(self): self._flyweights = {} + def get_flyweight(self, intrinsic_state): + if intrinsic_state not in self._flyweights: + self._flyweights[intrinsic_state] = ConcreteFlyweight(intrinsic_state) + return self._flyweights[intrinsic_state] + +factory = FlyweightFactory() + +# Создаем легковесы +flyweights = [ + factory.get_flyweight("A"), + factory.get_flyweight("B"), + factory.get_flyweight("A"), # Этот легковес будет переиспользован + factory.get_flyweight("C"), +] + +# Выполняем операции с легковесами +for i, flyweight in enumerate(flyweights): + print(flyweight.operation(f"{flyweight}")) diff --git a/iterator.py b/iterator.py new file mode 100644 index 0000000..a9789d2 --- /dev/null +++ b/iterator.py @@ -0,0 +1,28 @@ +from typing import List, Iterator +# юзер = его имя + список друзей +class VkUser: + def __init__(self, name: str, friends: List[str]): + self.name = name + self.friends = friends + def get_friends(self) -> List[str]: + return self.friends + +class VkFriendIterator(Iterator): + def __init__(self, vk_user: VkUser): + self._vk_user = vk_user + self._index = 0 + def __iter__(self): + return self + def __next__(self): + if self._index < len(self._vk_user.get_friends()): + friend = self._vk_user.get_friends()[self._index] + self._index += 1 + return friend + else: + raise StopIteration + +user = VkUser("Alice", ["Bob", "Charlie", "David", "Emma"]) +friends_iterator = VkFriendIterator(user) +print(f"Friends of {user.name}:") +for friend in friends_iterator: + print(friend) \ No newline at end of file diff --git a/mediator.py b/mediator.py new file mode 100644 index 0000000..f63e2a1 --- /dev/null +++ b/mediator.py @@ -0,0 +1,48 @@ +from abc import ABC, abstractmethod + +class IMediator(ABC): + @abstractmethod + def register_user(self): pass + @abstractmethod + def send_message(self): pass + +class Mediator: + """Класс-посредник, который управляет взаимодействием между пользователями.""" + def __init__(self): self._users = [] + + def register_user(self, user): + """Регистрация пользователя в системе.""" + self._users.append(user) + user.set_mediator(self) + + def send_message(self, sender, message): + """Отправка сообщения от одного пользователя всем остальным.""" + for user in self._users: + if user != sender: user.receive_message(message) + +class User: + """Класс пользователя, который может отправлять и получать сообщения.""" + def __init__(self, name): + self._name = name + self._mediator = None + + def set_mediator(self, mediator): + """Установка посредника для пользователя.""" + self._mediator = mediator + + def send_message(self, message): + """Отправка сообщения через посредника.""" + print(f"{self._name} отправляет сообщение: {message}") + self._mediator.send_message(self, message) + + def receive_message(self, message): + """Получение сообщения от другого пользователя.""" + print(f"{self._name} получил сообщение: {message}") + + +mediator = Mediator() +user1, user2, user3 = User("Alice"), User("Bob"), User("Charlie") +mediator.register_user(user1) +mediator.register_user(user2) +mediator.register_user(user3) +user1.send_message("Привет всем!") diff --git a/memento.py b/memento.py new file mode 100644 index 0000000..20a95cf --- /dev/null +++ b/memento.py @@ -0,0 +1,39 @@ +from abc import ABC, abstractmethod + +class IMemento(ABC): + @abstractmethod + def get_state(self): pass + +class Memento(IMemento): + """Класс Снимок, который хранит состояние объекта.""" + def __init__(self, state): self._state = state + def get_state(self): return self._state + +class TextEditor: + """Класс текстового редактора, который изменяет свое состояние.""" + def __init__(self): self._text = "" + def write(self, text): self._text += text + def get_text(self): return self._text + def save(self): + """Сохраняем текущее состояние в снимок.""" + return Memento(self._text) + def restore(self, memento): + """Восстанавливаем состояние из снимка.""" + self._text = memento.get_state() + +class Caretaker: + """Класс Хранитель, который управляет сохранением и восстановлением снимков.""" + def __init__(self): self._mementos = [] + def save_memento(self, memento): self._mementos.append(memento) + def get_memento(self, index): return self._mementos[index] + +editor, caretaker = TextEditor(), Caretaker() +# Пишем текст и сохраняем состояние +editor.write("Hello, ") +caretaker.save_memento(editor.save()) +editor.write("world!") +caretaker.save_memento(editor.save()) +print("Текущий текст:", editor.get_text()) # Вывод: Hello, world! +# Восстанавливаем предыдущее состояние +editor.restore(caretaker.get_memento(0)) +print("После восстановления:", editor.get_text()) # Вывод: Hello, diff --git a/proxy.py b/proxy.py new file mode 100644 index 0000000..b30c714 --- /dev/null +++ b/proxy.py @@ -0,0 +1,25 @@ +from abc import ABC, abstractmethod + +class IService(ABC): + @abstractmethod + def request(self): pass + +class RealService(IService): + def request(self): print("RealService: Handling request.") + +class ProxyService(IService): + def __init__(self, real_subject): + self._real_subject = real_subject + def request(self): + # Дополнительные операции до вызова метода оригинала + print("Proxy: Checking access before firing a real request.") + # Вызов метода оригинала + result = self._real_subject.request() + # Дополнительные операции после вызова метода оригинала + print("Proxy: Logging the request.") + return result +# Клиентский код +if __name__ == "__main__": + real_service = RealService() + proxy = ProxyService(real_service) + proxy.request() # Клиент вызывает метод через прокси diff --git a/singleton.py b/singleton.py new file mode 100644 index 0000000..edf6800 --- /dev/null +++ b/singleton.py @@ -0,0 +1,22 @@ +class Singleton: + __instance = None + def __init__(self): + if not Singleton.__instance: + print("init method is called") + else: + print("instance is already created:", self.getInstance()) + + @classmethod + # cls — это конвенция, аналогичная self, но вместо ссылки на экземпляр класса (как в обычных методах), + # она ссылается на сам класс. Это позволяет вам обращаться к атрибутам и методам + # класса без необходимости создавать экземпляр класса. + def getInstance(cls): + if not cls.__instance: + cls.__instance = Singleton() + return cls.__instance + +singleton1 = Singleton.getInstance() +singleton2 = Singleton.getInstance() + +print("singleton1:", singleton1) +print("singleton2:", singleton2) \ No newline at end of file diff --git a/state.py b/state.py new file mode 100644 index 0000000..bfe5cd7 --- /dev/null +++ b/state.py @@ -0,0 +1,81 @@ +from abc import ABC, abstractmethod +# интерфейс состояния +class State(ABC): + @abstractmethod + def insert_coin(self): pass + @abstractmethod + def select_drink(self): pass + @abstractmethod + def dispense(self): pass +# состояние ожидания монеты +class WaitingForCoinState(State): + def __init__(self, vending_machine): self.vending_machine = vending_machine + def insert_coin(self): + print("Монета принята") + self.vending_machine.set_state(self.vending_machine.waiting_for_selection) + def select_drink(self): + print("Сначала вставьте монету") + def dispense(self): + print("Невозможно выдать напиток без оплаты") +# состояние "Нет товаров" +class OutOfStockState(State): + def __init__(self, vending_machine): self.vending_machine = vending_machine + def insert_coin(self): print("Нет товаров") + def select_drink(self): print("Нет товаров") + def dispense(self): print("Нет товаров") +# состояние "Ожидание выбора" +class WaitingForSelectionState(State): + def __init__(self, vending_machine): self.vending_machine = vending_machine + def insert_coin(self): + print("Монета уже вставлена") + def select_drink(self): + print("Напиток выбран") + self.vending_machine.set_state(self.vending_machine.dispensing) + def dispense(self): + print("Выберите напиток, прежде чем получить его") +# состояние "Выдача товара" +class DispensingState(State): + def __init__(self, vending_machine): self.vending_machine = vending_machine + def insert_coin(self): print("Идет выдача напитка") + def select_drink(self): print("Идет выдача напитка") + def dispense(self): + if self.vending_machine.stock > 0: + self.vending_machine.stock -= 1 + print("Напиток выдан") + if self.vending_machine.stock == 0: + print("Товар закончился") + self.vending_machine.set_state(self.vending_machine.out_of_stock) + else: + self.vending_machine.set_state(self.vending_machine.waiting_for_coin) + else: + print("Товар закончился") + self.vending_machine.set_state(self.vending_machine.out_of_stock) +# контекст +class VendingMachine: + def __init__(self): + self.stock = 0 + self.out_of_stock = OutOfStockState(self) + self.waiting_for_coin = WaitingForCoinState(self) + self.waiting_for_selection = WaitingForSelectionState(self) + self.dispensing = DispensingState(self) + self.state = self.out_of_stock + def set_state(self, state): self.state = state + def insert_coin(self): self.state.insert_coin() + def select_drink(self): self.state.select_drink() + def dispense(self): self.state.dispense() + def refill(self, amount): + self.stock += amount + print(f"Товар пополнен. Запас: {self.stock}") + if self.stock > 0: + self.set_state(self.waiting_for_coin) + +vending_machine = VendingMachine() +vending_machine.refill(3) +vending_machine.insert_coin() +vending_machine.select_drink() +vending_machine.dispense() +vending_machine.select_drink() +vending_machine.insert_coin() +vending_machine.dispense() +vending_machine.dispense() +vending_machine.dispense() \ No newline at end of file diff --git a/visitor.py b/visitor.py new file mode 100644 index 0000000..fd9f08d --- /dev/null +++ b/visitor.py @@ -0,0 +1,34 @@ +from abc import ABC, abstractmethod +# Интерфейс для элементов, которые могут быть посещены +class Element(ABC): + @abstractmethod + def accept(self, visitor): pass +# Конкретные элементы +class Book(Element): + def __init__(self, title, author): + self.title = title + self.author = author + def accept(self, visitor): visitor.visit_book(self) + +class Movie(Element): + def __init__(self, title, director): + self.title = title + self.director = director + def accept(self, visitor): visitor.visit_movie(self) +# Интерфейс для посетителей +class Visitor(ABC): + @abstractmethod + def visit_book(self, book): pass + @abstractmethod + def visit_movie(self, movie): pass +# Конкретный посетитель +class ConcreteVisitor(Visitor): + def visit_book(self, book): print(f"Книга: {book.title}, Автор: {book.author}") + def visit_movie(self, movie): print(f"Фильм: {movie.title}, Режиссер: {movie.director}") +# Создаем элементы +book1, book2, movie1 = Book("1984", "Джордж Оруэлл"), Book("Мастер и Маргарита", "Михаил Булгаков"), \ + Movie("Начало", "Кристофер Нолан") +# Создаем посетителя +print_visitor = ConcreteVisitor() +# Посещаем элементы +for element in [book1, book2, movie1]: element.accept(print_visitor)