'전체 글'에 해당되는 글 678건

  1. 2011.08.13 디자인 패턴
  2. 2011.08.13 [펌]디자인패턴 1부터 9까지 내용 doc문서
  3. 2011.08.13 [펌] The Template Pattern
  4. 2011.08.13 [펌] The Strategy Pattern
한글
http://myhome.naver.com/gmgmgm21/otherdocs.htm

영문
Allan Clarke's Home Page
http://cpptips.hyperformix.com/
http://cpptips.hyperformix.com/Patterns.html


자바소스
http://caic.cnu.ac.kr/youngsik/oop/
http://myhome.hitel.net/~ein0204/study/pattern2.html
http://caic.cnu.ac.kr/youngsik/oop/




1부. 디자인 패턴에 익숙해지다 
1장. Iterator―하나씩 세다 
2장. Adapter―한 꺼풀 덧씌워 재사용 

2부. 하위 클래스에게 맡긴다 
3장. Template Method―구체적인 처리를 하위 클래스에게 맡긴다 
4장. Factory Method―인스턴스 작성을 하위 클래스에게 맡긴다 

3부. 인스턴스를 만든다 
5장. Singleton―단 하나의 인스턴스 
6장. Prototype―복사해서 인스턴스를 만든다 
7장. Builder―복잡한 인스턴스를 조립한다 
8장. Abstract Factory―관련된 부품을 조립해서 제품을 만든다 

4부. 분리해서 생각한다 
9장. Bridge―기능의 계층과 구현의 계층을 분리한다 
10장. Strategy―알고리즘을 모두 교체한다. 

5부. 동일시 
11장. Composite―그릇과 내용물의 동일시 
12장. Decorator―장식과 내용물의 동일시 

6부. 구조 안을 돌아다니다 
13장. Visitor―구조 안을 돌아다니면서 일을 한다 
14장. Chain of Responsibility―책임 떠넘기기 

7부. 간단하게 한다 
15장. Facade―간단한 창구 
16장. Mediator―상대는 카운셀러 한사람뿐 

8부. 상태를 관리한다 
17장. Observer―상태의 변화를 통지한다 
18장. Memento―상태를 보존한다 
19장. State―상태를 클래스로서 표현한다 

9부. 낭비를 없앤다 
20장. Flyweigh―동일한 것을 공유해서 낭비를 없앤다 
21장. Proxy―필요해지면 만든다 

10부. 클래스로 표현한다 
22장. Command―명령을 클래스로 만든다 
23장. Interpreter―문법 규칙을 클래스로 표현한다 


'Development > 패턴자료' 카테고리의 다른 글

[펌]디자인패턴 1부터 9까지 내용 doc문서  (0) 2011.08.13
[펌] The Template Pattern  (0) 2011.08.13
[펌] The Strategy Pattern  (0) 2011.08.13
[펌] The State Pattern  (0) 2011.08.13
[펌] The Singleton Pattern  (0) 2011.08.13
안정적인 DNS서비스 DNSEver DNS server, DNS service
Posted by 키르히아이스
,

아래 있는 자료들이 웹상에 존재하지 않아서 그림이 깨졌네요.

워드 파일로 받아보시면 그림까지 보실 수 있습니다.

 

작성자 : 한국정보통신대학원대학교  이승일

'Development > 패턴자료' 카테고리의 다른 글

디자인 패턴  (0) 2011.08.13
[펌] The Template Pattern  (0) 2011.08.13
[펌] The Strategy Pattern  (0) 2011.08.13
[펌] The State Pattern  (0) 2011.08.13
[펌] The Singleton Pattern  (0) 2011.08.13
안정적인 DNS서비스 DNSEver DNS server, DNS service
Posted by 키르히아이스
,

The Template Pattern

    하나 또는 그 이상의 메소드들을 파생된 클래스에 의해 구현하도록 남기는 부모 클래스를 작성할 때 마다  기본적으로 Template 패턴을 사용한다. Templeate 패턴은 클래스에서 알고리즘을 정의하는 것에 대한 생각을 형식화하지만 서브클래스에서 남겨진 것들에 대해 자세한 구현이 이루어 진다. 바꿔서 말하면 디자인 패턴에서 종종 발생하는 것처럼 base 클래스가 추상 클래스이면 Template 패턴의 간단한 형태를 이용한다.

Motivation

    Template들은 기초적인 것이어서 아마 그것에 관한 생각조차 없이 수 십 번도 더 사용했을 것이다. Template 패턴 이면의 생각은 알고리즘의 몇몇 부분이 잘 정의되고 base 클래스에서 구현될 수 있고 반면에 다른 부분은 파생된 클래스들에 남겨져 구현될 수 있다는 것이다. 또 다른 생각은 여러개의 서브클래스에서 반복되지 않도록 base 클래스에서 만들 수 있는 부분이 있다는 것에 대한 인식이다.

    예를 들어 Strategy 패턴의 예에서 사용했던 PlotPanel 클래스들의 개발에서 우리는 선 그래프나 막대 그래프 모두 데이터를 스케일하는 것과 x 축과 y축을 계산하는 부분이 발견되었다. 

public class PlotPanel extends JPanel {
	float xfactor, yfactor;
	int xpmin, ypmin, xpmax, ypmax;
	float minX, maxX, minY, maxY;
	float x[], y[];
	Color color;
	
	//--------------------------------------------
	public void setBounds(float minx, float miny, float maxx, float maxy) {
		minX=minx;
		maxX= maxx;
		minY=miny;
		maxY = maxy;
	}                                           
	
	//--------------------------------------------
	public void plot(float[] xp, float[] yp, Color c) {
		x = xp;      //copy in the arrays
		y = yp;
		color = c;   //and color
		
		//compute bounds and sclaing factors
		int w = getWidth() - getInsets().left - getInsets().right;
		int h = getHeight() - getInsets().top - getInsets().bottom;
		  
		xfactor = (0.9f * w) / (maxX - minX);
		yfactor = (0.9f * h)/ (maxY - minY);
		
		xpmin = (int)(0.05f * w);
		ypmin = (int)(0.05f * h);
		xpmax = w - xpmin;
		ypmax = h - ypmin;
		repaint();      //this causes the actual plot
	}
그러므로 이러한 메소들은 실제적인 plotting을 할 수 있는 능력 없이 모두 PlotPanel 크래스에 속해있는다. plot 메소드가 상수들을 스케일링하고 repaint() 메소드를 호출하는 걸 주목해 보자. 실제 paint 메소드는 파생된 클래스 까지 연기되어 있다. Jpanel 클래스가 항상 paint 메소드를 가지고 있기 때문에 우리는 base 클래스에서 추상 메소드로 선언하는 걸 원하지 않지만, 파생된 클래스에서 재정의할 필요가 있다.

Kinds of Methods in a Template Class

Template는 파생된 클래스에서 이용할 수 있는 네 가지의 메소드를 가지고 있다 :
  1. 서브클래스들이 사용하고자 하는 모든 기본적인 기능을 수행하는 메소드를 완성한다. 이런 것들은 Concrete methods 라 부른다.
     
  2. 전혀 채워 지지 않은 메소들은 파생 클래스에서 구현해야만 하나. 자바에서는 abstract 메소드로 선언한다.
     
  3. 몇몇 연산에 대하여 기본적인 구현을 포함하는 메소드는 파생 클래스에서 재정의 될 수 있다. 이런 것들을 Hook 메소드라 부른다. 물론 이것은 임의적으로 만들 수 있다.
     
  4. 마지막으로 Template 클래스는 어떤 추상이나 hook나 구체적인 메소드의 조합으로 그들 자체를 부를 수 있는 메소드를 포함할 수 있다.

Sample Code

    스크린 상에 삼각형들을 그리는 프로그램을 생각해 보자. 우리는 추상 Triangle 클래스를 가지고 시작할 것이고 그다음 몇몇 특별한 삼각형을 파생시킬 것이다.

    ##########0*

우리의 추상 Triangle 클래스는 Template 패턴으로 설명된다:

public abstract class Triangle {
	Point p1, p2, p3; 
	
	//---------------------------------------
	public Triangle(Point a, Point b, Point c) {
		//save
		p1 = a; p2 = b; p3 = c;
	}
	
	//---------------------------------------
	public void draw(Graphics g) {
		//This routine draws a general triangle
		drawLine(g, p1, p2);
		Point current = draw2ndLine(g, p2, p3);
		closeTriangle(g, current);
	}
	
	//---------------------------------------
	public void drawLine(Graphics g, Point a, Point b) {
		g.drawLine(a.x, a.y, b.x, b.y);
	}
	//---------------------------------------
	//this routine is the "Hook" that has to be implemented
	//for each triangle type.
	abstract public Point draw2ndLine(Graphics g, Point a, Point b);

	//---------------------------------------
	public void closeTriangle(Graphics g, Point c) {
		//draw back to first point
		g.drawLine(c.x, c.y, p1.x, p1.y);
	}

}
이 Triangle 클래스는 3개의 선의 좌표를 저장하지만, draw 루틴은 단지 첫째와 마지막 선만 그린다. draw2ndLine 메소드는 추상 메소드로 남겨진다. 파생된 클래스는 그리고자 하는 사각형의 종류를 생성하는 세 번째 점으로 이동할 수 있도록 한다.

    이것은 Template 패턴을 이용하는 클래스의 일반적인 예이다. draw 메소드는 두 개의 구체적인 base 클래스 메소드를 호출하고 하나의 추상 메소드를 Triangle로부터 상속 받은 구체적인 클래스에서 구체적으로 재정의 해야 한다.

Drawing a Standard Triangle

    모양에 제한 없이 일반적인 삼각형을 그리기 위해 우리는 간단히 draw2ndLine 메소드를 파생된 stdTrinalgle 클래스에서 구현하였다.   

public class stdTriangle extends Triangle {
	public stdTriangle(Point a, Point b, Point c) {
		super(a, b, c);
	}
	
	public Point draw2ndLine(Graphics g, Point a, Point b) {
		g.drawLine(a.x, a.y, b.x, b.y);
		return  b;
	}
}
Drawing an Isoceles Triangle  

    이 클래스는 세 번째 데이터 포인트를 두 변의 길이가 같도록 새로 계산하고 새로운 점을 저장한다.

public class IsocelesTriangle extends Triangle {
	Point newc;
	int newcx, newcy;
	int incr;
	
	public IsocelesTriangle(Point a, Point b, Point c)    {
		super(a, b, c);
		double dx1 = b.x - a.x;
		double dy1 = b.y - a.y;
		double dx2 = c.x - b.x;
		double dy2 = c.y - b.y;
		
		double side1 = calcSide(dx1, dy1);
		double side2 = calcSide(dx2, dy2);
		
		if (side2 < side1) 
		incr = -1;
		else
		incr = 1;
		
		double slope = dy2 / dx2;
		double intercept = c.y - slope* c.x;
		
		//move point c so that this is an isoceles triangle
		newcx = c.x; newcy = c.y;		
		while(Math.abs(side1 - side2) > 1) {
			newcx += incr;    //iterate a pixel at a time until close
			newcy = (int)(slope* newcx + intercept);
			dx2 = newcx - b.x;
			dy2 = newcy - b.y;
			side2 = calcSide(dx2, dy2);
		}
		newc = new Point(newcx, newcy);
	}
	
	//--------------------------------------
	//calculate length of side
	private double calcSide(double dx, double dy) {
		return Math.sqrt(dx*dx + dy*dy);
	}
Triangle 클래스가 draw 클래스를 호출했을 때 새로운 버젼의 draw2ndLine 메소드를 부르고 새로운 세 번째 점에 선을 그린다. 게다가 삼각형이 정확하게 연결될 수 있도록 새로운 점을 draw 메소드에 반환한다.

	//draws 2nd line using saved new point
	public Point draw2ndLine(Graphics g, Point b, Point c)    {
		g.drawLine(b.x, b.y, newc.x, newc.y);
		return newc;
	}

The Triangle Drawing Program

    메인 프로그램은 간단하게 그리고자하는 삼각형의 인스턴스를 생성한다. 그리고 나서, TPanel의 벡터에 그 인스턴스들을 추가한다.

public class TriangleDrawing extends JxFrame {
	stdTriangle t, t1;
	IsocelesTriangle it;
	
	public TriangleDrawing() {
		super("Draw triangles");
		TPanel tp = new TPanel();
		t = new stdTriangle(new Point(10,10), new Point(150,50), new Point(100, 75));
		it = new IsocelesTriangle(new Point(150,100), new Point(240,40), new Point(175, 150));
		t1 = new stdTriangle(new Point(150,100), new Point(240,40), new Point(175, 150));
		tp.addTriangle(t);
		tp.addTriangle(it);
		 
		getContentPane().add(tp);
		setSize(300, 200);
		setBackground(Color.white);
		setVisible(true);
	}
	
	//=======================================
	public void paint(Graphics g) {
		for (int i = 0; i < triangles.size(); i++) {
			Triangle tngl = (Triangle)triangles.elementAt(i);
			tngl.draw(g);
		}
	}	
	
	
	
	
아래 그림에서 왼쪽은 표준적인 삼각형들을 보여주고 오른쪽은 isoceles 삼각형을 보여주고 있다.

        ##########1*    

Summary and Consequences

    Template 패턴들은 객체지향 소프트웨어에서 상상 발생하고 복잡하거나 분명하지 않는 것을 의도하지 않는다. 이 패턴들은 객체지향 프로그램의 정규적인 부분이고 그것들이 실제적으로 하는 것 보다 더 추상적으로 만들려 할 필요가 없다.

    가장 의미 있는 점은 base 클래스가 메소드들 중 사용될 것은 정의하고 파생 클래스에서 구현할 것은 남겨 둔 다는 것이다. 두 번째는 메소드들의 시퀀스를 부를 수 있는 메소드가 base 클래스에 있을 수 있다는 것이다. Template 메소드는 base 클래스에서 자세한 구현이 완벽하게 이루어지지 않았더라도 일반적인 알고리즘을 정의한다.

    Template 클래스들은 종종 몇 개의 추상 메소드를 가질 수 있고 이 메소드들은 파생된 클래스에서 재정의해야만 한다.

'Development > 패턴자료' 카테고리의 다른 글

디자인 패턴  (0) 2011.08.13
[펌]디자인패턴 1부터 9까지 내용 doc문서  (0) 2011.08.13
[펌] The Strategy Pattern  (0) 2011.08.13
[펌] The State Pattern  (0) 2011.08.13
[펌] The Singleton Pattern  (0) 2011.08.13
안정적인 DNS서비스 DNSEver DNS server, DNS service
Posted by 키르히아이스
,

The Strategy Pattern

    Strategy 패턴은 윤곽은 State 패턴과 많이 비슷하지만 의도하는 목적이 약간 다르다. Strategy 패턴은 Context라 불리는 드라이버 클래스에서 캡슐화된 다수의 관련된 알고리즘들로 구성된다. 클라이언트 프로그램은 다른 알고리즘을 선택하거나 어떤 경우에는 Context가 최상의 알고리즘을 선택할 수 있다. State 패턴과 같이 어떤 조건문의 덩어리 없이 알고리즘들을 쉽게 바꿀 수 있도록 하는 것이 의도이다. 

Motivation

    특별한 서비스나 기능을 요구하는 프로그램과 기능을 수행하는 여러 가지 방법을 가지고 있는 것은 Strategy 패턴의 후보이다. 프로그램들은 컴퓨터 효율이나 사용자 선택을 기준으로 알고리즘을 선택한다.

    우리가 여러 가지 다른 방법으로 같은 일을 하려고 하는 프로그램에서 다수의 경우가 있다.
  • 다른 포멧으로 파일들을 저장한다.
  • 다른 알고리즘을 사용하여 파일들을 압축한다
  • 다른 압축 구조를 이용하여 비디오 데이터를 캡쳐한다.
  • 텍스트 데이터를 나타내기 위한 다른 line-breaking 전략을 이용한다.
  • 같은 데이터를 다른 포멧으로 그린다 : 선 그래프, 막대 그래프 나 파이 차트
    각각의 경우에 우리는 사용할 수 있는 전략들의 드라이버 모듈(Context)를 알려주는 클라이언트 프로그램을 상상할 수 있다.

Sampe Code

선그래프나 막대그래프로 데이터를 표현할 수 있는 간단한 그래픽 프로그램을 고려해 보자. 우리는 추상적인 PlotStrategy 클래스 부터 시작할 것이고 두 개의 플랏팅 클래스들을 파생시킬 것이다.

        ##########0*

    각각의 플랏이 그들 자신의 프레임에서 보여지기 때문에 base PlotStrategy 클래스는 JFrame 으로부터 파생될 것이다 :

public abstract class PlotStrategy extends JFrame {
	protected float[] x, y;
	protected float minX, minY, maxX, maxY;
	protected int width, height;
	protected Color color;
	
	public PlotStrategy(String title) {
		super(title);
		width = 300;
		height =200;
		color = Color.black;
		addWindowListener(new WindAp(this));
	}
	
	//--------------------------------------
	public abstract void plot(float xp[], float yp[]);
	
	//--------------------------------------
	public void setSize(Dimension sz) {
		width = sz.width;
		height = sz.height;
	}
	
	//--------------------------------------
	public void setPenColor(Color c) {
		color = c;
	}
    중요한 부분은 파생된 클래스들이 plot이라 불리는 메소드를 구현해야만 한다는 것이다. 이 클래스들 각각은 적당한 어떤 종류의 플랏이라도 가능하다.

The Context

    Context 클래스는 strategy가 어디에서 호출될 것이가를 결정하는 교통 경찰이다. 결정은 일반적으로 클라이언트 프로그램의 요구에 기인하고 결정할 필요가 있는 Context는 하나의 구체적인 전략이나 다른 을 참조하는 변수를 정한다.

public class Context {
	//this object selects one of the strategies
	//to be used for plotting
	private PlotStrategy plotStrategy;
	float x[], y[];
	
	//---------------------------------
	public Context() { setLinePlot(); }
	
	public void setBarPlot() {plotStrategy = new BarPlotStrategy(); }
	
	public void setLinePlot() { plotStrategy = new LinePlotStrategy(); }
	
	//---------------------------------
	public void plot() {
		plotStrategy.plot(x, y);
	}
	
	//---------------------------------
	public void setPenColor(Color c) {
		plotStrategy.setPenColor(c);
	}
	
	//---------------------------------
	public void readData(String filename) {
		StringTokenizer tok;
		InputFile f = new InputFile(filename);
		Vector xv = new Vector();
		Vector yv = new Vector();
		String s ="";
		//read data into 2 Vectors
		while(s != null) {
			s =f.readLine();   //read a line at a time
			if(s != null) {
				tok = new StringTokenizer(s);  
				xv.addElement(tok.nextToken());   //x data
				yv.addElement(tok.nextToken());   //y data
			}
		}
		
		f.close();
		//copy data into two float arrays
		x = new float[xv.size()];
		y = new float[yv.size()];
		
		for (int i=0; i< xv.size(); i++) {
			x[i] = new Float((String)xv.elementAt(i)).floatValue();
			y[i] = new Float((String)yv.elementAt(i)).floatValue();
		}
	}
}
    Context 클래스는 또한 데이터를 핸들링 하는데 또 다른 책임이 있다. 파일이나 데이터베이스로부터 데이터를 얻거나 Context가 생성될 때 전달한다. 데이터의 양에 의존하여 plot strategies 에 전달되거나 Context는 plot strategies로 그 자체의 인스턴스를 전달할 수 있고 데이터를 가져오는 public 메소드를 제공한다.

The Program Commands

    이 간단한 프로그램은 단지 두 개의 plot을 호출할 수 있는 두 개의 버튼을 가진 패널이다:

        ##########1*

    각각의 버튼들은 정확한 strategy를 정하는 명령 객체이고 Context의 plot 루틴을 호출한다. 예를 들어 아래는 Line graph button 클래스이다 :

public class JGraphButton extends JButton implements Command {
	Context context;
	
	public JGraphButton(ActionListener act, Context ctx) {
		super("Line graph");
		addActionListener(act);
		context  = ctx;
	}
	
	//-------------------------------
	public void Execute() {
		context.setPenColor(Color.red); //set color of plot
		context.setLinePlot();        //set kind of plot
		context.readData("data.txt"); //read the data
		context.plot();               //plot the data
	}
}

The Line and Bar Graph Strategies

두 개의 strategy 클래스들은 많이 비슷하다 : plotting을 위한 윈도우 크기를 정하고 plot 메소드를 호출한다.

public class LinePlotStrategy extends PlotStrategy {
	LinePlotPanel lp;
	
	//--------------------------------------
	public LinePlotStrategy() {
		super("Line plot");
		lp = new LinePlotPanel();
		getContentPane().add(lp);
	}
	
	//--------------------------------------	
	public void plot(float[] xp, float[] yp) {
		x = xp;  y = yp;        //copy in data
		findBounds();           //sets maxes and mins
		setSize(width, height);
		setVisible(true);
		setBackground(Color.white);
		lp.setBounds(minX, minY, maxX, maxY);
		lp.plot(xp, yp, color); //set up plot data
		repaint();              //call paint to plot
	}
}

Drawing Plots in Java

자바 GUI는 event-dirven이기 때문에, 실제적으로 plot 명령 이벤트에 직접 반응하여 화면에 선들을 그리는 루틴을 직접 작성하지 않는다. 대신 이벤트가 호출될 때 plotting을 수행하는 paint 이벤트를 갖는 패널을 제공한다. repaint 메소드는 직접 paint 메소드를 호출할 수 있다.
    우리는 JPanel을 토대로 PlotPanel을 생성하고 그것으로부터 실제적인 선과 막대를 위한 두 개의 클래스를 상속받는다:

        ##########2*

 base PlotPanel 클래스는 윈도우 맞게 데이터를 스케일링하기 위한 공통적인 코드를 포함한다.


public class PlotPanel extends JPanel {
	float xfactor, yfactor;
	int xpmin, ypmin, xpmax, ypmax;
	float minX, maxX, minY, maxY;
	float x[], y[];
	Color color;
	
	//--------------------------------------------
	public void setBounds(float minx, float miny, float maxx, float maxy) {
		minX=minx;
		maxX= maxx;
		minY=miny;
		maxY = maxy;
	}                                           
	
	//--------------------------------------------
	public void plot(float[] xp, float[] yp, Color c) {
		x = xp;      //copy in the arrays
		y = yp;
		color = c;   //and color
		
		//compute bounds and sclaing factors
		int w = getWidth() - getInsets().left - getInsets().right;
		int h = getHeight() - getInsets().top - getInsets().bottom;
		  
		xfactor = (0.9f * w) / (maxX - minX);
		yfactor = (0.9f * h)/ (maxY - minY);
		
		xpmin = (int)(0.05f * w);
		ypmin = (int)(0.05f * h);
		xpmax = w - xpmin;
		ypmax = h - ypmin;
		repaint();      //this causes the actual plot
	}
	
	//--------------------------------------
	protected int calcx(float xp) {
		return (int)((xp-minX) * xfactor + xpmin);
	}
	
	//--------------------------------------
	protected int calcy(float yp) {
		int ypnt = (int)((yp-minY) * yfactor);
		return ypmax - ypnt;
	}

}
    두 개의 파생받은 클래스는 간단하게 두 종류에 대한 paint 메소드를 구현한다. 다음은 선 그림에 대한 코드이다.

public class LinePlotPanel extends PlotPanel {
	//--------------------------------------
	public void paint(Graphics g) {
		int xp = calcx(x[0]);      //get first point
		int yp = calcy(y[0]);
		g.setColor(Color.white);   //flood background
		g.fillRect(0,0,getWidth(), getHeight());
		g.setColor(Color.black);
		
		//draw bounding rectangle
		g.drawRect(xpmin, ypmin, xpmax, ypmax);
		g.setColor(color);
	
		//draw line graph
		for(int i=1; i< x.length; i++) {
			int xp1 = calcx(x[i]);
			int yp1 = calcy(y[i]);
			g.drawLine(xp, yp, xp1, yp1);
			xp = xp1;
			yp = yp1;
		}
	}

}
    아래의 그림은 최종적인 두 개의 plot이다 :

##########3*##########4*

Consequences of the Strategy Pattern

    Strategy는 동적으로 여러 알고리즘들 중의 하나를 선택할 수 있다. 이러한 알고리즘들은 상속관계와 관련될 수 있거나 공통적인 인터페이스를 구현하여 관련이 없을 수도 있다. Context는 요청에 대한 strategy들을 교체하는 것이므로 요구되는 파생 클래스를 간단하게 호출할 수 있다면 좀더 유연해 질 수 있다. 이 접근은 또한 일기 힘들고 유지하기 힘든 조건 문장들을 피할 수 있다.

    반면에 strategy들은 모든 것을 숨기지 않는다. 클라이언트 코드는 다수의 대안 적인 전략들이 있어야 하고 그들 중 선택에 대한 기준이 있어야 한다. 이것은 클라이언트 프로그래머나 사용자에게 알고리즘적인 결정으로 옮겨진다.

'Development > 패턴자료' 카테고리의 다른 글

[펌]디자인패턴 1부터 9까지 내용 doc문서  (0) 2011.08.13
[펌] The Template Pattern  (0) 2011.08.13
[펌] The State Pattern  (0) 2011.08.13
[펌] The Singleton Pattern  (0) 2011.08.13
[펌] The Proxy Pattern  (0) 2011.08.13
안정적인 DNS서비스 DNSEver DNS server, DNS service
Posted by 키르히아이스
,