创建型设计模式-抽象工厂模式

Posted vbirdbest

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建型设计模式-抽象工厂模式相关的知识,希望对你有一定的参考价值。

工厂方法模式的适用的场景

工厂方法模式是一个具体工厂只生产一类产品。现在咖啡店升级了不止买咖啡了也开始卖甜点了,咖啡和甜点是两种不同的产品,如果我们按照工厂方法模式该怎么做呢?

public abstract class Coffee 
    public abstract String getName();

    public void addSugar() 
        System.out.println("Coffee 加糖");
    

    public void addMilk() 
        System.out.println("Coffee 加奶");
    


public class AmericanCoffee extends Coffee 
    @Override
    public String getName() 
        return "美式咖啡(美式风味)";
    


public class LatteCoffee extends Coffee 
    @Override
    public String getName() 
        return "拿铁咖啡(意大利风味)";
    

public interface CoffeeFactory 
    Coffee createCoffee();


public class AmericanCoffeeFactory implements CoffeeFactory 
    @Override
    public Coffee createCoffee() 
        return new AmericanCoffee();
    


public class LatteCoffeeFactory implements CoffeeFactory 
    @Override
    public Coffee createCoffee() 
        return new LatteCoffee();
    

// 甜点父类
public abstract class Dessert 
    public abstract String getName();


public class Trimisu extends Dessert 
    @Override
    public String getName() 
        return "提拉米苏(意大利风味)";
    


public class MatchMousse extends Dessert 
    @Override
    public String getName() 
        return "抹茶慕斯(美式风味)";
    


// 增加一个甜点工厂
public interface DessertFactory 
    Dessert createDessert();


// 增加一个抹茶慕斯工厂
public class MatchMousseDessertFactory implements DessertFactory 
    @Override
    public Dessert createDessert() 
        return new MatchMousse();
    


// 增加一个提拉米苏工厂
public class TrimisuDessertFactory implements DessertFactory 
    @Override
    public Dessert createDessert() 
        return new Trimisu();
    

public class CoffeeStore 

    private CoffeeFactory coffeeFactory;
    // 新增甜点工厂
    private DessertFactory dessertFactory;

    public void setCoffeeFactory(CoffeeFactory coffeeFactory) 
        this.coffeeFactory = coffeeFactory;
    

    public void setDessertFactory(DessertFactory dessertFactory) 
        this.dessertFactory = dessertFactory;
    

    public Coffee orderCoffee() 
        Coffee coffee = coffeeFactory.createCoffee();
        coffee.addMilk();
        coffee.addSugar();
        return coffee;
    
    
    // 增加点甜品功能
    public Dessert orderDessert() 
        Dessert dessert = dessertFactory.createDessert();
        System.out.println("制作甜点");
        return dessert;
    

public class ItalyClient 
    public static void main(String[] args) 
        CoffeeFactory coffeeFactory = new LatteCoffeeFactory();
        // 新增提拉米苏工厂
        DessertFactory dessertFactory = new TrimisuDessertFactory();

        CoffeeStore coffeeStore = new CoffeeStore();
        coffeeStore.setCoffeeFactory(coffeeFactory);
        coffeeStore.setDessertFactory(dessertFactory);

        Coffee coffee = coffeeStore.orderCoffee();
        // 点甜点
        Dessert dessert = coffeeStore.orderDessert();
        System.out.println(coffee.getName());
        System.out.println(dessert.getName());
    

咖啡店新增售卖甜品功能,首先无论使用什么模式Dessert、Trimisu、MatchMousse 三个实体肯定是少不了的,因为增加两个具体的甜品所以也要相应的增加两天具体的甜品工厂MatchMousseDessertFactory、TrimisuDessertFactory,响应的CoffeeStore也要增加orderDessert()方法。现在是增加了2个甜点需要创建2个工厂,如果增加100个甜点就要增加100个工厂类。

客户端需要点拿铁咖啡(意大利风味)和就需要创建两个对应的工厂来创建。
如果我偏好喜欢意大利口味的,那能否只创建一个工厂,这个工厂生产所有意大利口味的东西(咖啡、甜点、面条等)。

抽象工厂要解决的问题

工厂方法模式是一个工厂只生产一种特定的产品,实际社会中很多工厂都会生产多个产品(如咖啡店可能买咖啡、甜点、简餐等)。我们能不能把“一个工厂只生产一种特定产品”再进行抽象一下,让一个工厂可以生产多个产品,并且这个工厂生产的所有产品都有一定的关联性。比如开一个美式风味工厂可以生产美式咖啡、美式甜点、美式简餐,再开一个意大利风味工厂可以生产意大利式咖啡、意大利式甜点、意大利式简餐。这样由原来的工厂方法模式(如果新增100个产品增加100个具体工厂类)就变成了抽象工厂模式(如果新增100个产品,这100个产品只属于美式风味系列和意大利式风味系列,就变成只需要2个工厂类即可)。

工厂方法模式和抽象工厂模式其实就是分类的程度不同,工厂方法模式分类是分的特别细一类产品就属于一个工厂,而抽象工厂模式是以系列作为分类,分类的范围更广泛。

public interface CategoryFactory 
    Coffee createCoffee();
    Dessert createDessert();


// 美式风味工厂
public class AmericanFactory implements CategoryFactory 
    @Override
    public Coffee crateCoffee() 
        return new AmericanCoffee();
    

    @Override
    public Dessert createDessert() 
        return new MatchMousse();
    


// 意大利风味工厂
public class ItalyFactory implements CategoryFactory 
    @Override
    public Coffee crateCoffee() 
        return new LatteCoffee();
    

    @Override
    public Dessert createDessert() 
        return new Trimisu();
    

public class CoffeeStore 
	// 系列工厂
    private CategoryFactory categoryFactory;

    public void setCategoryFactory(CategoryFactory categoryFactory) 
        this.categoryFactory = categoryFactory;
    

    public Coffee orderCoffee() 
        Coffee coffee = categoryFactory.createCoffee();
        coffee.addMilk();
        coffee.addSugar();
        return coffee;
    

    public Dessert orderDessert() 
        Dessert dessert = categoryFactory.createDessert();
        System.out.println("制作甜点");
        return dessert;
    

public class Client 
    public static void main(String[] args) 
        // 只需要创建一个系列工厂,就能获取该系列工厂的所有产品
        CategoryFactory factory = new ItalyFactory();
        Coffee coffee = factory.createCoffee();
        Dessert dessert = factory.createDessert();
    

美式咖啡(AmericanCoffee-美式风味)和拿铁咖啡(LatteCoffee-意大利风味)都属于咖啡(Coffee)。
抹茶慕斯(MatchMousse-美式风味)和 提拉米苏(Trimisu-意大利风味)都属于甜点(Dessert)。

抽象工厂模式是工厂方法模式的升级版本,工厂方法只能生产同一类的对象,而抽象工厂模式可以生产多个种类的对象。

抽象工厂模式是为了解决一系列相关产品的创建。

工厂方法中的工厂类只生产一种对象,而抽象工厂模式中的工厂是生产一系列多种对象。

开发者涨薪指南 48位大咖的思考法则、工作方式、逻辑体系

以上是关于创建型设计模式-抽象工厂模式的主要内容,如果未能解决你的问题,请参考以下文章

创建型模式 抽象工厂

设计模式之抽象工厂模式(创建型)

创建型设计模式——抽象工厂模式

6创建型模式之工厂模式与抽象工厂模式

设计模式01 创建型模式 - 抽象工厂

创建型模式:抽象工厂