commit ca095408cf4aa8255e1131dfd9475a22e881c829 Author: serr Date: Fri Feb 7 12:10:20 2025 +0300 new 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)