IT박스

디자인 패턴 : 팩토리 vs 팩토리 메소드 vs 추상 팩토리

itboxs 2020. 6. 2. 19:01
반응형

디자인 패턴 : 팩토리 vs 팩토리 메소드 vs 추상 팩토리


웹 사이트에서 디자인 패턴을 읽고있었습니다

거기에서 Factory, Factory method 및 Abstract factory에 대해 읽었지만 혼란스럽고 정의에 명확하지 않습니다. 정의에 따르면

팩토리-인스턴스화 로직을 클라이언트에 노출시키지 않고 객체를 작성하고 공통 인터페이스를 통해 새로 작성된 객체를 참조합니다. Factory Method의 단순화 된 버전입니다

팩토리 메소드-오브젝트를 작성하기위한 인터페이스를 정의하지만 서브 클래스가 인스턴스화 할 클래스를 결정하고 공통 인터페이스를 통해 새로 작성된 오브젝트를 참조하도록합니다.

Abstract Factory-클래스를 명시 적으로 지정하지 않고 관련 객체 패밀리를 작성하기위한 인터페이스를 제공합니다.

또한 Abstract Factory와 Factory Method에 관한 다른 stackoverflow 스레드를 보았지만 거기에 그려진 UML 다이어그램은 이해를 훨씬 더 악화시킵니다.

누구든지 말해줘

  1. 이 세 가지 패턴은 어떻게 다릅니 까?
  2. 언제 사용합니까?
  3. 또한 가능한 경우 이러한 패턴과 관련된 Java 예제가 있습니까?

세 가지 팩토리 유형 모두 동일한 작업을 수행합니다. "스마트 생성자"입니다.

Apple과 Orange라는 두 가지 종류의 과일을 만들 수 있다고 가정 해 봅시다.

공장

팩토리는 "고정"되었습니다. 서브 클래 싱없이 구현이 하나뿐이기 때문입니다. 이 경우 다음과 같은 클래스가 있습니다.

class FruitFactory {

  public Apple makeApple() {
    // Code for creating an Apple here.
  }

  public Orange makeOrange() {
    // Code for creating an orange here.
  }

}

사용 사례 : Apple 또는 Orange를 생성하는 것은 생성자를 처리하기에 너무 복잡합니다.

공장 방법

팩토리 메소드는 일반적으로 클래스에 일반 처리가 있지만 실제로 사용하는 과일의 종류를 변경하려는 경우에 사용됩니다. 그래서:

abstract class FruitPicker {

  protected abstract Fruit makeFruit();

  public void pickFruit() {
    private final Fruit f = makeFruit(); // The fruit we will work on..
    <bla bla bla>
  }
}

FruitPicker.pickFruit()하위 클래스에서 팩토리 메소드를 구현 하여 공통 기능을 재사용 할 수 있습니다 .

class OrangePicker extends FruitPicker {

  @Override
  protected Fruit makeFruit() {
    return new Orange();
  }
}

추상 공장

Abstract factory는 일반적으로 의존성 주입 / 전략과 같은 것들에 사용되는데, "동일한 종류"가 필요하고 몇 가지 공통 기본 클래스를 가진 전체 객체 계열을 만들 수 있기를 원할 때. 다음은 모호한 과일 관련 예입니다. 여기서 유스 케이스는 실수로 Apple에서 OrangePicker를 사용하지 않도록하려는 것입니다. 우리가 같은 공장에서 과일과 피커를 얻는 한, 그들은 일치 할 것입니다.

interface PlantFactory {

  Plant makePlant();

  Picker makePicker(); 

}

public class AppleFactory implements PlantFactory {
  Plant makePlant() {
    return new Apple();
  }

  Picker makePicker() {
    return new ApplePicker();
  }
}

public class OrangeFactory implements PlantFactory {
  Plant makePlant() {
    return new Orange();
  }

  Picker makePicker() {
    return new OrangePicker();
  }
}

  1. 이 세 가지 패턴은 어떻게 다릅니 까?

Factory: Creates objects without exposing the instantiation logic to the client.

Factory Method: Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses

Abstract Factory: Provides an interface for creating families of related or dependent objects without specifying their concrete classes.

AbstractFactory pattern uses composition to delegate responsibility of creating object to another class while Factory method design pattern uses inheritance and relies on derived class or sub class to create object

  1. When to use which?

Factory: Client just need a class and does not care about which concrete implementation it is getting.

Factory Method: Client doesn't know what concrete classes it will be required to create at runtime, but just wants to get a class that will do the job.

AbstactFactory: When your system has to create multiple families of products or you want to provide a library of products without exposing the implementation details.

Abstract Factory classes are often implemented with Factory Method. Factory Methods are usually called within Template Methods.

  1. And also if possible, any java examples related to these patterns?

Factory and FactoryMethod

Intent:

Define an interface for creating an object, but let sub classes decide which class to instantiate. Factory Method lets a class defer instantiation to sub classes.

UML diagram:

enter image description here

Product: It defines an interface of the objects the Factory method creates.

ConcreteProduct: Implements Product interface

Creator: Declares the Factory method

ConcreateCreator: Implements the Factory method to return an instance of a ConcreteProduct

Problem statement: Create a Factory of Games by using Factory Methods, which defines the game interface.

Code snippet:

Factory Pattern. When to use factory methods?

Comparison with other creational patterns:

  1. Design start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed

  2. Abstract Factory classes are often implemented with Factory Methods, but they can also be implemented using Prototype

References for further reading: Sourcemaking design-patterns


Factory - Separate Factory class to create complex object.

Ex: FruitFactory class to create object of Fruit

class FruitFactory{

public static Fruit getFruit(){...}

}

Factory Method - Instead of whole separate class for factory, just add one method in that class itself as a factory.

Ex:

Calendar.getInstance() (Java's Calendar)

Abstract Factory Method - Factory of Factory

Ex: Lets say we want to build factory for computer parts. So there are several types of computers like Laptop, Desktop, Server.

So for each compter type we need factory. So we create one highlevel factory of factories like below

ComputerTypeAbstractFactory.getComputerPartFactory(String computerType) ---> This will return PartFactory which can be one of these ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

Now these 3 itself are again factories. (You will be dealing with PartFactory itself, but under the hood, there will be separate implementation based on what you provided in abstract factory)

  Interface-> PartFactory. getComputerPart(String s), 
Implementations -> ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

Usage:
new ComputerTypeAbstractFactory().getFactory(“Laptop”).getComputerPart(“RAM”)

EDIT: edited to provide exact interfaces for Abstract Factory as per the objections in comments.


Every design pattern thrives to help ensure that written, working code is not touched. We all know that once we touch working code, there are defects in existing working flows, and a lot more testing needs to get done to ensure that we did not break anything.

A factory pattern creates objects based on input criteria, thus ensuring that you dont need to write code like if this then create this kinda object else this kinda object. A good example of this is a travel website. A travel website can only provide travel (flight, train, bus) or / and provide hotels or / and provide tourist attraction packages. Now, when a user selects next, the website needs to decide what objects it needs to create. Should it only create the travel or hotel object too.

Now, if you envision adding another website to your portfolio, and you believe that the same core be used, for example, a carpooling website, which now searches for cab's and makes payments online, you can use a abstract factory at your core. This way you can just snap in one more factory of cabs and carpools.

Both factory's have nothing to do with each other, so its a good design to keep them in different factory's.

Hope this is clear now. Study the website again keeping this example in mind, hopefully it will help. And I really hope I have represented the patterns correctly :).


AbstractProductA, A1 and A2 both implementing the AbstractProductA
AbstractProductB, B1 and B2 both implementing the AbstractProductB

interface Factory {
    AbstractProductA getProductA(); //Factory Method - generate A1/A2
}

Using Factory Method, user can able to create A1 or A2 of AbstractProductA.

interface AbstractFactory {
    AbstractProductA getProductA(); //Factory Method
    AbstractProductB getProductB(); //Factory Method
}

But Abstract Factory having more than 1 factory method ( ex: 2 factory methods), using those factory methods it will create the set of objects/ related objects. Using Abstract Factory, user can able to create A1, B1 objects of AbstractProductA, AbstractProductB


For this answer, I refer to the "Gang of Four" book.

There are no "Factory" nor "Simple Factory" nor "Virtual Factory" definitions in the book. Usually when people are talking about "Factory" pattern they may be talking about something that creates a particular object of a class (but not the "builder" pattern); they may or may not refer to the "Factory Method" or "Abstract Factory" patterns. Anyone can implement "Factory" as he won't because it's not a formal term (bear in mind that some people\companies\communities can have their own vocabulary).

The book only contains definitions for "Abstract Factory" and "Factory Method".

Here are definitions from the book and a short explanation of why both can be so confusing. I omit code examples because you can find them in other answers:

Factory Method (GOF): Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

Abstract Factory (GOF): Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Source of Confusion: Often, one can call a class that used in "Factory Method" pattern as "Factory". This class is abstract by definition. That's why it easy to call this class "Abstract Factory". But it's just the name of the class; you shouldn't confuse it with "Abstract Factory" pattern (class name != pattern name). The "Abstract Factory" pattern is different - it does not use an abstract class; it defines an interface (not necessarily a programming language interface) for creating parts of a bigger object or objects that are related to each other or must be created in a particular way.

참고URL : https://stackoverflow.com/questions/13029261/design-patterns-factory-vs-factory-method-vs-abstract-factory

반응형