프로토타입 패턴
프로토타입 패턴은 성능을 보장하면서 반복되는 개체를 만드는 데 사용됩니다. 이러한 유형의 디자인 패턴은 객체를 생성하는 최적의 방법을 제공하는 생성 패턴입니다.
이 패턴은 현재 개체의 복제본을 만드는 데 사용되는 프로토타입 인터페이스를 구현합니다. 이 모드는 객체를 직접 생성하는 비용이 상대적으로 높을 때 사용됩니다. 예를 들어, 비용이 많이 드는 데이터베이스 작업 후에 개체를 생성해야 합니다. 객체를 캐시하고, 다음 요청 시 객체의 복제본을 반환하고, 필요할 때 데이터베이스를 업데이트하여 데이터베이스 호출을 줄일 수 있습니다.
Introduction
의도: 프로토타입 인스턴스를 사용하여 생성할 개체 유형을 지정하고, 이러한 프로토타입을 복사하여 새 개체를 만듭니다.
주요 솔루션: 런타임 중에 프로토타입을 생성하고 삭제합니다.
사용 시기: 1. 시스템이 제품과 독립적으로 생성, 구성 및 표현되어야 하는 경우. 2. 인스턴스화할 클래스가 런타임 시 동적 로딩 등을 통해 지정되는 경우. 3. 제품 클래스 계층 구조와 평행한 공장 클래스 계층 구조 생성을 방지하기 위해. 4. 클래스의 인스턴스가 여러 가지 상태 조합 중 하나만 가질 수 있는 경우. 매번 적절한 상태로 클래스를 수동으로 인스턴스화하는 것보다 해당 수의 프로토타입을 만들고 복제하는 것이 더 편리할 수 있습니다.
해결 방법: 기존 프로토타입 개체를 사용하여 프로토타입 개체와 동일한 인스턴스를 빠르게 생성합니다.
핵심 코드: 1. JAVA에서 Cloneable을 상속하고 .NET에서는 Object 클래스의 MemberwiseClone() 메서드를 사용하여 객체의 얕은 복사본을 구현할 수 있습니다. 직렬화를 통해 딥 카피를 구현합니다. 2. 프로토타입 패턴은 클래스 객체 사용자와 특정 유형(휘발성 클래스) 간의 결합 관계를 분리하는 데에도 사용됩니다. 또한 안정적인 인터페이스를 갖기 위해서는 이러한 "휘발성 클래스"가 필요합니다.
적용 예: 1. 2. JAVA의 객체 clone() 메소드.
장점: 1. 성능이 향상되었습니다. 2. 생성자의 제약 조건을 탈출합니다.
단점: 1. 클래스의 기능에 대한 포괄적인 고려가 필요합니다. 이는 새로운 클래스의 경우 어렵지 않지만, 기존 클래스의 경우 쉽지 않을 수 있습니다. 특히 클래스 참조가 지원되지 않는 경우 더욱 그렇습니다. 직렬화, 간접 객체 또는 참조에 순환 구조가 포함된 경우. 2. Cloneable 인터페이스를 구현해야 합니다. 3. 생성자의 제약 조건을 탈출합니다.
사용 시나리오: 1. 리소스 최적화 시나리오. 2. 클래스 초기화에는 데이터, 하드웨어 리소스 등을 포함한 많은 리소스의 소화가 필요합니다. 3. 성능 및 보안 요구 사항이 있는 시나리오. 4. new를 통해 객체를 생성하는 데 매우 번거로운 데이터 준비나 접근 권한이 필요한 경우 프로토타입 모드를 사용할 수 있습니다. 5. 객체의 여러 수정자가 있는 시나리오. 6. 다른 개체가 개체에 액세스해야 하고 각 호출자가 해당 값을 수정해야 하는 경우 프로토타입 모드를 사용하여 호출자가 사용할 여러 개체를 복사하는 것을 고려할 수 있습니다. 7. 실제 프로젝트에서는 프로토타입 패턴이 단독으로 나타나는 경우가 거의 없으며 일반적으로 팩토리 메소드 패턴과 함께 나타나며, clone 메소드를 통해 객체가 생성된 후 팩토리 메소드에 의해 호출자에게 제공됩니다. 프로토타입 패턴은 Java와 통합되어 누구나 사용할 수 있습니다.
참고: 클래스를 인스턴스화하여 새 개체를 생성하는 것과 달리 프로토타입 패턴은 기존 개체를 복사하여 새 개체를 생성합니다. 얕은 복사는 복제 가능, 다시 쓰기를 구현하고, 전체 복사는 직렬화 가능을 구현하여 바이너리 스트림을 읽습니다.
Implementation
추상 클래스 Shape과 Shape 클래스를 확장하는 엔터티 클래스를 만듭니다. 다음 단계는 Hashtable에 모양 개체를 저장하고 요청 시 해당 개체의 복제본을 반환하는 ShapeCache 클래스를 정의하는 것입니다.
PrototypPatternDemo, 우리의 데모 클래스는 ShapeCache 클래스를 사용하여 Shape 개체를 가져옵니다.
1단계
Clonable 인터페이스를 구현하는 추상 클래스를 만듭니다.
Shape.java
public abstract class Shape implements Cloneable { private String id; protected String type; abstract void draw(); public String getType(){ return type; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Object clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; } }
2단계
위의 추상 클래스를 확장하는 엔터티 클래스를 만듭니다.
Rectangle.java
public class Rectangle extends Shape { public Rectangle(){ type = "Rectangle"; } @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } }
Square.java
public class Square extends Shape { public Square(){ type = "Square"; } @Override public void draw() { System.out.println("Inside Square::draw() method."); } }
Circle.java
public class Circle extends Shape { public Circle(){ type = "Circle"; } @Override public void draw() { System.out.println("Inside Circle::draw() method."); } }
3단계
클래스를 생성하여 데이터베이스에서 엔터티 클래스를 가져와 Hashtable에 저장합니다. .
ShapeCache.java
import java.util.Hashtable; public class ShapeCache { private static Hashtable<String, Shape> shapeMap = new Hashtable<String, Shape>(); public static Shape getShape(String shapeId) { Shape cachedShape = shapeMap.get(shapeId); return (Shape) cachedShape.clone(); } // 对每种形状都运行数据库查询,并创建该形状 // shapeMap.put(shapeKey, shape); // 例如,我们要添加三种形状 public static void loadCache() { Circle circle = new Circle(); circle.setId("1"); shapeMap.put(circle.getId(),circle); Square square = new Square(); square.setId("2"); shapeMap.put(square.getId(),square); Rectangle rectangle = new Rectangle(); rectangle.setId("3"); shapeMap.put(rectangle.getId(),rectangle); } }
4단계
PrototypePatternDemo ShapeCache 클래스를 사용하여 Hashtable에 저장된 모양의 복제본을 가져옵니다.
PrototypePatternDemo.java
public class PrototypePatternDemo { public static void main(String[] args) { ShapeCache.loadCache(); Shape clonedShape = (Shape) ShapeCache.getShape("1"); System.out.println("Shape : " + clonedShape.getType()); Shape clonedShape2 = (Shape) ShapeCache.getShape("2"); System.out.println("Shape : " + clonedShape2.getType()); Shape clonedShape3 = (Shape) ShapeCache.getShape("3"); System.out.println("Shape : " + clonedShape3.getType()); } }
5단계
출력을 확인합니다.
rreee