디자인 패턴 - 프로토타입 패턴의 상세 설명

머리말

  • 디자인 패턴 소개
  • 디자인 패턴은 소프트웨어 개발에서 흔히 발생하는 문제에 대한 솔루션으로, 연습과 경험을 통해 요약된 재사용 가능한 디자인 아이디어이자 솔루션입니다. 디자인 패턴은 일반적인 구조, 원칙 및 지침을 제공하여 개발자가 고품질 코드를 보다 효율적으로 작성하는 데 도움이 됩니다.
    디자인 패턴은 세 가지 주요 범주로 나뉩니다.
  1. 생성 패턴: 객체 인스턴스화 방법, 객체 생성 세부 정보 숨기기, 객체 복사 및 복제 방법 등 객체 생성 프로세스에 중점을 둡니다.
  2. 구조적 패턴: 클래스 간의 관계와 같은 더 큰 구조의 목표를 달성하기 위해 객체와 클래스가 결합되는 방식에 중점을 둡니다.
  3. 행동 패턴: 더 나은 협업과 제어를 달성하기 위해 클래스와 개체가 상호 작용하고 통신하는 방식에 중점을 둡니다.
  • 프로토타입 패턴 소개
    프로토타입 패턴은 객체 복사 및 복제에 중점을 둔 생성 패턴의 한 유형입니다. 경우에 따라 기존 인스턴스화를 통해 새 객체를 생성하는 것은 엄청나게 비용이 많이 들고 복잡할 수 있습니다. 이때 프로토타입 패턴은 기존 객체를 복제하여 새 객체를 생성하는 대체 방법을 제공하므로 비용이 많이 드는 초기화 프로세스를 피할 수 있습니다.

프로토타입 패턴은 복제 방법을 사용하여 새로운 객체를 생성함으로써 자원과 시간을 절약하고 객체 생성 효율성을 향상시킬 수 있습니다. 유사한 객체를 많이 생성해야 하는 시나리오에 적합하며, 확장성도 좋고 필요에 따라 복제 방식을 상속하고 재정의하여 맞춤형 복제 로직을 구현할 수 있습니다.

정리하자면 프로토타입 패턴은 기존 객체를 복제하여 새로운 객체를 생성하는 디자인 패턴이다. 이는 개체를 생성하는 유연하고 효율적인 방법을 제공하여 특정 시나리오에서 코드 재사용성과 유지 관리성을 크게 향상시킬 수 있습니다.
여기에 이미지 설명을 삽입하세요.

이론적 기초

1. 프로토타입 패턴 정의

프로토타입 패턴은 전통적인 인스턴스화 프로세스에 의존하지 않고 기존 객체를 복제하여 새로운 객체를 생성할 수 있도록 하는 생성 디자인 패턴입니다. 이 패턴은 기존 객체의 속성과 상태를 복사하여 새로운 독립 객체를 생성하며, 필요에 따라 해당 객체의 특정 속성을 수정할 수 있습니다.

프로토타입 패턴에서는 객체 복제를 위한 추상 메소드를 포함하는 추상 프로토타입 클래스를 정의합니다. 구체적인 프로토타입 클래스는 추상 프로토타입 클래스를 상속하고 복제 메서드를 구현하여 자신의 복제된 복사본을 반환합니다. 클라이언트 코드는 구체적인 프로토타입 클래스의 인스턴스를 사용하고 해당 복제 메서드를 호출하여 새 개체를 만듭니다.

프로토타입 패턴의 핵심 아이디어는 처음부터 새로운 인스턴스화 프로세스를 시작하는 것이 아니라 기존 객체에서 새로운 객체를 생성하는 것입니다. 기존 개체를 복제하면 반복적인 초기화 작업과 리소스 소비를 방지하고 개체 생성 효율성을 높일 수 있습니다. 동시에 프로토타입 모드에서는 객체 생성이 더욱 유연해지며 필요에 따라 수정 및 사용자 정의가 가능합니다.

2. 프로토타입 역할

  • 추상 프로토타입 클래스
  • 구체적인 프로토타입 클래스
  • 고객

3. 프로토타입 모드의 작업 과정

4. 프로토타입 패턴의 장점과 단점

실용적인 응용 프로그램

1. 프로토타입 모드의 적용 가능한 시나리오

  • 객체 초기화 프로세스에 더 많은 시간이 소요됨
  • 클래스 초기화는 많은 리소스를 소비합니다.
  • new를 통해 객체를 생성하는 것이 더 복잡합니다.
  • 초기 구성을 위해 클래스의 하위 클래스 사용을 피해야 함

2. 프로토타입 패턴 구현 단계

  • 추상 프로토타입 클래스 생성
  • 구체적인 프로토타입 클래스 만들기
  • 클라이언트 클래스 생성

3. 프로토타입 패턴과 싱글톤 패턴의 차이점

프로토타입 패턴의 변형

1. 프로토타입 관리자를 사용한 프로토타입 패턴

  • 프로토타입 관리자가 포함된 프로토타입 패턴:
    프로토타입 관리자가 포함된 프로토타입 패턴은 프로토타입 패턴의 확장으로, 프로토타입 객체를 중앙에서 관리하기 위해 프로토타입 관리자(Prototype Manager)를 도입합니다. 프로토타입 관리자는 다양한 프로토타입 객체를 저장하고 검색하는 레지스트리 역할을 합니다.

프로토타입 패턴의 이 변형을 사용하면 다양한 유형의 여러 프로토타입 객체를 더 쉽게 생성하고 관리할 수 있습니다. 클라이언트는 clone 메소드를 명시적으로 호출하지 않고도 프로토타입 관리자를 통해 필요한 프로토타입 객체를 얻을 수 있습니다. 프로토타입 관리자는 내부적으로 프로토타입 개체 컬렉션을 유지 관리하고 필요에 따라 이를 복사하고 반환할 수 있습니다.

  • 프로토타입 관리자를 사용한 프로토타입 패턴 코드 구현:
import java.util.HashMap;
import java.util.Map;

// 原型接口
interface Prototype {
    
    
    Prototype clone();
}

// 具体原型类 A
class ConcretePrototypeA implements Prototype {
    
    
    private String name;

    public ConcretePrototypeA(String name) {
    
    
        this.name = name;
    }

    public String getName() {
    
    
        return name;
    }

    @Override
    public Prototype clone() {
    
    
        return new ConcretePrototypeA(this.name);
    }
}

// 具体原型类 B
class ConcretePrototypeB implements Prototype {
    
    
    private int number;

    public ConcretePrototypeB(int number) {
    
    
        this.number = number;
    }

    public int getNumber() {
    
    
        return number;
    }

    @Override
    public Prototype clone() {
    
    
        return new ConcretePrototypeB(this.number);
    }
}

// 原型管理器
class PrototypeManager {
    
    
    private Map<String, Prototype> prototypes;

    public PrototypeManager() {
    
    
        prototypes = new HashMap<>();
    }

    public void registerPrototype(String key, Prototype prototype) {
    
    
        prototypes.put(key, prototype);
    }

    public Prototype getPrototype(String key) {
    
    
        Prototype prototype = prototypes.get(key);
        if (prototype != null) {
    
    
            return prototype.clone();
        }
        return null;
    }
}

// 客户端
public class Main {
    
    
    public static void main(String[] args) {
    
    
        PrototypeManager manager = new PrototypeManager();
        manager.registerPrototype("A", new ConcretePrototypeA("Prototype A"));
        manager.registerPrototype("B", new ConcretePrototypeB(10));

        Prototype prototypeA = manager.getPrototype("A");
        if (prototypeA != null) {
    
    
            System.out.println("Clone A: " + ((ConcretePrototypeA) prototypeA).getName());
        }

        Prototype prototypeB = manager.getPrototype("B");
        if (prototypeB != null) {
    
    
            System.out.println("Clone B: " + ((ConcretePrototypeB) prototypeB).getNumber());
        }
    }
}

2. 게으른 싱글턴 패턴의 프로토타입 패턴 구현

  • 게으른 싱글톤 패턴의 프로토타입 패턴:
    게으른 싱글톤 패턴은 싱글톤 패턴을 구현하는 일반적인 방법으로, 싱글톤 개체가 처음 생성될 때까지 인스턴스화를 지연합니다. 게으른 싱글톤 패턴과 프로토타입 패턴을 결합하면 게으른 로딩 및 인스턴스 재사용 패턴을 얻을 수 있습니다.

이 프로토타입 패턴 변형에서는 싱글톤 객체가 프로토타입 객체 역할을 하며 클라이언트가 처음 인스턴스를 요청할 때 복제를 통해 객체의 복사본을 얻어 싱글톤 객체로 반환합니다. 그 후에는 각 요청에서 이 기존 복사본을 반환하여 반복적인 생성 및 초기화 프로세스를 방지합니다.

이 구현 방법은 지연 로딩과 개체 재사용을 결합하고 새 개체를 동적으로 생성하고 필요할 때 캐시하여 시스템 성능과 리소스 활용도를 향상시킬 수 있습니다.

  • 게으른 싱글톤 패턴의 프로토타입 패턴 코드 구현:
// 单例类
class Singleton {
    
    
    private static Singleton instance;

    // 私有构造函数
    private Singleton() {
    
    
        System.out.println("Singleton instance created.");
    }

    // 获取单例对象
    public static Singleton getInstance() {
    
    
        if (instance == null) {
    
    
            synchronized (Singleton.class) {
    
    
                if (instance == null) {
    
    
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

    // 克隆方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
    
    
        throw new CloneNotSupportedException("Cannot clone a singleton object.");
    }
}

// 客户端
public class Main {
    
    
    public static void main(String[] args) {
    
    
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();

        System.out.println("Singleton 1: " + singleton1);
        System.out.println("Singleton 2: " + singleton2);

        // 尝试克隆单例对象
        try {
    
    
            Singleton clone = (Singleton) singleton1.clone();
            System.out.println("Clone: " + clone);
        } catch (CloneNotSupportedException e) {
    
    
            System.out.println(e.getMessage());
        }
    }
}

3. 세분화된 프로토타입 모드

  • 세분화된 프로토타입 패턴:
    세분화된 프로토타입 패턴은 복잡한 개체를 여러 부분으로 분할하고 각 부분에 해당하는 프로토타입 개체를 만드는 것을 의미합니다. 이런 방식으로 특정 부분을 사용해야 할 경우 복잡한 개체 전체를 복제하는 대신 해당 부분의 프로토타입 개체만 복제하면 됩니다.

세분화된 프로토타입 제작 패턴은 시스템 유연성과 효율성을 향상시킬 수 있습니다. 이를 통해 클라이언트는 전체 개체를 복제하지 않고도 복제에 필요한 부분을 선택할 수 있습니다. 동시에 특정 부분이 변경되면 전체 객체를 다시 만들지 않고 해당 프로토타입 객체만 수정하면 됩니다.

이 패턴은 여러 구성 요소나 모듈로 구성된 복잡한 개체에 적합합니다. 세분화된 프로토타입 개체를 통해 복잡한 개체의 구성 요소를 보다 유연하게 구성하고 수정할 수 있으므로 코드 중복과 결합이 줄어듭니다.

  • 세분화된 프로토타입 패턴 코드
// 原型接口
interface Prototype {
    
    
    Prototype clone();
}

// 具体原型类 A
class ConcretePrototypeA implements Prototype {
    
    
    private String name;

    public ConcretePrototypeA(String name) {
    
    
        this.name = name;
    }

    public String getName() {
    
    
        return name;
    }

    @Override
    public Prototype clone() {
    
    
        return new ConcretePrototypeA(this.name);
    }
}

// 具体原型类 B
class ConcretePrototypeB implements Prototype {
    
    
    private int number;

    public ConcretePrototypeB(int number) {
    
    
        this.number = number;
    }

    public int getNumber() {
    
    
        return number;
    }

    @Override
    public Prototype clone() {
    
    
        return new ConcretePrototypeB(this.number);
    }
}

// 客户端
public class Main {
    
    
    public static void main(String[] args) {
    
    
        Prototype prototypeA = new ConcretePrototypeA("Prototype A");
        Prototype cloneA = prototypeA.clone();
        if (cloneA instanceof ConcretePrototypeA) {
    
    
            System.out.println("Clone A: " + ((ConcretePrototypeA) cloneA).getName());
        }

        Prototype prototypeB = new ConcretePrototypeB(10);
        Prototype cloneB = prototypeB.clone();
        if (cloneB instanceof ConcretePrototypeB) {
    
    
            System.out.println("Clone B: " + ((ConcretePrototypeB) cloneB).getNumber());
        }
    }
}

요약하다

  • 프로토타입 모드 사용 요약
  • 소프트웨어 개발을 위한 프로토타입 패턴의 중요성
// 抽象原型类
abstract class Prototype implements Cloneable {
    
    
    public abstract Prototype clone();
}

// 具体原型类
class ConcretePrototype extends Prototype {
    
    
    @Override
    public Prototype clone() {
    
    
        try {
    
    
            return (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
    
    
            e.printStackTrace();
            return null;
        }
    }
}

// 客户端
public class Client {
    
    
    public static void main(String[] args) {
    
    
        ConcretePrototype prototype = new ConcretePrototype();
        ConcretePrototype clone = (ConcretePrototype) prototype.clone();
        // 进行操作
    }
}

위 코드는 프로토타입 패턴의 간단한 구현을 보여줍니다. 추상 프로토타입 클래스는 추상 메소드 clone을 정의하고, 이는 구상 프로토타입 클래스에서 구현되며, 객체는 super.clone() 메소드를 호출하여 복제됩니다. 클라이언트에서는 프로토타입 개체를 생성하고 이를 복제하여 작업을 위한 새 개체를 얻을 수 있습니다.

프로토타입 모드는 유사한 개체를 많이 생성해야 하는 시나리오에 적합하며, 기존 개체를 복제하여 효율성을 높일 수 있습니다. 이는 객체 생성 프로세스를 단순화하고 반복되는 초기화 작업을 줄입니다. 동시에 프로토타입 모드는 확장성도 뛰어나며, 복제 메소드를 상속하고 재정의하여 사용자 정의 복제 로직을 구현할 수 있습니다.

일반적으로 프로토타입 패턴은 소프트웨어 개발에서 폭넓은 활용 가치를 갖는 간단하고 실용적인 디자인 패턴이다. 프로토타입 패턴을 합리적으로 사용함으로써 코드의 재사용성, 유지보수성, 유연성을 향상시켜 소프트웨어 개발의 효율성과 품질을 향상시킬 수 있습니다.

추천

출처blog.csdn.net/pengjun_ge/article/details/132591678