python design pattern creation pattern

Posted by elklabone on Tue, 21 Sep 2021 11:04:02 +0200

Creation mode (5 kinds): factory method mode, abstract factory mode, creator mode, prototype mode and singleton mode

https://www.bilibili.com/video/BV19541167cn?spm_id_from=333.999.0.0

1. Object oriented

"""
SOLID principle:
    - Open and closed principle
    - Richter substitution principle
    - Dependency Inversion Principle
    - Interface isolation principle
    - Single responsibility principle
"""
from abc import ABCMeta, abstractmethod


class Payment(metaclass=ABCMeta):
    # abstract class
    @abstractmethod
    def pay(self, money):
        pass


class Aipay(Payment):
    def pay(self, money):
        print('Alipay payment%d element.' % money)


class WechatPay(Payment):
    def pay(self, money):
        print('Wechat payment%d element.' % money)


p = Aipay()
p.pay(100)

2. Simple factory mode (not 23)

  • Simple factory mode
    • Content: instead of directly exposing the details of the created implementation to the client, the implementation of the created product class is copied through a factory class
    • Role:
      • Factory role
      • Abstract product role
      • Specific product roles
    • advantage:
      • Hides the implementation details of object creation
      • The client does not need to modify the code
    • shortcoming
      • Violating the principle of single responsibility, the creation logic is concentrated in a factory class
      • When adding a new factory product, the factory code needs to be modified, which violates the opening and closing principle
from abc import ABCMeta, abstractmethod


class Payment(metaclass=ABCMeta):
    # abstract class
    @abstractmethod
    def pay(self, money):
        pass


class Alipay(Payment):
    def __init__(self, use_huabei=False):
        self.use_huabei = use_huabei

    def pay(self, money):
        if self.use_huabei:
            print('Flower payment%d element.' % money)
        else:
            print("Alipay balance payment%d element" % money)


class WechatPay(Payment):
    def pay(self, money):
        print('Wechat payment%d element.' % money)


class PaymentFactory:
    def create_payment(self, method):
        if method == 'alipay':
            return Alipay()
        elif method == 'wechat':
            return WechatPay()
        elif method == 'huabei':
            return Alipay(use_huabei=True)
        else:
            return TypeError("No such payment named %s" % method)


# client
pf = PaymentFactory()
p = pf.create_payment('huabei')
p.pay(100)

3. Factory method model

  • Factory method model
    • Content: define an interface (factory interface) for creating objects, and let subclasses decide which product class to instantiate
    • Role:
      • Abstract factory role
      • Specific factory roles
      • Abstract product role
      • Specific product roles
    • advantage:
      • Each specific product corresponds to a specific factory class. There is no need to modify the factory class code
      • Hides the implementation details of object creation
    • Disadvantages:
      • Each time a specific class is added, a corresponding specific factory class must be added
from abc import ABCMeta, abstractmethod


class Payment(metaclass=ABCMeta):
    # abstract class
    @abstractmethod
    def pay(self, money):
        pass


class Alipay(Payment):
    def __init__(self, use_huabei=False):
        self.use_huabei = use_huabei

    def pay(self, money):
        if self.use_huabei:
            print('Flower payment%d element.' % money)
        else:
            print("Alipay balance payment%d element" % money)


class WechatPay(Payment):
    def pay(self, money):
        print('Wechat payment%d element.' % money)


class PaymentFactory(metaclass=ABCMeta):
    @abstractmethod
    def create_payment(self):
        pass


class AlipayFactory(PaymentFactory):
    def create_payment(self):
        return Alipay()


class WechatpayFactory(PaymentFactory):
    def create_payment(self):
        return WechatPay()


class HuabeiFactory(PaymentFactory):
    def create_payment(self):
        return Alipay(use_huabei=True)


pf = HuabeiFactory()
p = pf.create_payment()
p.pay(100)

4. Abstract factory pattern

  • Abstract factory pattern:
    • Content: define a factory class interface to let factory subclasses create a series of related or interdependent objects
    • Compared with the factory method pattern, each concrete factory in the abstract factory pattern produces a set of products
    • Role:
      • Abstract factory role
      • Specific factory roles
      • Abstract product role
      • Specific product roles

5. Builder mode

  • Builder pattern
    • Content: separate the construction of a complex object from its representation, so that the same construction process can create different representations
    • Role:
      • Abstract Creator
      • Specific Creator
      • Commander
      • product
    • Similar to the abstract factory pattern, the builder pattern is also used to create complex objects. The main difference is that the builder pattern pays attention to building one object step by step
      Complex objects, while the abstract factory pattern focuses on multiple series of product objects
from abc import ABCMeta, abstractmethod


class Player:
    def __init__(self, face=None, body=None, arm=None, leg=None):
        self.face = face
        self.body = body
        self.arm = arm
        self.leg = leg

    def __str__(self):
        return "%s %s %s %s" % (self.face, self.body, self.arm, self.leg)


class PlayBuilder(metaclass=ABCMeta):
    @abstractmethod
    def build_face(self):
        pass

    @abstractmethod
    def build_body(self):
        pass

    @abstractmethod
    def build_arm(self):
        pass

    @abstractmethod
    def build_leg(self):
        pass


class SexyGirlBuilder(PlayBuilder):
    def __init__(self):
        self.player = Player()

    def build_face(self):
        self.player.face = "cheek"

    def build_body(self):
        self.player.body = "slim"

    def build_arm(self):
        self.player.arm = "Arms"

    def build_leg(self):
        self.player.leg = "long legs"


class Monster(PlayBuilder):
    def __init__(self):
        self.player = Player()

    def build_face(self):
        self.player.face = "Monster face"

    def build_body(self):
        self.player.body = "Monster figure"

    def build_arm(self):
        self.player.arm = "Monster arm"

    def build_leg(self):
        self.player.leg = "Monster leg"


class PlayerDirector:  # Control assembly sequence
    def build_player(self, builder):
        builder.build_body()
        builder.build_face()
        builder.build_arm()
        builder.build_leg()
        return builder.player


# client
builder = SexyGirlBuilder()
director = PlayerDirector()
p = director.build_player(builder)

6. Singleton mode

  • Singleton mode
    • Content: ensure that a class has only one instance, and provide a global access point to access it
    • Role: single case
    • advantage:
      • Controlled access to unique instances
      • A singleton is equivalent to a global variable, but prevents namespace contamination
class Singleton:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance


class MyClass(Singleton):
    def __init__(self, a):
        self.a = a


a = MyClass(10)
b = MyClass(20)

Topics: Python