본문 바로가기

Programming/Design Pattern

Design pattern - Prototype (디자인패턴 - 프로토타입) / Java C++ C#

 Design pattern - Prototype (디자인패턴 - 프로토타입) / Java C++ C#

 

 

 디자인 패턴 두번째 포스팅으로.. 좀 큼직한걸 시간들여서 쓰고 싶었으나..

귀찮아서 일단 작은거부터 쓰는 중

 

 

 Prototype 패턴이라하면.. 

 

자바에서는 모든 객체의 상위 클래스인 Object 클래스에 기본으로 들어가 있는,

 

clone() 함수로 이 패턴이 쓰인다. 

 

자기 자신 클래스를 복사해서 반환형으로 똑같은 값들을 가진 같은 클래스를 내보낸다.

 

 

 뭐 얕은복사, 깊은복사 이런 소리가 있는데..

 

-> 얕은복사는 보통 heap에 할당된 객체(list) 등을 대표주소값만 복사하여

같은 객체나 값을 공유하고 각기 서로 다른 주소값만 갖고 있는 경우가 된다.

 

-> 깊은복사는 할당된 객체(list) 등이 갖고 있는 값이나 객체들까지도

전부 복사해서 새로 만들어서 아예 같은 해당 객체 한 덩어리를 다 만드는 경우가 된다.

 

예제 코드에서는.. 간단하게 두종류를 다 보긴 할건데.. 

얕은/깊은 이런 이름은 접어두고 그냥 객체 위치나 영역에 맞게 제대로 복사를 해주면 된다.

 

 

 clone() 자체를 길게 쓰기 싫다면, 복사생성자를 따로 만들어서 쓰는게 깔끔하다.

 

 

 

 

 Code... Let me see code!

 코드... 코드를 보자!

 

 

import java.util.LinkedList;

        import java.util.List;



public class TestClass {



    private List<String> stringList = new LinkedList<>();



    private String testString = "Test";

    private int testInteger = 182314;



    /**

     * Constructor

     */

    public TestClass() {

        this.stringList.add("string1");

        this.stringList.add("string2");

        this.stringList.add("string3");

    }



    /**

     * Copy constructor

     * @param source

     */

    public TestClass(TestClass source) {

        for (String val : source.stringList)

        {

            this.stringList.add(new String(val));

        }

        this.testString = source.testString;

        this.testInteger = source.testInteger;

    }



    @Override

    public TestClass clone() {

        return new TestClass(this);

    }



    public TestClass cloneFalse(TestClass source) {

        TestClass newTestClass = new TestClass();



        newTestClass.stringList = source.stringList;

        newTestClass.testString = source.testString;

        newTestClass.testInteger = source.testInteger;



        return newTestClass;

    }



    public void printOutStringList() {

        for (int i = 0; i < this.stringList.size(); ++i)

        {

            System.out.println(this.stringList.get(i));

        }

    }



    public void modifyStringList(int index, String text) {

        this.stringList.remove(index);

        this.stringList.add(index, text);

    }



    public void setTestString(String test) {

        this.testString = test;

    }

    public void setTestInteger(int test) {

        this.testInteger = test;

    }



    public String getTestString() {

        return this.testString;

    }

    public int getTestInteger() {

        return this.testInteger;

    }



    public static void main(String args[]) {



        TestClass testClass1 = new TestClass();

        System.out.println(testClass1.getTestString() + " " + testClass1.getTestInteger());

        testClass1.printOutStringList();



        System.out.println("");



        TestClass testClass2 = testClass1.clone();

        System.out.println(testClass2.getTestString() + " " + testClass2.getTestInteger());

        testClass1.modifyStringList(1, "modify1");

        testClass1.printOutStringList();

        System.out.println("--------------------------------");

        testClass2.printOutStringList();

        testClass2.setTestString("Super");

        testClass2.setTestInteger(100);

        System.out.println(testClass2.getTestString() + " " + testClass2.getTestInteger());



        // Correct copy

        /////////////////////////////////////////////////////////////////////////////////////////////

        // False copy



        System.out.println("\n===================================================\n");



        System.out.println(testClass1.getTestString() + " " + testClass1.getTestInteger());

        testClass1.printOutStringList();



        System.out.println("");



        TestClass testClass3 = testClass1.cloneFalse(testClass1);

        System.out.println(testClass3.getTestString() + " " + testClass3.getTestInteger());

        testClass1.modifyStringList(1, "modify122222");

        testClass1.printOutStringList();

        System.out.println("--------------------------------");

        testClass3.printOutStringList();

        testClass3.setTestString("Super");

        testClass3.setTestInteger(100);

        System.out.println(testClass3.getTestString() + " " + testClass3.getTestInteger());



    }

}

 

 

 

예제에서 눈여겨 볼 포인트는..

 

1. Object 의 clone() 함수를 오버라이딩해서 재정의 해주는데, 복사생성자를 미리 만들거나..

clone() 함수 내에서 복사를 하던가 해서 제대로 복사를 해준다.

 

2. 메인 함수를 확인해보면

 -> === 위의 부분은 제대로 복사 (깊은복사?) 가 되어있는 것을 볼 수 있다.

어떻게 보냐하면.. list 의 string이 각기 별개로 출력된다.

 

 -> === 아래의 부분은 제대로 복사가 안되고 같은 list 를 주소값만 나눠가진 모양새이다.

list 의 string을 출력해보면 -> 한 쪽에서만 바꾸었는데 두군데 값이 다 바뀌었다.

 

3. Prototype의 포인트는 -> 자기자신과 연관은 없지만 내용값이 똑같은 하나를 클론한다.

 

 

 

Something else....

 

 

 

2018/10/11 - [Programming/Design Pattern ] - Design pattern - Singleton (디자인패턴 - 싱글턴)

2018/10/16 - [Programming/Java] - Java enum class 자바 이넘 클래스 (Singleton design pattern 처럼 사용방법)

 

 

2018/10/19 - [Algorithm/Code Signal (Code Fights)] - Aracade Intro #13 ReverseParentheses, Codefights, CodeSignal

2018/10/08 - [Algorithm/Code Signal (Code Fights)] - Aracade Intro #12 SortByHeight

2018/10/06 - [Algorithm/Code Signal (Code Fights)] - Aracade Intro #11 IsLucky