2008. 10. 6. 21:45

GOF 디자인 패턴 (생성 패턴)


1.    Singleton 패턴

 

목적

n        어떤 객체가 하나만 생성되어 사용되어야 적용

 

 

public class A {

       private static A instance;

      

       private A() {}      // 생성자 제한

       public static synchronized A getInstance() {

             if(instance == null) {

                    instance = new A();

                    return instance;

             }else

                    return instance;                

       }

      

       public static void main(String [] args) {

             A a1 = A.getInstance();

             A a2 = A.getInstance();

            

             if(a1 == a2) {

                    System.out.println(" 객체는 동일합니다.");

             }

       }

}

 

 

2.    Factory Method 패턴

 

목적

n         객체를 생성하기 위한 인터페이스를 정의

n         서브클래스가 어느 클래스를 인스턴스화 할지를 결정

 

 



public abstract class Connection {

       protected String url;

      

       public Connection(String url) {

             this.url = url;

       }

       abstract public void connect();

}

 

class TCPConnection extends Connection {

       public TCPConnection(String url) {

             super(url);

       }

       public void connect() {

             System.out.println(url + " TCP 연결을 시도합니다.");

       }

}

 

class UDPConnection extends Connection {

       public UDPConnection(String url) {

             super(url);

       }

      

       public void connect() {

             System.out.println(url + " UDP 연결을 시도합니다.");

       }

}

 

class HTTPConnection extends Connection {

       public HTTPConnection(String url) {

             super(url);

       }

      

       public void connect() {

             System.out.println(url + " HTTP 연결을 시도합니다.");

       }

}

 

abstract class ConnectionFactory {

       abstract public Connection getConnection(String str);

}

 

class TCPConnectionFactory extends ConnectionFactory {

       public Connection getConnection(String url) {

             return new TCPConnection(url);

       }

}

 

class UDPConnectionFactory extends ConnectionFactory {

       public Connection getConnection(String url) {

             return new UDPConnection(url);

       }

}

 

class HTTPConnectionFactory extends ConnectionFactory {

       public Connection getConnection(String url) {

             return new HTTPConnection(url);

       }

}

 

public class Client {

       public static void main(String[] args) {

             ConnectionFactory factory = new TCPConnectionFactory();

             Connection socket = factory.getConnection("SOCKET://70.12.113.168:5555");

             socket.connect();

            

             ConnectionFactory factory1 = new UDPConnectionFactory();

             Connection datagram = factory1.getConnection("DATAGRAM://70.12.113.168:5555");

             datagram.connect();

            

             ConnectionFactory factory2 = new HTTPConnectionFactory();

             Connection http = factory1.getConnection("HTTP://70.12.113.168:5555");

             http.connect();

       }

}

 

3.    Abstract Factory 패턴

 

목적

n         구체 클래스를 명시하지 않고 관련된 혹은 의존적인 객체의 집합을 생성하기 위한 인터페이스를 제공

n         단순하게 객체 하나를 생성하는 경우보다는 여러 개의 객체를 생성해야 하는 경우에 유용

 

 





 

abstract class Head {

       abstract public void display();

}

 

class CircleHead extends Head {

       public void display() {

             System.out.println("둥근 타입의 머리를 가졌습니다.");

       }

}

 

abstract class Leg {

       abstract public void display();

}

 

class WheelLeg extends Leg {

       public void display() {

             System.out.println("바퀴 타입의 다리를 가졌습니다.");

       }

}

 

abstract class Body {

       abstract public void display();

}

 

class LCDBody extends Body {

       public void display() {

             System.out.println("몸통에는 LCD 화면을 가지고 있습니다.");

       }

}

 

abstract class Arm {

       abstract public void display();

}

 

class FingerArm extends Arm {

       public void display() {

             System.out.println("손가락 팔을 가지고 있습니다.");

       }

}

 

 

 

class Robot {

       private Head head;

       private Body body;

       private Leg leg;

       private Arm arm;

      

       public void addHead(Head head) {

             this.head = head;

       }

       public void addBody(Body body) {

             this.body = body;

       }

       public void addLeg(Leg leg) {

             this.leg = leg;

       }

       public void addArm(Arm arm) {

             this.arm = arm;

       }

       public void displayRobot() {

             System.out.println("완성된 로봇은 다음과 같은 기능을 가지고 있습니다.");

             head.display();

             body.display();

             leg.display();

             arm.display();

       }

}

 

 

 

abstract class RobotFactory {

       abstract public Head createHead();

       abstract public Body createBody();

       abstract public Leg createLeg();

       abstract public Arm createArm();

}

 

class HomeRobotFactory extends RobotFactory {

       public Head createHead() {

             return new CircleHead();

       }

       public Body createBody() {

             return new LCDBody();

       }

       public Leg createLeg() {

             return new WheelLeg();

       }

       public Arm createArm() {

             return new FingerArm();

       }

}

 

 

 

public class Client {

       public static void main(String[] args) {

             Robot homeRobot = new Robot();

             RobotFactory homeFactory = new HomeRobotFactory();

             homeRobot.addHead(homeFactory.createHead());

             homeRobot.addBody(homeFactory.createBody());

             homeRobot.addLeg(homeFactory.createLeg());

             homeRobot.addArm(homeFactory.createArm());

            

             homeRobot.displayRobot();

       }

}

 

 

 

4.    Builder 패턴

 

목적

n         Product 대한 다양한 추가 작업으로 인한 결과값의 변형에 유용

n         하나의 Product 완성하기 위해서 복잡한 작업을 거쳐야 경우에도 유용

 

 




 

 

import java.io.*;

 

abstract class Builder {

       StringBuffer result = new StringBuffer();

      

       public boolean makeFile(String filename) {

             try {

                    FileOutputStream fout = new FileOutputStream(filename);

                    DataOutputStream dout = new DataOutputStream(fout);

                   

                    dout.writeUTF(result.toString());

                    return true;

             }

             catch (Exception e) {

                    return false;

             }

       }

       public abstract String getResult();

       public abstract void makeTitle(String title);

       public abstract void makeAuthor(String author);

       public abstract void makeDate(String date);

       public abstract void makeSubTitle(String subTitle);

       public abstract void makeContext(String context[]);

}

 

 

 

class HTMLBuilder extends Builder {

       public String getResult() {

             result.append("</body></html>");

             return result.toString();

       }

       public void makeTitle(String title) {

             result.append("<html><<head>");

             result.append("<title>" + title + "</title>");

             result.append("</head>");

             result.append("<body>");

             result.append("TITLE : " + title + "<br>");

       }

       public void makeAuthor(String author) {

             result.append("AUTHOR : " + author + "<br>");

       }

       public void makeDate(String date) {

             result.append("DATE : " + date + "<br><hr>");

       }

       public void makeSubTitle(String subTitle) {

             result.append(subTitle + "<br>");

       }

       public void makeContext(String context[]) {

             result.append("<ul>");

             for(int i=0; i<context.length; i++) {

                    result.append("<li>" + context[i] + "</li>");

             }

             result.append("</ul>");

       }

}

 

 

 

class Director {

       private Builder builder;

       private String filename;

      

       public Director(Builder builder, String filename) {

             this.builder = builder;

             this.filename = filename;

       }

       public String construct() {

             builder.makeTitle("Member List");

             builder.makeAuthor("kkang");

             builder.makeDate("2005.12.25");

             builder.makeSubTitle("A++");

             builder.makeContext(new String[]{"홍길동", "김길동", "강길동"});

             builder.makeSubTitle("B++");

             builder.makeContext(new String[]{"길동", "원길동", "정길동"});

             return builder.getResult();

       }

      

       public boolean makeFile() {

             return builder.makeFile(filename);

       }

}

 

 

 

public class Client {

       public static void main(String[] args) {

             Director director = new Director(new HTMLBuilder(), "member.html");

            

             System.out.println(director.construct());

             director.makeFile();

       }

}

 

 

5.    Prototype 패턴

 

목적

n         새로운 객체를 생성할 new 연산자를 사용하지 않고 기존의 객체를 복사하여 이용하는 패턴


 



 



 

class Product implements Cloneable {

       private String name;

       private int price;

      

       public Product(String name, int price) {

             this.name = name;

             this.price = price;

       }

       public Product cloneMe() throws CloneNotSupportedException {

             return (Product) clone();

       }

      

       public String getName() {

             return name;

       }

       public void setName(String name) {

             this.name = name;

       }

       public int getPrice() {

             return price;

       }

       public void setPrice(int price) {

             this.price = price;

       }

}

 

 

 

class Manager {

       private Product product = null;

      

       public Product getProduct() {

             if(product == null) {

                    product = new Product("design pattern", 10000);

                    return product;

             }

             else {

                    try {

                           product = product.cloneMe();

                           return product;

                    } catch (Exception e) {

                           return null;

                    }

             }

       }

}

 

 

 

public class Client {

       public static void main(String[] args) {

             Manager manager = new Manager();

            

             Product product = manager.getProduct();

             System.out.println("name:" + product.getName());

             System.out.println("price:" + product.getPrice());

             System.out.println();

            

             Product product1 = manager.getProduct();

             System.out.println("name:" + product1.getName());

             System.out.println("price:" + product1.getPrice());

             System.out.println();

            

             product1.setName("java programming");

             product1.setPrice(5000);

            

             Product product2 = manager.getProduct();

             System.out.println("name:" + product2.getName());

             System.out.println("price:" + product2.getPrice());

             System.out.println();

       }

}

 

 

참고

1.      삼성 SDS 멀티캠퍼스 교육 과정 – “자바 개발자를 위한 디자인 패턴” (수강 추천)

      2.   StarUML 패턴 관련 도움말.