3개의 핵심 창조적인 본을 이해하십시오

소프트웨어 디자인 패턴은 반복 설계 문제를 해결하기위한 전투 테스트 블루 프린트입니다. 가장 자주 사용되는 중에는 생성 패턴 - 싱글 톤, 공장 및 프로토 타입 - 각 개체가 즉석인지를 지배합니다. 올바른 하나의 직접적인 영향 코드 유지, 성능 및 확장성. 이 확장 가이드는 각 패턴으로 깊은 다이빙을 확장하고 실제 시나리오를 탐구하고, 당신이 알 수 있는 결정을 내릴 수 있도록 행동 가능한 기준을 제공합니다.

싱글톤 패턴: 규칙에 한 인스턴스 모두

Singleton 패턴은 클래스가 정확히 하나의 인스턴스를 보장하고 글로벌 액세스 포인트를 제공합니다. 그것은 가장 간단한 패턴 중 하나입니다, 그러나 그것은 종종 잘못된다. 핵심 아이디어는 몇 번 클래스가 요청되지 않는 방법을 중요하지 않는 즉시 프로세스를 제어하는 것입니다, 같은 객체가 반환됩니다.

Singleton 작동 방법

일반적으로 Singleton 클래스는 인스턴스를 반환하는 개인 구성자 및 정적 방법을 가지고 있습니다. 첫 번째 호출은 객체를 만듭니다. 이후 호출은 동일한 인스턴스를 재사용합니다. 다중 스레드 환경에서 동기화는 여러 인스턴스를 만들 수있는 인종 상태를 방지해야합니다.

public class DatabaseConnectionPool {
 private static DatabaseConnectionPool instance;
 private DatabaseConnectionPool() { /* initialization */ }
 public static synchronized DatabaseConnectionPool getInstance() {
 if (instance == null) {
 instance = new DatabaseConnectionPool();
 }
 return instance;
 }
}

싱글톤 시일

  • 수업 공유 자원: 연결 풀, 로깅 서비스, 또는 구성 관리자 혜택의 단일 지점에서 조정.
  • Global state: 응용 프로그램 전체 캐시 또는 레지스트리가 일관된 접근을 필요로 할 때.
  • Hardware 또는 OS-level 리소스: 파일 시스템, 프린터 스풀러 또는 창 관리자는 일반적으로 하나의 인스턴스만 허용한다.

피하기 위해 일반적인 Pitfalls

  • Overuse: Singleton을 사용하여 모든 것이 숨겨진 의존성을 갖게 되고, 쉽게 모의 인스턴스를 대체할 수 없기 때문에 단위 테스트를 합니다.
  • Thread-safety overhead: 고전적인 동기화 방법은 Bottleneck이 될 수 있습니다. eager 초기화 또는 이중 검사 잠금과 같은 대안 (휘발성) 콘텐츠 감소.
  • Tight 커플링: 글로벌 액세스 포인트가 하드 코딩이기 때문에, 클라이언트는 콘크리트 싱글턴 클래스에 결합되어, 종속 원칙을 위반.

이 단점에도 불구하고 Singleton은 실제로 단일, 글로벌 접근 가능한 객체가 필요할 때 유용합니다. 더 깊은 이해를 위해 ]Guru의 Singleton Guide]를 참조하십시오.

공장 패턴 : 개체 생성 위임

공장 패턴은 객체의 순간 논리를 캡슐화, 즉석으로 클래스를 결정하는 클래스를 허용. 그것은 두 가지 주요 맛에 온다: 공장 방법 (새로운 개체를 반환하는 단일 방법) 및 Abstract Factory] (관련 공장 방법의 가족). 두 두 콘크리트 클래스에서 클라이언트 코드를 분리, 느슨한 커플링 및 확장을 촉진.

공장 방법 상세

오브젝트를 만들기위한 인터페이스를 정의하지만, 하위 클래스는 생성 될 객체의 유형을 변경할 수 있습니다. 예를 들어, 대화 형 클래스는 메소드 가있을 수 있습니다. WindowsDialog 및 LinuxDialog와 같은 서브 클래스는이 방법을 통해 플랫폼 별 버튼을 반환합니다.

abstract class Dialog {
 abstract Button createButton();
 public void render() {
 Button okButton = createButton();
 okButton.onClick();
 }
}
class WindowsDialog extends Dialog {
 Button createButton() { return new WindowsButton(); }
}

이 본은 때 이상적입니다:

  • 클래스는 객체의 클래스를 생성해야 할 수 없습니다.
  • 객체 생성 논리를 한 곳에서 로컬로 변환합니다.
  • 시스템은 개체가 어떻게 구성되는지 독립적으로해야합니다.

Abstract Factory: 관련 개체의 가족을 생산

Abstract Factory는 콘크리트 클래스를 지정하지 않고 관련 또는 의존 개체의 가족을 만드는 인터페이스를 제공합니다. 주어진 테마 (예 : 재료, Cupertino)에서 일관성있는 보이기 위해 버튼, 체크 박스 및 스크롤 바를 생성해야하는 GUI 툴킷의 생각. 클라이언트는 제품을 얻기 위해 초록색 공장 인터페이스를 사용하고 콘크리트 공장 (MaterialFactory, CupertinoFactory)는 올바른 변형을 생성합니다.

이 본은 다음을 선호합니다:

  • 시스템은 여러 가족의 제품으로 구성되어야 합니다.
  • 제품 중 일관성을 시행하고 싶습니다.
  • 새 제품 가족 추가는 기존 코드에 최소 변경이 필요합니다.

공장과 다른 본 사이 결정

공장은 객체 생성이 복잡하거나 실행시에 구현을 교환 할 때 이동입니다. 그것은 단지 생성을 중앙화하기 때문에 단일 톤보다 더 유연합니다. Prototype과는 달리, 공장은 기존의 하나 복사보다 스크래치에서 새로운 인스턴스를 만듭니다. 두 변종의 포괄적 인 개요를 위해 Guru의 공장 방법 페이지 및 [] [[Fract]]]] 공장 :[Fract]] 공장 :[Fract]] 공장 :[Fractical]] 공장 :[Fractical]] 공장 :[Fractical]

Prototype 패턴 : Construct 대신 복제

Prototype 패턴은 기존 객체를 복사하여 새로운 객체를 만듭니다. 즉, 프로토타입이 비싸면 특히 값이 비싸면 (예 : 무거운 데이터베이스 쿼리, 복잡한 형상 계산) 또는 객체 구성이 시간 소모 될 때 유용합니다. 스크래치에서 건물 대신 미리 구성된 인스턴스를 복제하고 필요에 따라 tweak을 추가합니다.

Cloning Mechanics : Shallow 대. 깊은 복사

대부분의 프로그래밍 언어는 내장 복제 방법을 제공합니다 (] Java, ] Python, 또는 JavaScript에 확산). 그러나 주의는 복사가 얕은 (매우 독립적으로 mutable 객체에 대한 참조) 또는 깊은 (매우 독립적으로)인지 여부를 지불해야합니다. 심층 복사는 복제에 의해 참조 된 모든 개체를 복제합니다. Prototype을 구현하면, 당신은 사용의 레벨을 결정해야합니다.

class MazePrototype {
 public MazePrototype clone() throws CloneNotSupportedException {
 return (MazePrototype) super.clone(); // shallow copy
 }
}

Prototype에 대한 이상적인 시나리오

  • Costly object create: 예를 들어, 파일에서 큰 구성을 로딩하거나 복잡한 기하학적 메쉬를 생성한다.
  • Dynamic runtime object: 시스템의 경우, 실행 시간에 결정되는 새로운 객체를 생성해야 (예를들면, 사전 정의 템플릿에서 스파게이되는 게임의 적 유형).
  • 미래 폭발을 감소: 약간의 변이를 위한 많은 subclasses를 창조하는 대신, 당신은 시제품을 복제하고 몇몇 재산을 조정합니다.

Prototype Registry 및 캐싱

Prototype을 키로 색인을 붙인 미리 만들어진 프로토 타입의 중앙 저장소를 구현하여 단계가 더 걸릴 수 있습니다. 클라이언트는 키로 프로토 타입을 요청하고, 그것을 복제합니다. 레지스트리를 가진 Prototype의 조합은 특정 경우에 공장 또는 Singleton에 경량 대안으로 봉사 할 수 있습니다. 자세한 walkthrough를 위해 ]Guru의 Prototype 가이드를 참조하십시오.

측 측 측 측향 비교: Singleton, 공장, Prototype

선택해주려면, 아래 표는 주요 차이점을 강조합니다.

PatternInstance CountCreation MechanismBest For
SingletonExactly oneSelf-managed global accessShared resources, global state
FactoryMultiple instances (or families)Centralized creation logicDecoupling client from concrete classes, complex creation
PrototypeMultiple instances cloned from a templateCloning (shallow/deep copy)Expensive instantiation, runtime object generation

패턴 오버랩 또는 Combine 때

  • Singleton + Factory: 공장은 Singleton (예: 플랫폼당 1개의 추상 공장)이 될 수 있습니다. 이는 중앙화 된 창조와 글로벌 액세스를 결합합니다.
  • Prototype + Factory: 프로토 타입 레지스트리가 공장으로 작동할 수 있는 프로토 타입 대신 생성자를 호출할 수 있습니다. 이것은 특히 게임 개발에서 스파킹 엔티티티가 될 때 유용합니다.
  • Prototype + Singleton: 프로토 타입 객체는 타입에 따라 하나의 프로토 타입 인스턴스가 존재한다는 의미에서 Singleton이 될 수 있지만, 복제가 싱글톤이 아닙니다.

Practical Decision Framework의 개발

창조 패턴을 호출하는 디자인 문제를 직면 할 때, 주문에 이러한 질문을:

  1. 응용 프로그램 전반에 정확히 하나의 인스턴스가 필요합니까?] 예, Singleton을 고려하면 됩니다. 그러나 전 세계적으로 공유된 상태가 실제로 필요한지 확실하며, 테스트 능력이 겪지 않을 것입니다.
  2. Is 오브젝트 생성 복잡하거나 변경할 가능성이 있습니까? 예, 공장 방법 또는 추상 공장 사용. 이 새로운 개체 유형 추가를 기대할 때 특히 도움이 됩니다.
  3. Is 객체는 성능 Bottleneck을 생성하거나 약간 다른 많은 인스턴스를 필요로합니까?] 예가 있다면 Prototype은 템플릿을 복제하여 시간과 메모리를 절약 할 수 있습니다.
  4. ]하나 이상의 패턴을 동시에 사용할 수 있습니까?]거래-오프를 평가합니다. 예를 들어, Flyweight 패턴은 목표가 immutable 데이터를 공유하는 경우 Prototype 대신 메모리를 줄일 수 있습니다.

Real-World 예제 엔지니어링 소프트웨어

엔지니어링 응용 프로그램은 종종이 패턴을 혼합합니다. CAD 시스템은 사용자 선호 관리자에 대한 단일 톤을 사용할 수 있으며, 다양한 형상 (circle, polygon, spline) 및 복잡한 조립을 복제하기위한 프로토 타입 및 수정할 수 있습니다. 시뮬레이션 엔진은 다양한 해결사 개체를 만들 수 있으며, 입자 시스템 구성을 복사하기위한 프로토 타입, 모든 시뮬레이션 단계를 기록하는 로깅 서비스에 대한 단일 톤.

결론 : 패턴을 해보지 마십시오. 당신의 디자인

단일톤, 공장 및 Prototype은 기초 제작 패턴이지만, 그들은 실버 탄알이 아닙니다. 가장 좋은 선택은 시스템의 제약을 이해하는 데 나타납니다 : 인스턴스 제어, 객체 생성의 복잡성 및 새로운 인스턴스의 비용. 항상 패턴 순도에 명확성과 테스트 가능성을 선호합니다. 의심 할 여지없이, 공장과 시작하면 가장 깨끗한 디코딩을 제공하고 Prototype 또는 Singleton으로 교체하거나 증강 할 수 있습니다.

이 세 가지 패턴을 마스터함으로써 강력한 유연한 엔지니어링 소프트웨어를 구축하기위한 다양한 툴킷을 갖추고 있습니다. 자세한 내용을 보려면 소프트웨어 디자인 패턴 ] ]의 Guru 개요를 참조하십시오.