[GOF]
- 공유를 통한 많은 수의 소립 객체들을 효과적으로 지원
[ 실용주의 디자인패턴 ]
- 메모리 사용량을 줄이기 위해 외부 상태(상태정보 저장, 계산)를 사용하거나
공유(객체의 복사본 대신 단일 객체에 대한 다중 참조를 이용)한다.
- 무엇을 하느냐에 의해 정의, 즉 메소드에 의해 정의됨
▶ 즉 공유하는 객체를 이용하되 상태 정보를 외부 객체가 따로 관리
■ 사용 예
- game of life를 단순하게 구현할때 '셀'이 살아있는가?는 주변 상태를 참조를 지니고 있어야된다. 1024*1024를 표현하려해도 40mb가 필요함
flywieght를 사용하면 동일한 상태를 지닌 객체가 단 하나의 객체를 통해 표현
■ 장/단점
- 장점 : flyweight를 사용하지 않으면 객체지향적으로 구현하기가 힘듬
- 장점 : flyweight 풀을 이용하면 자바의 == 연산자로 객체의동일성 여부를 결정 할 수 있다.
- 단점 : 외부상태가 계산되는 값이라면(매번 데이터베이스에 접근) 하면 접근이 느릴 수 있다.
- 단점 : 코드가 복잡해짐, 유지보수를 어렵게하고 코드가 커질 수 있음
■ 코드 예제
쉬운 예>
ElementStyle e = new ElementStyle;
e.setMargin(ElementStyleFactory.createMargin(10,10,20,10)); -> 객체는 공유하되 외부 객체가 따로 관리 되도록
게임프로그래밍 패턴예제(js로 구현)>
[origin]<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>flyweight origin</title> </head> <body> 경량패턴??<br> 어떤 객체의 수가 너무 많아 좀 가볍게 만들고 싶을때 사용<br> 고유상태와 외부상태로 나눔<br> <br> 예제 : 지형 만들기<br> 타일(고유상태)과 각 타일들이 갖고 있는 정보(외부상태)<br> <script> function Terrain(kind){ return { "TERRAIN_CLASS" : "TERRAIN_CLASS", "TERRAIN_HILL" : "TERRAIN_HILL", "TERRAIN_RIVER" : "TERRAIN_RIVER" }[kind]; } function World(){ this.tiles = {}; } World.prototype.getMovementCost = function(x,y){ return { "TERRAIN_CLASS" : 1, "TERRAIN_HILL" : 2, "TERRAIN_RIVER" : 3 }[this.tiles[x][y]]; }; World.prototype.getIsWater = function(x,y){ return { "TERRAIN_CLASS" : false, "TERRAIN_HILL" : false, "TERRAIN_RIVER" : true }[this.tiles[x][y]]; }; World.prototype.setTile = function(x,y, value){ this.tiles = this.tiles||{}; this.tiles[x] = this.tiles[x]||{}; this.tiles[x][y] = this.tiles[x][y]||""; this.tiles[x][y] = value; }; function Main(){ var world = new World; var terrain_class = Terrain("TERRAIN_CLASS"); var terrain_hill = Terrain("TERRAIN_HILL"); var terrain_river = Terrain("TERRAIN_RIVER"); world.setTile(1,1,terrain_class) ; world.setTile(1,2,terrain_hill) ; world.setTile(1,3,terrain_river) ; console.log(world.getIsWater(1,3)); console.log(world.getMovementCost(1,2)); } window.onload = function(){ Main(); } </script> </body> </html>
[fly weight]
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>flyweight </title> </head> <body> 경량패턴??<br> 어떤 객체의 수가 너무 많아 좀 가볍게 만들고 싶을때 사용<br> 고유상태와 외부상태로 나눔<br> <br> 예제 : 지형 만들기<br> 타일(고유상태)과 각 타일들이 갖고 있는 정보(외부상태)<br> <script> function Terrain(movementCost, isWater, texture){ var movementCost_; var isWater_; var texture_; function _Terrain(){ this.movementCost_ = movementCost; this.isWater_ = isWater; this.texture_ = texture; } _Terrain.prototype.getMovementCost = function(){ return this.movementCost_; }; _Terrain.prototype.isWater = function(){ return this.isWater_; }; _Terrain.prototype.getTexture = function(){ return this.texture_; }; if(!(this instanceof _Terrain )){ return new _Terrain(); } } var CONST_GLASS_TEXTURE = "GLASS_TEXTURE"; var CONST_HILL_TEXTURE = "HILL_TEXTURE"; var CONST_RIVER_TEXTURE = "RIVER_TEXTURE"; var CONST_WIDTH = 10; var CONST_HEIGHT = 12; function World(){ var tiles = {}; function _World(){ this.glassTerrain_ = [1,false,CONST_GLASS_TEXTURE]; this.hillTerrain_ = [2,false,CONST_HILL_TEXTURE]; this.riverTerrain_ = [3,true,CONST_RIVER_TEXTURE]; this.tiles = tiles; } _World.prototype.setTile = function(x,y, value){ this.tiles = this.tiles||{}; this.tiles[x] = this.tiles[x]||{}; this.tiles[x][y] = this.tiles[x][y]||""; this.tiles[x][y] = value; }; _World.prototype.getTile = function(x,y){ return Terrain.apply(this, this.tiles[x][y]); }; _World.prototype.generateTerrain = function(){ for(var x=0; x < CONST_WIDTH; x++) { for(var y=0; y < CONST_HEIGHT; y++){ if(x % 2 == 0){ this.setTile.apply(this, [x,y,this.glassTerrain_]); }else{ this.setTile.apply(this, [x,y,this.hillTerrain_]); } if(y % 3 == 1){ this.setTile.apply(this, [x,y,this.riverTerrain_]); } } } }; if(!(this instanceof _World )){ return new _World(); } } function Main(){ var world = World(); world.generateTerrain(); console.dir(world.getTile(1,1).getMovementCost()); } window.onload = function(){ Main(); } </script> </body> </html>