设计模式(一)——工厂模式

1、概念

代码编写出来是为了给别人(Client)调用的:

  • 调用者(client)跟代码编写者(provider),可能是同一个人,也可能是不同的人
  • 提供给调用者的代码,有可能是源码可见的,也可能是源码不可见、不可修改的(比如 jar 包)。

所以,为了简化代码的协作使用及管理维护,必须想尽办法简化代码逻辑,实现必要的【分离】。下面我分别介绍几种工厂模式。

2、最原始的工厂模式

我们使用手机来作为测试,首先上代码图:

public class Iphone {
    public void call () {}
}
public class Huawei {
    public void call () {}
}
public class Oppo{}
public class XiaoMi {}
public class Vivo {}

最原始的方式:如果我们要创建多个不同品牌的手机, 那么就要 new 多个不同品牌的手机类,如果这样的代码提供给客户端调用,必须要将所有类的名称以及对应的方法暴露给客户端,这样的方式非常原始,也很简单,但是代码的逻辑不清晰暴露的内容过多。为此,我们有一个解决方案:抽象逻辑(抽取其中的一些逻辑),提供一个 接口 这样 可以减少方法调用的复杂度也便于抽象跟代码管理

2.1、有了接口之后

代码图:

public interface Phone {
    void play();
}

所有手机类都实现 Phone 接口,然后将暴露给客户端调用的逻辑都封装在 play 方法里,那么客户端(调用者)需要知道的 API 就减少到了两种:Phone 的接口信息Phone 的接口有哪些实现类

但是这种工厂模式的缺点也很大:

  1. 客户端(调用者),必须知道手机类的具体名称,如果有 1000 个手机需要调用,则我们需要记住 1000 个手机的名称 ,这对于调用者来说不可能的。
  2. 客户端的调用,跟提供的代码是耦合的,例如有一天手机新增了一个功能,然后我们修改了接口的方法,同时成百上千个手机类也实现了这个接口,则全部手机类都是需要修改的,其 可扩展性 就减少了,维护的成本也随之增加了。

3、简单工厂

通过原始工厂模式的演变,为了更好的符合实际环境。

原理:通过在接口与实现类中间添加一层来解决需要记住名称过多和耦合问题。我们只要记住,代码耦合的话,可以通过两者之间添加一层来解决。

代码图:

public class PhoneFactory {
    public Phone createPhone(String tag) {
        if ("iphone".equals(tag)) {
            return new Iphone();
        } else if ("vivo".equals(tag)) {
            return new Vivo();
        } else if ("huawei".equals(tag)) {
            return new Huawei();
        }
    }
}

我们在原始工厂模式的基础上,再创建一个 PhoneFactory 类,里面只定义一个专门生产手机的方法,通过客户端调用者传进来的 手机品牌 然后生产对应的手机。

然后客户端调用者就可以直接调用相应的手机品牌的方法了:

PhoneFactory pf = new PhoneFactory();
pf.createPhone("iphone").play();
pf.createPhone("vivo").play();
pf.createPhone("huawei").play();

简单工厂模式,本身已经为解耦合做出了很好的方案。但是事情都是有两面性的,所以它也有缺点:

  1. PhoneFactory 类代码跟 Phone 代码 有耦合
  2. 每次要 添加/删除/修改 某一个 Phone,都需要修改 PhoneFactory 这个类

为此,简单工厂继续演变,就有工厂方法模式。

4、工厂方法模式

在简单工厂的基础上,首先为 Phone 专门建立一个生产手机的 工厂 (父工厂)。

public interface PhoneFactory {
    Phone createPhone();
}

如果我们需要增加一款产品,比如是 iPhone ,那么,只需要建立一个只生产 iPhone 的(子)工厂就可以了;如果再增加一款产品,比如 HuaWei,那么只需要增加另外一条只生产 HuaWei 手机的(子)工厂就可以了 。

public class HuaweiFactory implements PhoneFactory {
    public phone createPhone() {
        return new Huawei();
    }
}

客户端调用者,只需其中一个手机品牌工厂实现 Phone 工厂(接口)就可以了,就是一个手机品牌对应一个手机工厂,从而达到了解耦合。

PhoneFactory huaWeiPf = new HuaweiFactory();
huaWeiPf .createPhone().play();

PhoneFactory iPhonePf = new IphoneFactory();
iPhonePf .createPhone().play();

工厂方法模式的缺点:

  1. 代码容易膨胀,例如:我们每增加一个手机产品,相应的也要增加一个子工厂。
  2. 不容易反应产品与产品之间的关系。

事情是两面性的,耦合解决了也会产生另外一方面的问题,所以就要根据实际情况选择相应的对策来。就工厂方法模式来说,是目前最标准的一种工厂模式,也是应用广泛的一种模式了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值