Prototype Pattern (프로토타입 패턴)이란
Copy and change rather than creating with new;
Creating with new is costly;
Copy general properties, and change necessary part;
Prototype is a creational design pattern that lets you copy existing objects without making your code dependent on their classes.
Problem
Say you have an object, and you want to create an exact copy of it. How would you do it? First, you have to create a new object of the same class. Then you have to go through all the fields of the original object and copy their values over to the new object.
Nice! But there’s a catch. Not all objects can be copied that way because some of the object’s fields may be private and not visible from outside of the object itself.
개체가 있다고 가정하면 개체의 정확한 복사본을 만들 수 있습니다. 그걸 어떻게 하시겠어요? 먼저 같은 클래스의 새 개체를 만들어야 합니다. 그런 다음 원래 개체의 모든 필드를 살펴보고 해당 값을 새 개체로 복사해야 합니다.
좋네! 하지만 함정이 있어. 개체의 필드 중 일부가 private 필드이고 개체 자체 외부에서 표시되지 않을 수 있기 때문에 일부 개체를 이러한 방식으로 복사할 수 없습니다.
There’s one more problem with the direct approach. Since you have to know the object’s class to create a duplicate, your code becomes dependent on that class. If the extra dependency doesn’t scare you, there’s another catch. Sometimes you only know the interface that the object follows, but not its concrete class, when, for example, a parameter in a method accepts any objects that follow some interface.
직접적인 접근법에 한 가지 문제가 더 있습니다. 복제를 만들려면 개체의 클래스를 알아야 하므로 코드가 해당 클래스에 종속됩니다. 즉, 의존도가 너무 높아진다. 경우에 따라 객체가 따르는 인터페이스만 알 수 있지만 구체적인 클래스는 알 수 없는 경우가 있습니다. 예를 들어, 메소드의 매개 변수가 일부 인터페이스를 따르는 개체를 허용할 때 그렇습니다.
Solution
The Prototype pattern delegates the cloning process to the actual objects that are being cloned. The pattern declares a common interface for all objects that support cloning. This interface lets you clone an object without coupling your code to the class of that object. Usually, such an interface contains just a single clone method.
The implementation of the clone method is very similar in all classes. The method creates an object of the current class and carries over all of the field values of the old object into the new one. You can even copy private fields because most programming languages let objects access private fields of other objects that belong to the same class.
An object that supports cloning is called a prototype. When your objects have dozens of fields and hundreds of possible configurations, cloning them might serve as an alternative to subclassing.
프로토타입 패턴은 cloning 프로세스를 복제 중인 실제 개체로 위임합니다. 이 패턴은 복제를 지원하는 모든 개체에 대해 공통 인터페이스를 선언합니다. 이 인터페이스를 사용하면 코드를 해당 개체의 클래스에 연결하지 않고 개체를 복제할 수 있습니다. 일반적으로 이러한 인터페이스는 단일 클론 메서드를 포함합니다.
복제 방법의 구현은 모든 클래스에서 매우 유사합니다. 메소드는 현재 클래스의 개체를 만들고 이전 개체의 모든 필드 값을 새 개체로 전달합니다. 대부분의 프로그래밍 언어에서는 개체가 동일한 클래스에 속하는 다른 개체의 개인 필드에 액세스할 수 있기 때문에 개인 필드를 복사할 수도 있습니다.
복제를 지원하는 개체를 프로토타입이라고 합니다. 개체에 수십 개의 필드와 수백 개의 가능한 구성이 있는 경우 이를 복제하는 것이 하위 분류의 대안으로 작용할 수 있습니다.
Structure
- The Prototype interface declares the cloning methods. In most cases, it’s a single clone method.
- The Concrete Prototype class implements the cloning method. In addition to copying the original object’s data to the clone, this method may also handle some edge cases of the cloning process related to cloning linked objects, untangling recursive dependencies, etc.
- The Client can produce a copy of any object that follows the prototype interface.
1. 프로토타입 인터페이스는 복제 방법 (Cloning Method)을 선언합니다. 대부분의 경우 단일 복제 방법입니다.
2. 콘크리트 프로토타입 클래스는 복제 방법을 구현합니다. 이 방법은 원래 개체의 데이터를 복제본에 복사하는 것 외에도 연결된 개체 복제, 재귀 종속성 제거 등과 관련된 복제 프로세스의 일부 에지 사례를 처리할 수도 있습니다.
3. 클라이언트는 프로토타입 인터페이스를 따르는 모든 객체의 복사본을 만들 수 있습니다.
How to Implement
1. Create the prototype interface and declare the clone method in it.
2. A prototype class must define the alternative constructor that accepts an object of that class as an argument. The constructor must copy the values of all fields defined in the class from the passed object into the newly created instance.
3. The cloning method usually consists of just one line: running a new operator with the prototypical version of the constructor. Note, that every class must explicitly override the cloning method and use its own class name along with the new operator.
4. Optionally, create a centralized prototype registry to store a catalog of frequently used prototypes.
Pros and Cons
Pros
- You can clone objects without coupling to their concrete classes.
- You can get rid of repeated initialization code in favor of cloning pre-built prototypes.
- You can produce complex objects more conveniently.
- You get an alternative to inheritance when dealing with configuration presets for complex objects.
Cons
- Cloning complex objects that have circular references might be very tricky.
Compare Prototype Pattern with Singleton Pattern
프로토타입 패턴 vs 싱글톤 패턴
Singleton and Prototype patterns fall under Creational Design Patterns which deal with object creation.
Singleton - The purpose of a Singleton pattern is to ensure that one and only instance of the class is present at any time. We usually create the instance of the object on demand i.e. delay loading and then ensure that once it is created, no more instances are allowed to be created.
A classical example would be a menu in a Windows application. The menu is common to all pages so we ensure it is not recreated again and again.
The basic fundamental of a singleton is to have a class with a private constructor and expose a static getter property which will control the object creation; upon initial access, the object has to be created and then for subsequent access, the same object is returned. For thread safety purposes, we can use a lock.
Prototype pattern - The intent behind the usage of a Prototype pattern is for creation of an object clone.
The cloning again falls under two categories: shallow and deep. A shallow copy is returned by using MemberwiseClone .Net method. A shallow copy copies only the elements, whether they are reference types or value types, but it does not copy the objects that the references refer to. The references in the new object point to the same objects that the references in the original object points to. In contrast, a deep copy of an object copies the elements and everything directly or indirectly referenced by the elements.
Singleton Pattern 및 Prototype Pattern은 객체 생성을 다루는 생성 디자인 패턴에 해당합니다.
Singleton - Singleton 패턴의 목적은 언제든지 클래스의 하나뿐인 인스턴스가 있는지 확인하는 것입니다. 우리는 일반적으로 요청 시 객체의 인스턴스(예: 로드 지연)를 생성한 다음 생성 후 더 이상 인스턴스를 생성할 수 없도록 합니다.
일반적인 예로는 Windows 응용 프로그램의 메뉴가 있습니다. 메뉴는 모든 페이지에 공통적이므로 반복 재생성되지 않도록 보장합니다.
싱글톤의 기본적인 기본은 개인 생성자를 가진 클래스가 있고 객체 생성을 제어하는 정적 게터 속성을 노출시키는 것이다. 초기 액세스 시 객체를 생성하고 이후 액세스를 위해 동일한 객체가 반환된다. Thread safety을 위해 lock를 사용할 수 있습니다.
According to the GoF a singleton aims to:
“Ensure a class only has one instance, and provide a global point of access to it”
So, there are 2 requirements for a class to be a singleton:
- Having a unique instance
- Being accessible from anywhere
Using this way, the singleton instance is created only once when the class is loaded by the classloader.
When do you need to use a singleton?
- When you need only one resource (a database connection, a socket connection …)
- To avoid multiple instances of a stateless class to avoid memory waste
- For business reasons
You shouldn’t use singleton for sharing variables/data between different objects since it produces a very tight coupling!
Prototype Pattern - 프로토타입 패턴의 사용 배경은 객체 클론을 만드는 것입니다.
복제는 다시 ShallowClone (ShallowCopy)과 DeepClone (DeepCopy)의 두 가지 범주에 속한다. MemberwiseClone을 사용하면 ShallowCopy가 반환됩니다. ShallowCopy은 참조 유형 또는 값 유형에 관계없이 value만 복사하지만 참조가 참조하는 개체는 복사하지 않습니다. 새 개체의 참조는 원래 개체의 참조가 가리키는 것과 동일한 개체를 가리킵니다. 이와는 대조적으로, 오브젝트의 DeepCopy는 구성요소와 구성요소에 의해 직접 또는 간접적으로 참조되는 모든 것을 복사합니다.
When to use prototypes?
According to the Gof, the prototype should be used:
- when a system should be independent of how its products are created, composed, and represented
- when the classes to instantiate are specified at run-time, for example, by dynamic loading
- to avoid building a class hierarchy of factories that parallels the class hierarchy of products
- when instances of a class can have one of only a few different combinations of state. It may be more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually, each time with the appropriate state.
- 시스템의 생성, 구성 및 표현 방법에 독립적이어야 할 때
- 인스턴스화할 클래스가 런타임에 동적 로드에 의해 지정된 경우
- 제품의 계층구조와 병행하는 factories의 계층구조 구축을 피하다
- 클래스의 인스턴스는 상태의 몇 가지 다른 조합 중 하나만 가질 수 있습니다. 매번 적절한 상태로 클래스를 수동으로 인스턴스화하는 것보다 해당 수의 프로토타입을 설치하고 복제하는 것이 더 편리할 수 있습니다.
Prototype and Singleton Scope
Prototype scope = A new object is created each time it is injected/looked up. It will use new SomeClass() each time.
Singleton scope = (Default) The same object is returned each time it is injected/looked up. Here it will instantiate one instance of SomeClass and then return it each time.
Shallow Copy vs Deep Copy
Shallow Copy 얕은 복사
- 하지만, a[1] 에 값을 변경하면 b[1]도 따라 변경됩니다.
같은 주소를 참조하고 있기 때문에 value를 바꾸면 두 객체 모두에 영향을 줌.
Deep Copy 깊은 복사
- 깊은 복사는 내부에 객체들까지 모두 새롭게 copy 되는 것입니다.
- copy.deepcopy메소드가 해결해줍니다.
'공부 > Object-Oriented Design Pattern' 카테고리의 다른 글
Facade Pattern (퍼사드 패턴)이란 (0) | 2021.05.21 |
---|---|
Visitor Pattern Double Dispatch (방문자 패턴 더블 디스패치란) (0) | 2021.05.19 |
Visitor Pattern (방문자 패턴)이란 (0) | 2021.05.11 |
Factory Method Pattern (팩토리 메소드 패턴) (0) | 2021.05.07 |
MVC vs Observer Pattern (MVC 패턴과 옵저버 패턴 차이점) (0) | 2021.05.04 |
댓글