[PYTHON] J'ai étudié les modèles de conception (mémo personnel) Partie 4 (modèle AbstractFactory, modèle de pont, modèle de stratégie)

introduction

Cet article est un mémo d'étude personnel. J'écris un article motivé par l'obsession que ce que j'entre doit être une sortie. J'écris cet article sur Qiita avec l'espoir que quelqu'un qui le connaît pourra signaler les erreurs et donner des conseils.

Je vis une vie professionnelle en tant qu'ingénieur, mais je n'ai pas bien appris les modèles de conception, alors j'ai essayé d'étudier.

Ce qui est décrit ici https://github.com/ck-fm0211/notes_desigh_pattern Je télécharge sur.

Journal passé

J'ai étudié les modèles de conception (mémo personnel) Partie 1 J'ai étudié les modèles de conception (mémo personnel) Partie 2 J'ai étudié les modèles de conception (mémo personnel) Partie 3

Modèle d'usine abstraite

  car.add_tire(CarTire());
  car.add_handle(CarHandle());

――Il peut arriver qu'un pneu différent (pneu de vélo) soit remis en raison d'une erreur du programmeur.

  car.add_tire(BicycleTire());
  car.add_handle(CarHandle());

--Il est possible d'utiliser un objet qui ne doit pas être utilisé

En fait utiliser

Matière

―― Pensez à faire un "pot"

# -*- coding:utf-8 -*-


class HotPot:
    pot = None
    soup = None
    protein = None
    vegetables = []
    other_ingredients = []

    @staticmethod
    def hot_pot(pot):
        HotPot.pot = pot

    @staticmethod
    def add_soup(soup):
        HotPot.soup = soup

    @staticmethod
    def add_main(protein):
        HotPot.protein = protein

    @staticmethod
    def add_vegitables(vegitables):
        HotPot.vegetables = vegitables

    @staticmethod
    def add_other_ingredients(other_ingredients):
        HotPot.other_ingredients = other_ingredients

--Préparer une classe Factory qui résume le processus de fabrication d'un pot

class Factory(metaclass=ABCMeta):

    @abstractmethod
    def get_soup(self):
        pass

    @abstractmethod
    def get_main(self):
        pass

    @abstractmethod
    def get_vegetables(self):
        pass

    @abstractmethod
    def get_other_ingredients(self):
        pass

--Préparez la classe Mizutaki Factory qui hérite de cela et fabriquez un cuiseur à eau sur cette base.

class MizutakiFactory(Factory):

    def get_soup(self):
        return "torigara"

    def get_main(self):
        return "chicken"

    def get_vegetables(self):
        return ["hakusai", "ninjin", "negi"]

    def get_other_ingredients(self):
        return ["tofu"]


class Sample:

    @staticmethod
    def main():
        hp = HotPot()
        mf = MizutakiFactory()

        hp.add_soup(mf.get_main())
        hp.add_main(mf.get_main())
        hp.add_vegitables(mf.get_vegetables())
        hp.add_other_ingredients(mf.get_other_ingredients())

--Sélectionnez et générez la classe Factory à utiliser réellement en fonction de la chaîne de caractères donnée dans l'argument

class Sample:


    @staticmethod
    def create_factory(s):
        if s == "fondue au kimchi":
            return KimuchiFactory()

        elif s == "Sukiyaki":
            return SukiyakiFactory()

        else:
            return MizutakiFactory()

    @staticmethod
    def main(arg):
        hp = HotPot()
        fc = create_factory(arg)

        hp.add_soup(fc.get_main())
        hp.add_main(fc.get_main())
        hp.add_vegitables(fc.get_vegetables())
        hp.add_other_ingredients(fc.get_other_ingredients())

--Dans la méthode principale, le traitement se poursuit sans connaître le type réel de la méthode Factory. En d'autres termes, nous procédons au traitement en utilisant la classe abstraite Factory. ――Il est possible de répondre à la demande de "remplacer en douceur les objets à utiliser"

Résumé des modèles Builder

AbstractFactory.png

Modèle de pont

En fait utiliser

Matière

# -*- coding:utf-8 -*-
from abc import ABCMeta, abstractmethod


class Sorter(metaclass=ABCMeta)

    @abstractmethod
    def sort(self, obj):
        pass


class QuickSorter(Sorter):

    def sort(self, obj):
        #Tri rapide
        pass


class BubbleSorter(Sorter):

    def sort(self, obj):
        #Tri à bulles
        pass

--Je veux ajouter une méthode timer_sorter qui a une fonction pour afficher le temps pris pour le tri dans la classe Sorter.

from datetime import datetime

class TimerSorter(metaclass=ABCMeta, Sorter):

    @abstractmethod
    def time_sorter(self, obj):
        start = datetime.now()
        Sorter.sort(obj)
        end = datetime.now()
        print("time:" + str((end - start)))
class SortImple(metaclass=ABCMeta):
    @abstractmethod
    def sort(self, obj):
        pass


class Sorter:
    si = SortImple()

    @staticmethod
    def sorter(si):
        Sorter.si = si

    def sort(self, obj):
        Sorter.si.sort(obj)


class QuickSorterImple(SortImple):

    def sort(self, obj):
        #Tri rapide
        pass


class BubbleSorterImple(SortImple):

    def sort(self, obj):
        #Tri à bulles
        pass

from datetime import datetime


class TimerSorter(metaclass=ABCMeta, Sorter):

    def __init__(self, sort_impl):
        super(sort_impl)

    @abstractmethod
    def time_sorter(self, obj):
        start = datetime.now()
        Sorter.sort(obj)
        end = datetime.now()
        print("time:" + str((end - start)))

Résumé des modèles Builder

Bridge.png

Modèle de stratégie

――Lors de la programmation normale, l'algorithme peut être implémenté sous une forme qui se fond dans la méthode. --Changez l'algorithme en branchant avec l'instruction if, etc. --Dans le modèle Stratégie, soyez conscient de la partie stratégie et créez-la en tant que classe distincte. --Créez la partie stratégie x en tant que classe distincte, et si vous souhaitez modifier la stratégie, changez la classe de stratégie à utiliser.

En fait utiliser

Matière

――Il existe de nombreux cas où vous devez changer l'algorithme en fonction de la situation. Par exemple, dans un programme de jeu, l'algorithme de stratégie est modifié en fonction du niveau de difficulté. «Ici, pensons à un algorithme qui fait une simple comparaison entre les grands et les petits.

# -*- coding:utf-8 -*-
from abc import ABCMeta, abstractmethod


class Human:

    def __init__(self, name, height, weight, age):
        self.name = name
        self.height = height
        self.weight = weight
        self.age = age
class SampleClass:

    @staticmethod
    def compare(h1: Human, h2: Human) -> int:
        if h1.age > h2.age:
            return 1
        elif h1.age == h2.age:
            return 0
        else:
            return -1

class SampleClass2:

    type = -1
    COMPARE_AGE = 1
    COMPARE_HEIGHT = 2
    COMPARE_WEIGHT = 3

    def __init__(self, type):
        SampleClass2.type = type

    @staticmethod
    def compare(h1: Human, h2: Human) -> int:
        if SampleClass2.type == SampleClass2.COMPARE_AGE:
            if h1.age > h2.age:
                return 1
            elif h1.age == h2.age:
                return 0
            else:
                return -1
        elif SampleClass2.type == SampleClass2.COMPARE_HEIGHT:
            if h1.height > h2.height:
                return 1
            elif h1.height == h2.height:
                return 0
            else:
                return -1
        #・ ・ ・

――Cela devient un code compliqué. Dans le modèle Stratégie, la partie de l'algorithme qui doit être modifiée en fonction de la situation est consciemment séparée en une classe distincte pour améliorer la perspective de modifier ou d'ajouter l'algorithme.

class AgeComparator:

    @staticmethod
    def compare(h1: Human, h2: Human) -> int:
        if h1.age > h2.age:
            return 1
        elif h1.age == h2.age:
            return 0
        else:
            return -1

--Séparez la partie de l'algorithme de comparaison afin que le processus de comparaison réel puisse être délégué à AgeComparator.

class MyClass:

    @staticmethod
    def compare(h1: Human, h2: Human) -> int:
        return AgeComparator.compare(h1, h2)

«Cela seul n'a aucun mérite et ce n'est pas un modèle de stratégie. Le modèle de stratégie nécessite que des parties d'algorithme distinctes aient une interface commune.

class Comparator(metaclass=ABCMeta):

    @staticmethod
    @abstractmethod
    def compare(h1: Human, h2: Human) -> int:
        pass


class AgeComparator(Comparator):

    @staticmethod
    def compare(h1: Human, h2: Human) -> int:
        if h1.age > h2.age:
            return 1
        elif h1.age == h2.age:
            return 0
        else:
            return -1


class HeightComparator(Comparator):

    @staticmethod
    def compare(h1: Human, h2: Human) -> int:
        if h1.height > h2.height:
            return 1
        elif h1.height == h2.height:
            return 0
        else:
            return -1
class SampleClass:

    def __init__(self, comp: Comparator):
        self._comp = comp

    def compare(self, h1: Human, h2: Human) -> int:
        return self._comp.compare(h1, h2)

Résumé des modèles de stratégie

Strategy.png

Recommended Posts

J'ai étudié les modèles de conception (mémo personnel) Partie 4 (modèle AbstractFactory, modèle de pont, modèle de stratégie)
J'ai étudié les modèles de conception (mémo personnel) Partie 3 (modèle de prototype, modèle de constructeur)
J'ai étudié les modèles de conception (mémo personnel) Partie 5 (modèle composite, modèle décorateur, modèle visiteur)
J'ai étudié les modèles de conception (mémo personnel), partie 8 (modèle proxy, modèle de commande, modèle d'interprétation)
J'ai étudié les modèles de conception (mémo personnel) Partie 7 (modèle d'observateur, modèle de souvenir, modèle d'état, modèle de poids mouche)
J'ai étudié les modèles de conception (mémo personnel) Partie 6 (modèle de chaîne de responsabilité, modèle de façade, modèle de médiateur)
Modèle de conception #Strategy
J'ai bien étudié Systemd