移动架构学习笔记四:简单工厂模式与抽象工厂模式

目录

前言

简单工厂模式

抽象工厂模式

总结

简单工厂模式使用场景:

抽象工厂使用场景:


  • 前言

从今天开始,再次系统学习设计模式。这是第三次学习设计模式,每次学习都会有不一样的收获。为什么要反复学习设计模式呢,打个比方,编程语言就像武功招式,而设计模式就像内功。没有内力修为,再好的武功招式也是花架子,发挥不了最强的威力。而内力不是一朝一夕能练成的,大多靠平时工作中的积累和反复总结。所以每工作多两三年,再回头看看设计模式,从中得到的东西都不一样。今天从工厂模式开始,把简单工厂模式和抽象工厂模式放在一起,比较起来学习。

  • 简单工厂模式

简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

 

简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。

该模式中包含的角色及其职责

工厂(Creator)角色

简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。

抽象产品(Product)角色

简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

具体产品(Concrete Product)角色

是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。

看上面的解释,总是很抽象,不好理解。还是举例说明比较好理解。比如,我们想吃面包该怎么办呢?二话不说,先来一个面包的接口:

public interface IBread {
    void eat();
}

再来一个面包的实现类:

public class Bread implements IBread {

    @Override
    public void eat() {
        System.out.println("原味面包被吃了");
    }
}

 面包有了,怎么个吃法呢?当然第一种选择就是new一个面包直接吃:

//普通用法
IBread bread = new Bread();
bread.eat();

 这样吃面包当然能吃,但是也意味着,我要吃面包,就得自己做。现实情况是我根本不会做面包,我也不想知道面包怎么做的。也就是根据接口隔离原则,我们不应该让吃面包的人必须知道面包是怎么做的。那要怎么做呢,现实情况是我不会做面包,我可以直接去店里面买面包,工厂会直接生成面包。所以我们可以有一个工厂类:

public static IBread create() {
    return new Bread();
}

 当然,工厂肯定不只生成一种面包,工厂生成的面包是多种多样的:

    public static IBread create(int type) {
        switch (type) {
            case 1:
                return new Bread();
            case 2:
                return new CreamBread();
            case 3:
                return new FruitsBread();
            default:
                return new Bread();
        }
    }

 这样,我想要什么面包,告诉工厂就可以了:

       //简单工厂方法并判断类型
        IBread bread3 = BreadFactory.create(2);
        bread3.eat();

 这样就实现了简单工厂模式,优点当然是接口隔离了,用户不用关心面包是怎么生成出来的,直接吃就可以了。但是缺点也很明显,当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利。

也就是面包种类越来越多,用户需要知道工厂生成的多种面包的种类,工厂也要不停的去判断。那要怎么解决这个问题呢?答案就是抽象工厂模式。

  • 抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)隶属于设计模式中的创建型模式,用于产品族的构建。抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。

工厂模式中的每一个形态都是针对一定问题的解决方案,工厂方法针对的是多个产品系列结构;而抽象工厂模式针对的是多个产品族结构,一个产品族内有多个产品系列。

 抽象工厂模式中存在四种角色,分别是抽象工厂角色,具体工厂角色,抽象产品角色,具体产品角色。

抽象工厂角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。

具体工厂角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。 

抽象产品角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。

具体产品角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。

再回到上面的列子,面包厂不是所有种类的面包的生产,我们假设奶油面包厂只生成奶油面包,水果面包厂只生成水果面包。此时我们应该有一个工厂的标准,也就是工厂接口:

public interface IFactory {
    IBread create();
}

 另外有两个具体实现的面包工厂:

public class CreamBreadFactory implements IFactory {
    @Override
    public IBread create() {
        return new CreamBread();
    }
}
public class FruitsBreadFactory implements IFactory {
    @Override
    public IBread create() {
        return new FruitsBread();
    }
}

 奶油面包厂只生成奶油面包,水果面包厂只生成水果面包,用户想吃什么面包就去什么面包厂买就可以了:

public class Client {
    public static void main(String[] args) {
        //生成奶油面包工厂,再有工厂生成奶油面包
        IFactory factory = new CreamBreadFactory();
        factory.create().eat();

        //生成水果面包工厂,再有工厂生成水果面包
        factory = new FruitsBreadFactory();
        factory.create().eat();
    }
}

 这样,就解决了简单工厂中,用户需要知道工厂具体有几种面包的问题,工厂内部也减少了判断。当然抽象工厂模式也有缺点:难以支持新种类的产品。因为抽象工厂接口确定了可以被创建的产品集合,所以难以扩展抽象工厂以生产新种类的产品。

  • 总结

简单工厂模式使用场景:

工厂类负责创建的对象比较少;客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;

由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。

抽象工厂使用场景:

一个系统要独立于它的产品的创建、组合和表示时

一个系统要由多个产品系列中的一个来配置时。

需要强调一系列相关的产品对象的设计以便进行联合使用时。

提供一个产品类库,而只想显示它们的接口而不是实现时。

 

完成案例代码:demo

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值