工厂模式

工厂模式

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

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

所以,为了简化代码的协作使用及管理维护,必须想尽办法简化代码逻辑,实现必要的分离

1 最原始的方式

比如说,有一系列的代码,是用来创建不同品牌的手机。代码是这样的:

public class Iphone {
    public void mypg () {}
}
public class Huawei {
    public void myhwi () {}
}
public class Lennovo {}
public class Xiaomi {}
public class Vivo {}

如果这样的代码提供给客户端调用,那么提供者必须要将所有类的名称以及对应的方法暴露给客户端。

客户端的调用示例如下:

Iphone pg = new Iphone();
phone1.mypg();

Huawei hw = new Huawei();
phone2.myhw();

这样的方式非常原始,也很简单,但是代码的逻辑不清晰,暴露的内容过多。

解决的方案:

  • 抽象逻辑,提供接口

2 有了接口之后

为了减少方法调用的复杂度,也为了便于抽象跟代码管理,咱们额外提供一个接口:

public interface Phone {
    void play();
}

然后,将所有手机类都实现 Phone 接口,将暴露给客户端调用的逻辑都封装在 play 方法里。

那么,客户端需要知道的调用 API 就减少到了两种:

  1. Phone 接口的信息
  2. Phone 接口有哪些实现类

调用的逻辑就变简单了:

Phone phone1 = new Iphone();
phone1.play();

Phone phone2 = new Lianxiang();
phone2.play();

Phone phone3 = new Xiaomii();
phone3.play();

这种方式有缺点:

  1. 客户端,必须要知道手机类的具体名字
  2. 客户端的调用,跟提供的代码是耦合的

所以,自然产生了简单工厂的这种策略

3 简单工厂

在中间加一层:

public class PhoneFactory {
    public Phone createPhone(String tag) {
        if (tag.equals("lx")) {
            return new Lenovo();
        } else if (tag.equals("pg")) {
            return new Iphone();
        } else if (tag.equals("hw")) {
            return new Huawei();
        }
    }
}

客户端的调用:

PhoneFactory pf = new PhoneFactory();

pf.createPhone("hw").play();
pf.createPhone("pg").play();
pf.createPhone("xm").play();

简单工厂模式,本身已经为解耦合做出了很好的方案。但是它有缺点:

  • PhoneFactory 代码跟 Phone 代码紧耦合
  • 每次要添加/删除/修改某一个 Phone,需要修改 PhoneFactory 这个类

解决方案就是工厂方法模式

4 工厂方法模式

为 Phone 工厂,创建一个接口:

public interface GCIphoneFactory {
Phone createPhone();
}

如果增加了一款产品,比如是 iPhone,那么,只需要为 iPhone 创建一个工厂类就可以了:

 

public class IphoneFactory implements GCIphoneFactory {
    @Override
    public Phone createPhone() {
        return new IPhone();
    }
}

如果再增加另外一款产品,比如 Huawei,那么只需要另外一个工厂就可以了:

 

public class HuaweiFactory implements GCIphoneFactory {
    @Override
    public Phone createPhone() {
        return new Huawei();
    }
}

客户端的调用:

GCIphoneFactory gc = new HuaweiFactory();
gc.createPhone().play();
        
GCIphoneFactory pg = new IphoneFactory();
pg.createPhone().play();

工厂方法模式,是最标准的一种工厂模式,也是应用广泛的一种模式

但是工厂方法模式,有一个很大的缺点:

   每增加一个产品,相应的也要增加一个子工厂,加大了额外的开发量。
 
posted @ 2018-12-11 14:30  肥烁  阅读(161)  评论(0编辑  收藏  举报