public class Restuarant{ public ???? orderBuger(String request){ if("BEEF".equals(request)){ BeefBurger burger = new BeefBurger(); burget.prepare(); return burger; }else if("VEGGIE".equals(request)){ VeggieBurger burger = new VeggieBurger(); burget.prepare(); return burger; } } }
We can extract common foods then have a standard factory below. It extracts common methods from the BeefBurger and VeggieBurger classes, reducing duplicated methods.
Static Factory Method (Simple Factory)
is not a full-fledged offical pattern
Implementation Uses a single class with a static method to create different types of objects based on input parameters.
Use Case Use the Simple Factory pattern when you have a limited number of classes to instantiate and do not expect the set of classes to change frequently.
UML
classDiagram
class Restaurant{
+ Burger orderBurger()
}
class SimpleBurgetFactory{
+ Burger createBurget()
}
class Burger {
+ int productId
+ String addOns
+ prepare()
}
class BeefBurger {
+ boolean angus
+ prepare()
}
class VeggieBurger {
+ boolean combo
+ prepare()
}
Burger <|-- beefburger burger <|-- veggieburger <.. simpleburgetfactory restaurant < div>
implements
1 2 3 4 5 6 7 8 9 10 11
public class SimpleBurgetFactory{ public Burger orderBuger(String request){ if("BEEF".equals(request)){ BeefBurger burger = new BeefBurger(); }else if("VEGGIE".equals(request)){ VeggieBurger burger = new VeggieBurger(); } burget.prepare(); return burger; } }
public class Restaurant{ public Burger orderBuger(String request){ Burger burger = createBurget(); burget.prepare(); return burger; } public abstract Burget createBurget(); }
public class BeefBurgetRestaurant extends Restaurant{ @Override public Burget createBurget(){ return new BeefBurger(); } }
public class VeggieBurgetRestaurant extends Restaurant{ @Override public Burget createBurget(){ return new VeggieBurger(); } }
public interface Burger{ void prepare(); }
public class BeefBurger implements Burger{ void prepare(){} }
public class VeggieBurger implements Burger{ void prepare(){} }
/** 原来的代码没有, 可以尝试这种方式更好*/ public class Store{ privste Restaurant factory; public Store(Restaurant factory){ this.factory = factory; } public orderBuger(String request){ factory.orderBuger(request) } }
public static void main(String[] args) { BeefBurgetRestaurant beefResto = new BeefBurgetRestaurant(); Burger beefBurger = beefResto.orderBurget();
VeggieBurgetRestaurant veggieResto = new VeggieBurgetRestaurant(); Burger beefBurger = veggieResto.orderBurget(); }
Use the Abstract Factory pattern when a system needs to be independent of how its objects are created, composed, and represented.
It is useful when a system needs to support multiple families of products.
Implementation:
so A single factory is not enough, The Abstract Factory pattern involves multiple factory methods to create a set of related objects.
It defines an interface for creating all the objects in a family, and each concrete factory implements this interface to create specific types of objects.
The class I drew below is not very clear, so I only drew the ConcreateFactory part
classDiagram
class AbstractFactory {
+createProductA(): AbstractProductA
+createProductB(): AbstractProductB
}
class ConcreteFactory1 {
+createProductA(): AbstractProductA
+createProductB(): AbstractProductB
}
class ConcreteFactory2 {
+createProductA(): AbstractProductA
+createProductB(): AbstractProductB
}
class AbstractProductA {
+operationA(): void
}
class ConcreteProductA1 {
+operationA(): void
}
class ConcreteProductA2 {
+operationA(): void
}
class AbstractProductB {
+operationB(): void
}
class ConcreteProductB1 {
+operationB(): void
}
class ConcreteProductB2 {
+operationB(): void
}
AbstractFactory <|-- concretefactory1 abstractfactory <|-- concretefactory2 abstractproducta <|..concreteproducta1 <|..concreteproducta2 abstractproductb <|..concreteproductb1 <|..concreteproductb2 *.. concreteproducta1 concreteproductb1 < div>
public abstract class Company { public abstract Gpu createGpu(); public abstract Monitor createMonitor(); }
public class AsusManufacturer extends Company { @Override public Gpu createGpu() { return new AsusGpu(); } @Override public Monitor createMonitor() { return new AsusMonitor(); } }
public class MsiManufacturer extends Company {
@Override public Gpu createGpu() { return new MsiGpu(); }
@Override public Monitor createMonitor() { return new MsiMonitor(); }
}
public static void main(String[] args) {
Company msi = new MsiManufacturer(); Company asus = new AsusManufacturer();
Scope: The Factory Method is used for creating a single product, while the Abstract Factory is used for creating families of related products.
Complexity: The Abstract Factory pattern is more complex than the Factory Method pattern because it involves multiple factory methods to create a set of related objects.
Inheritance vs. Composition: The Factory Method pattern uses inheritance to let subclasses decide which class to instantiate, while the Abstract Factory pattern uses composition to create families of related objects. but I think I think there isn’t much difference.