동일한 것을 공유해서 낭비 없애기
Flyweight는 플라이급이라는 의미로, 권투에서 가장 체중이 가벼운 체급을 의미한다.
디자인패턴에서는오브젝트를 가볍게 하기 위한 것의 의미에서 사용하였다.
오브젝트는컴퓨터 내부에서 가상적으로 존재하는 것이기 때문에 무겁다 또는 가볍다라고 표현하는 것은 실제 무게가 아닌, "메모리의 사용량"을 의미하는 것이다.
객체를 만들 때 그 객체를 저장하기 위해서 메모리가 확보되는데, 객체를 많이 만든다고 생각해보면 그 객체가차지하고 있는 단위 메모리가 작을 수록 가벼워 진다.
인스턴스를 가능한대로 공유시켜서 쓸데없는 메모리를 할당하지 않도록 한다.
이미 만들어져 있는 인스턴스를 이용할 수 있으면 그것을 공유해서 사용한다.
"여러 장소에 영향을 미친다."
해당 패턴은 global 변수와 유사한 단점을 가지고 있다.
Flyweight 패턴은 인스턴스를 공유하는 것이 주요한 테마이다.
이때, 가장 주의해야 할 것은 공유하고 있는 것을 변경하면 여러 장소에 영향을 미친다는 점이다.
하나의 인스턴스를 변경하면 그 인스턴스를 사용하고 있는 여러 장소에 동시에 영향을 미치게 된다.
여러 장소에 영향을 미치는 것이 항상 나쁜 것은 아니고, 프로그램이 취급하는 문제에 따라서 좋을 수도, 나쁠 수도 있다.
따라서, Flyweight 역할에게 제공하는 정보는 신중히 선택할 필요가 있다.
Intrinsic vs Extrinsic
# 기본적인 코드
class Dog:
def __init__(self, name, age, gender, breed, DNA):
self.name = name
self.age = age
self.gender = gender
self.breed = breed
self.DNA = DNA
def __repr__(self):
return f'{self.name},{self.age},{self.DNA}'
choco = Dog('choco', 2, 'male', 'shihTzu', 'ATAGGCTTACCGATGG....')
baduk = Dog('baduk', 3, 'female', 'jinDo' , 'ATAGGCTTACCGATGG....')
print(choco)
print(baduk)
# 모든 강아지의 DNA 같은 경우
class Dog:
DNAseq = "ATAGGCTTACCGATGG...."
def __init__(self, name, age, gender, breed):
self.name = name
self.age = age
self.gender = gender
self.breed = breed
def __repr__(self):
return f'{self.name},{self.age},{Dog.DNAseq}'
choco = Dog('choco', 2, 'male', 'shihTzu')
baduk = Dog('baduk', 3, 'female', 'jinDo')
print(choco)
print(baduk)
# 새로운 강아지 객체를 만들더라도 시츄나 진돗개라면 이미 존재하는 DNA 정보를 가리킴으로써 메모리 사용량을 줄일 수 있다.
# DogBreedDNA class는 강아지 종과 DNA 정보를 저장하는 class
class DogBreedDNA:
def __init__(self, breed, DNA):
self.breed = breed
self.DNA = DNA
def __repr__(self):
return f'{self.DNA}'
# 강아지 종마다 DNA가 다른 경우
class Dog:
DNA_Table = {}
@staticmethod
def addDNA(breed, DNA):
breed_DNA = DogBreedDNA(breed, DNA)
Dog.DNA_Table[breed] = breed_DNA
def __init__(self, name, age, gender, breed):
self.name = name
self.age = age
self.gender = gender
self.breed = breed
if breed not in Dog.DNA_Table:
raise ValueError(f'{breed} is not in DNA_Table')
def __repr__(self):
return f'{self.name},{self.age},{Dog.DNA_Table[self.breed]}'
Dog.addDNA('shihTzu', 'ATAGGCTTACCGATGG....')
Dog.addDNA('jinDo', 'ATAGGCTTACCGATGG....')
choco = Dog('choco', 2, 'male', 'shihTzu')
baduk = Dog('baduk', 3, 'female', 'jinDo')
print(choco)
print(baduk)