[GO] Learn the design pattern "Flyweight" in Python

As a material for learning GoF design patterns, the book "Introduction to Design Patterns Learned in the Augmented and Revised Java Language" seems to be helpful. However, since the examples taken up are based on JAVA, I tried the same practice in Python to deepen my understanding.

■ Flyweight (flyweight pattern)

The Flyweight pattern is one of the design patterns defined by GoF. The purpose is to save resources in the program by reusing one instance when using equivalent instances in different places.

UML class and sequence diagram W3sDesign_Flyweight_Design_Pattern_UML.jpg UML class diagram flyweight.png (The above is quoted from Wikipedia)

□ Memorandum

** flyweight ** stands for "flyweight", which is the lightest weight class in boxing, and in this design pattern, it is said to be for "lightening" objects. The technique used in the Flyweight pattern is to" share instances as much as possible and not wastefully new ", so when you need an instance, you can use the already created instance instead of always newing it. Then, it seems that it is shared and used. Intuitively, I feel that it is an application of design pattern "Singleton".

■ "Flyweight" sample program

(1) Advance preparation

Prepare a text file that displays numbers like Akky Art.

big0.txt


....######......
..##......##....
..##......##....
..##......##....
..##......##....
..##......##....
....######......
................

big1.txt


......##........
..######........
......##........
......##........
......##........
......##........
..##########....
................

big2.txt


....######......
..##......##....
..........##....
......####......
....##..........
..##............
..##########....
................

(Hereafter omitted)

(2) Operation check

I would like to actually run a sample program that utilizes the Flyweight pattern and check the following behavior.

--Display the specified numbers in ASCII art in the order of the argument numbers

$ python Main.py 012123
....######......
..##......##....
..##......##....
..##......##....
..##......##....
..##......##....
....######......
................
......##........
..######........
......##........
......##........
......##........
......##........
..##########....
................
....######......
..##......##....
..........##....
......####......
....##..........
..##............
..##########....
................
......##........
..######........
......##........
......##........
......##........
......##........
..##########....
................
....######......
..##......##....
..........##....
......####......
....##..........
..##............
..##########....
................
....######......
..##......##....
..........##....
......####......
..........##....
..##......##....
....######......
................

■ Details of sample program

Similar code has been uploaded to the Git repository. https://github.com/ttsubo/study_of_design_pattern/tree/master/Flyweight

--Directory structure

.
├── Main.py
├── big0.txt
├── big1.txt
├── big2.txt
├── big3.txt
├── big4.txt
├── big5.txt
├── big6.txt
├── big7.txt
├── big8.txt
├── big9.txt
└── flyweight
    ├── __init__.py
    └── big_char_factory.py

(1) The role of Flyweight

If you handle it normally, the program will be heavy, so it is a role that represents something that should be shared. In the sample program, the BigChar class serves this role.

flyweight/big_char_factory.py


class BigChar(object):
    def __init__(self, charname):
        try:
            with open("big{0}.txt".format(charname), 'r') as txtfile:
                data = txtfile.read()
            self.__fontdata = data
        except IOError:
            self.__fontdata = charname + '?'

    def __str__(self):
        return self.__fontdata

(2) The role of Flyweight Factory

It is the role of the factory that makes Flyweight. If you use this factory to create a Flyweight role, the instance will be shared. In the sample program, the BigCharFactory class serves this role.

flyweight/big_char_factory.py


class BigCharFactory(object):
    def __init__(self):
        self.__pool = {}

    @classmethod
    def getInstance(cls):
        if not hasattr(cls, "_instance"):
            cls._instance = cls()
        return cls._instance

    def getBigChar(self, charname):
        bc = self.__pool.get(charname)
        if bc is None:
            bc = BigChar(charname)
            self.__pool[charname] = bc
        return bc

(3) The role of Client

It is a role to create a Flyweight using the Flyweight Factory role and use it. In the sample program, the BigString class and the startMain method serve this role.

flyweight/big_char_factory.py


class BigString(object):
    def __init__(self, string):
        self.bigchars = []
        self.factory = BigCharFactory.getInstance()
        for s in string:
            self.bigchars.append(self.factory.getBigChar(s))

    def print(self):
        for bc in self.bigchars:
            print(bc)

Main.py


import sys
from flyweight.big_char_factory import BigCharFactory, BigString

def startMain(string):
    bs = BigString(string)
    bs.print()

if __name__ == '__main__':
    startMain(sys.argv[1])

■ Reference URL

-[Finishing "Introduction to Design Patterns Learned in Java Language" (Not)](https://medium.com/since-i-want-to-start-blog-that-looks-like-men-do/java Introduction to Design Patterns Learned in Language-Finishing-Not-2cc9b34a30b2)

Recommended Posts

Learn the design pattern "Flyweight" in Python
Learn the design pattern "Prototype" in Python
Learn the design pattern "Builder" in Python
Learn the design pattern "Observer" in Python
Learn the design pattern "Memento" in Python
Learn the design pattern "Proxy" in Python
Learn the design pattern "Command" in Python
Learn the design pattern "Visitor" in Python
Learn the design pattern "Bridge" in Python
Learn the design pattern "Mediator" in Python
Learn the design pattern "Decorator" in Python
Learn the design pattern "Iterator" in Python
Learn the design pattern "Strategy" in Python
Learn the design pattern "Composite" in Python
Learn the design pattern "State" in Python
Learn the design pattern "Adapter" in Python
Learn the design pattern "Abstract Factory" in Python
Learn the design pattern "Template Method" in Python
Learn the design pattern "Factory Method" in Python
Learn the design pattern "Chain of Responsibility" in Python
Learn the design pattern "Singleton" with Python
Learn the design pattern "Facade" with Python
Implement the Singleton pattern in Python
Flyweight pattern in Java
Singleton pattern in Python
Visitor pattern in Python
Download the file in Python
Find the difference in Python
Learn cumulative sum in Python
Design Patterns in Python: Introduction
Learn exploration in Python # 1 Full exploration
Python Design Pattern --Template method
Getting the arXiv API in Python
Change the Flyweight pattern to Pythonic (?) (3)
Python in the browser: Brython's recommendation
Change the Flyweight pattern to Pythonic (?) (2)
Save the binary file in Python
Hit the Sesami API in Python
Get the desktop path in Python
Get the script path in Python
In the python command python points to python3.8
Hit the web API in Python
Change the Flyweight pattern to Pythonic (?) (1)
I wrote the queue in Python
Calculate the previous month in Python
Examine the object's class in python
Get the desktop path in Python
Get the host name in Python
Access the Twitter API in Python
The first step in Python Matplotlib
I wrote the stack in Python
Master the weakref module in Python
Learn the basics of Python ① Beginners
Load the remote Python SDK in IntelliJ
Try using the Wunderlist API in Python
Check the behavior of destructor in Python
[Python Kivy] About changing the design theme
Try using the Kraken API in Python
Learn the basics while touching python Variables
Write the test in a python docstring
OR the List in Python (zip function)