cs/디자인 패턴
[디자인 패턴]FlyWeight 패턴(플라이웨이트 패턴)
sang_hoony
2019. 1. 31. 16:46
FlyWeight 패턴
FlyWeight 패턴은 이름 그대로 더 가볍게 프로그래밍을 할 수 없을까 해서 만들어진 패턴이다. new를 통해 객체를 한번만 만들고 필요할 때 마다 사전에 만들어진 객체를 공유하여 제공하는 방법입니다.
주의할 점
특정한 객체를(새 객체가 아니라 공유된 객체) 바꾸어주면 여러 장소에 영향을 미칠 수 있습니다. 그러니 이부분을 고려하여 코드를 작성해야할 것 같습니다.
UML
BigChar.java
import java.io.*;
public class BigChar{
private String fontdata;
public BigChar(char charname){
try{
BufferedReader reader = new BufferedReader(
new FileReader("big"+charname+".txt")
);
String line;
StringBuilder buf = new StringBuilder();
while((line = reader.readLine()) != null){
buf.append(line);
buf.append("\n");
}
reader.close();
this.fontdata = buf.toString();
}catch(IOException e){
this.fontdata = charname+"?";
}
}
public void print(){
System.out.print(fontdata);
}
}
big1.txt big2.txt 등의 파일을 읽어서 저장 후 반환해줍니다.
저는 숫자 다하기 좀 그래서 3만 했습니다.
................
....#####.......
..##......##....
..........##....
......####......
..........##....
..##......##....
....#####.......
................
BigCharFactory.java
import java.util.HashMap;
public class BigCharFactory{
private HashMap pool = new HashMap();
private static BigCharFactory singleton = new BigCharFactory();
private BigCharFactory(){}
public static BigCharFactory getInstance(){
return singleton;
}
public synchronized BigChar getBigChar(char charname){
BigChar bc = (BigChar)pool.get(""+charname);
if(bc==null){
bc = new BigChar(charname);
pool.put(charname, bc);
}
return bc;
}
}
getBigChar 함수를 보면 객체가 만들어 진 적이 있다면 HashMap에 등록되어있는 객체를 가져와서 사용합니다.(이패턴의 핵심)
synchronized를 실행 시켜준 이유는 만약에 스레드 A, B가 동시에 돌아가게 된다면 bc가 있는지 확인하고 pool에 넣어주는 행동이 겹칠 수 있어서 그런 문제를 사전에 차단하고자 붙이게 되었습니다.
BigString.java
public class BigString{
private BigChar[] bigchars;
public BigString(String string){
bigchars = new BigChar[string.length()];
BigCharFactory bigcharFactory = BigCharFactory.getInstance();
for(int i = 0; i < bigchars.length; i++)
bigchars[i] = bigcharFactory.getBigChar(string.charAt(i));
}
public void print(){
for(int i = 0; i < bigchars.length; i++)
bigchars[i].print();
}
}
Main.java
import java.io.*;
public class Main{
public static void main(String[] args) throws Exception{
BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
String strname = bfr.readLine();
BigString bs = new BigString(strname);
bs.print();
}
}
출력 결과
BigString.py
from BigFactory import BigFactory
class BigString:
def __init__(self, orders):
self.orders = orders
def getText(self):
for order in self.orders:
factory = BigFactory()
big_char = factory.making(order)
self.result_print(big_char)
def result_print(self, big_char):
print(big_char)
BigFactory.py
객체가 호출 될때 마다 새로운 객체를 만들지 않고 싱글톤 객체를 반환해주고 있습니다.
making 메소드는 기존에 만든 객체가 없다면 만들어서 등록해주고 등록이 되어있으면 새로 만들지 않고 등록된 객체를 호출해준다.
from BigChar import BigChar
class BigFactory:
__singleton = None
def __init__(self):
self.array = {}
def __new__(cls, *args, **kwargs):
if not cls.__singleton:
cls.__singleton = super(BigFactory, cls).__new__(cls, *args, **kwargs)
return cls.__singleton
def making(self, number):
if number not in self.array.keys():
self.array[number] = BigChar(number)
return self.array[number].getBigChar()
BigChar.py
파일을 읽을 떄 마다 txt변수에 등록해준다.
class BigChar:
def __init__(self, number):
self.txt = ""
with open("big" + number + ".txt", 'r') as fp:
lines = fp.read()
for line in lines:
self.txt += line
def getBigChar(self):
return self.txt
main.py
from BigString import BigString
if __name__ == '__main__':
numbers = str(input())
BigString(numbers).getText()