Python

""

Python ""

  • (Intrinsic State)
  • (Extrinsic State)


#
class Character:
    def __init__(self, char, font, size, color):
        self.char = char      #
        self.font = font      #
        self.size = size      #
        self.color = color    #
   
    def render(self, position):
        print(f" {position} '{self.char}'")

#
char_a = Character('A', '', 12, '')
char_b = Character('B', '', 12, '')
char_a_another = Character('A', '', 12, '')  # 'A'


from typing import Dict

# -
class CharacterFlyweight:
    def __init__(self, char: str, font: str, size: int, color: str):
        self.char = char      #
        self.font = font      #
        self.size = size      #
        self.color = color    #
   
    def render(self, position: tuple):
        """position """
        x, y = position
        print(f"({x}, {y}): '{self.char}' "
              f"[:{self.font}, :{self.size}, :{self.color}]")

# -
class CharacterFactory:
    _characters: Dict[str, CharacterFlyweight] = {}
   
    @classmethod
    def get_character(cls, char: str, font: str, size: int, color: str) -> CharacterFlyweight:
        #
        key = f"{char}_{font}_{size}_{color}"
       
        #
        if key not in cls._characters:
            cls._characters[key] = CharacterFlyweight(char, font, size, color)
            print(f": {key}")
        else:
            print(f": {key}")
       
        return cls._characters[key]

# -
class TextDocument:
    def __init__(self):
        self.characters = []  #
   
    def add_character(self, char: str, font: str, size: int, color: str, position: tuple):
        #
        character = CharacterFactory.get_character(char, font, size, color)
        #
        self.characters.append((character, position))
   
    def render(self):
        print("\n=== ===")
        for character, position in self.characters:
            character.render(position)
        print("=== ===\n")

#
document = TextDocument()

#
document.add_character('H', 'Arial', 12, 'black', (0, 0))
document.add_character('e', 'Arial', 12, 'black', (1, 0))
document.add_character('l', 'Arial', 12, 'black', (2, 0))
document.add_character('l', 'Arial', 12, 'black', (3, 0))  # 'l'
document.add_character('o', 'Arial', 12, 'black', (4, 0))
document.add_character('!', 'Arial', 12, 'red', (5, 0))    #
document.add_character('H', 'Arial', 12, 'black', (0, 1))  # 'H'

#
document.render()

#
print(f" {len(CharacterFactory._characters)} ")

: H_Arial_12_black
: e_Arial_12_black
: l_Arial_12_black
: l_Arial_12_black
: o_Arial_12_black
: !_Arial_12_red
: H_Arial_12_black

===  ===
(0, 0): 'H' [:Arial, :12, :black]
(1, 0): 'e' [:Arial, :12, :black]
(2, 0): 'l' [:Arial, :12, :black]
(3, 0): 'l' [:Arial, :12, :black]
(4, 0): 'o' [:Arial, :12, :black]
(5, 0): '!' [:Arial, :12, :red]
(0, 1): 'H' [:Arial, :12, :black]
===  ===

 6 

1. Flyweight

2. ConcreteFlyweight

3. FlyweightFactory

4. Client


-

from typing import Dict, List
from dataclasses import dataclass

@dataclass
class TreeType:
    """ - """
    name: str          #
    texture: str       #
    color: str         #
   
    def render(self, x: int, y: int, height: int):
        """"""
        print(f"({x}, {y}){self.name}{height} "
              f"[:{self.texture}, :{self.color}]")

class TreeFactory:
    """ - """
    _tree_types: Dict[str, TreeType] = {}
   
    @classmethod
    def get_tree_type(cls, name: str, texture: str, color: str) -> TreeType:
        key = f"{name}_{texture}_{color}"
        if key not in cls._tree_types:
            cls._tree_types[key] = TreeType(name, texture, color)
            print(f": {name}")
        return cls._tree_types[key]
   
    @classmethod
    def list_tree_types(cls):
        print(f"\n {len(cls._tree_types)} :")
        for tree_type in cls._tree_types.values():
            print(f"  - {tree_type.name}")

class Tree:
    """ - """
    def __init__(self, x: int, y: int, height: int, tree_type: TreeType):
        self.x = x              # X
        self.y = y              # Y  
        self.height = height    #
        self.tree_type = tree_type  #
   
    def render(self):
        self.tree_type.render(self.x, self.y, self.height)

class Forest:
    """ - """
    def __init__(self):
        self.trees: List[Tree] = []
   
    def plant_tree(self, x: int, y: int, height: int,
                   name: str, texture: str, color: str):
        tree_type = TreeFactory.get_tree_type(name, texture, color)
        tree = Tree(x, y, height, tree_type)
        self.trees.append(tree)
   
    def render(self):
        print("\n=== ===")
        for tree in self.trees:
            tree.render()
        print("=== ===")

#
forest = Forest()

# -
forest.plant_tree(10, 20, 15, "", "pine_texture.png", "")
forest.plant_tree(30, 40, 12, "", "pine_texture.png", "")  #
forest.plant_tree(50, 60, 18, "", "oak_texture.png", "")
forest.plant_tree(70, 80, 20, "", "pine_texture.png", "")  #
forest.plant_tree(90, 100, 16, "", "maple_texture.png", "")

#
forest.render()

#
TreeFactory.list_tree_types()

  1. bug


1

#
class AdvancedCharacterFlyweight:
    #
    pass

#
def test_advanced_system():
    #
    pass

2

class IconFlyweight:
    #
    pass

class IconFactory:
    #
    pass

class Application:
    #
    pass