ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

设计模式3之抽象工厂模式

2021-04-12 11:54:29  阅读:159  来源: 互联网

标签:手环 工厂 抽象 产品 设计模式 小米 public


抽象工厂模式定义

工厂方法模式中工厂只负责同类产品的生产。比如电视机工厂不应该生产汽车。

然而现实生活中有很多综合型的工厂,比如有些电视工厂不仅生产电视机,还会生产与之配套的机顶盒。

那么抽象工厂模式随之诞生,这种模式将考虑多种类型产品的生产。

我们总结下:

  • 工厂方法模式只考虑成产同一等级级的产品
  • 抽象方法模式考虑生产多等级的产品,可以说是工厂方法模式的升级版

图片


如上图,小米音响和苹果音响为同一个产品。而小米手机和小米音响为同一产品族。

使用场景

那么什么情况下可以使用抽象工厂模式?

使用抽象工厂模式一般要满足以下条件。

  • 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
  • 系统一次只可能消费其中某一族产品,即同族的产品一起使用。

抽象工厂模式同工厂方法模式结构一样,需要抽象产品,抽象工厂,具体产品,具体工厂4部分组成。

结构图如下:

图片

实现代码

这个图你可能看着头晕,我们用代码来表示:

首先创建抽象工厂AbstractFactory

public interface AbstractFactory {
    Product1 newProduct1();
    Product2 newProduct2();
}

然后在创建两个抽象产品

/**
 * 手机
 */
public interface Product1 {
    void show();
}

/**
 * 音响
 */
public interface Product2 {
    void show();
}

然后创建具体产品

public class ConcreteProduct11 implements Product1 {
    @Override
    public void show() {
        System.out.println("具体产品11显示【小米-手机】...");
    }
}

public class ConcreteProduct12 implements Product1 {
    @Override
    public void show() {
        System.out.println("具体产品12显示【苹果-手机】...");
    }
}

public class ConcreteProduct21 implements Product2 {
    @Override
    public void show() {
        System.out.println("具体产品21显示【小米-音响】...");
    }
}

public class ConcreteProduct22 implements Product2 {
    @Override
    public void show() {
        System.out.println("具体产品22显示【苹果-音响】...");
    }
}

再创建具体工厂ConcreteFactory1用来生产小米产品【小米-手机,小米-音响】

/**
 * Description: 小米工厂
 *
 * @author Lvshen
 * @since JDK 1.8
 */
public class ConcreteFactory1 implements AbstractFactory {
    public Product1 newProduct1() {
        System.out.println("具体工厂 1 【小米工厂】 生成-->具体产品 11...");
        return new ConcreteProduct11();
    }
    public Product2 newProduct2() {
        System.out.println("具体工厂 1 【小米工厂】 生成-->具体产品 21...");
        return new ConcreteProduct21();
    }
}

ConcreteFactory1用来生产苹果产品【苹果-手机,苹果-音响】

/**
 * Description: 苹果工厂
 *
 * @author Lvshen
 * @since JDK 1.8
 */
public class ConcreteFactory2 implements AbstractFactory {
    public Product1 newProduct1()
    {
        System.out.println("具体工厂 2 【苹果工厂】生成-->具体产品 12...");
        return new ConcreteProduct12();
    }
    public Product2 newProduct2()
    {
        System.out.println("具体工厂 2 【苹果工厂】生成-->具体产品 22...");
        return new ConcreteProduct22();
    }
}

测试

我们使用小米工厂,生产小米手机

@Slf4j
public class FactoryTest {
    @Test
    public void test() {
        ConcreteFactory1 concreteFactory1 = new ConcreteFactory1();
        Product1 product1 = concreteFactory1.newProduct1();
        product1.show();
    }
}

测试结果

图片

我们再来用苹果工厂生产苹果音响

@Slf4j
public class FactoryTest {
    @Test
    public void test() {
        ConcreteFactory2 concreteFactory = new ConcreteFactory2();
        Product2 product = concreteFactory.newProduct2();
        product.show();
    }
}

测试结果

图片

关于抽象工厂模式的思考

当新增一条产品族时,只需要新增一个工厂即可。比如新增华为手机,华为音响,我们就需要需新增华为工厂。

如果新增新产品等级的产品,那么就需要修改工厂。假如我们新增了手环产品,比如小米手环,苹果手环,华为手环。那么,每个工厂都需要修改。这并不满足闭开原则。

我们再总结下什么情况下会使用抽象工厂模式:

  • 系统中有多个产品族,但每次只使用其中的某一族产品。比如我就喜欢专门使用小米的手机和手环
  • 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构

同工厂模式一样,抽象工厂模式的优点在于,我们不需要知道产品是如何创建的。要获取产品对象,通过工厂就可以获取。做到了很好的封装。

如果产品族类的产品与产品之间存在约束,比如小米手环和小米手机有一定的约束【小米手环需要与小米手机配对才能激活小米手环(这里我瞎说,只是举个栗子)】。那么可以在小米工厂内做出约束,用户并不需要知道内部如如何约束。

我们再来列举一个使用场景

如一个文本编辑器和一个图片处理器,都是软件实体,但是Linux下的文本编辑器和Windows下的文本编辑器虽然功能和界面都相同,但是代码实现是不同的,图片处理器也有类似情况。也就是具有了共同的约束条件:操作系统类型。于是我们可以使用抽象工厂模式,产生不同操作系统下的编辑器和图片处理器。


标签:手环,工厂,抽象,产品,设计模式,小米,public
来源: https://blog.51cto.com/u_15127545/2700944

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有