前言
在之前的内容中已经介绍了设计模式中的单例模式,接下来我们介绍一种非常常用的设计模式-工厂模式,该模式提供了一种简单、快速、高效且安全地创建对象的方式。
一、工厂模式是什么?
工厂模式:最常见的设计模式,属于创建型模式,用户只需通过接口创建需要的对象即可,不用关注对象的具体创建流程。
实现方式:在接口中定义了创建对象的方法,而将具体的创建对象的过程在子类中实现。
通俗的来讲,就是用工厂方法代替new操作创建一个实例化对象的方式。
工厂模式有几种不同的实现方式,在这里介绍简单工厂模式和抽象工厂模式。
二、简单工厂模式
如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫"简单工厂模式"。
以创建手机为例,假设手机的品牌有华为和小米两种类型,我们要实现的是根据不同的传入参数实例化不同的手机,具体的设计如下图。
定义一个Phone接口,以及两个实现类XiaoMi和HuaWei,定义一个Factory的工厂类,工厂类有一个方法createPhone(),根据不同的参数实例化不同品牌的手机返回。
JAVA代码实现
定义手机接口,并在接口中定义了brand(),用来返回手机的品牌。
public interface Phone {
String brand();
}
定义小米和华为实现类,两个品牌的手机通过实现brand()打印自己的商标。
public class XiaoMi implements Phone {
@Override
public String brand() {
return "小米手机";
}
}
public class HuaWei implements Phone {
@Override
public String brand() {
return "华为手机";
}
}
定义工厂类,工厂类有一个静态方法createPhone(),用来根据不同的参数实例化不同品牌的手机类并返回
public class Factory {
public static Phone createPhone(String name){
if(name.equals("小米")){
return new XiaoMi();
}else if (name.equals("华为")){
return new HuaWei();
}else{
return null;
}
}
}
测试工厂模式
public class Test {
public static void main(String[] args) {
Phone xiaoMi=Factory.createPhone("小米");
Phone huaWei=Factory.createPhone("华为");
System.out.println(xiaoMi.brand());
System.out.println(huaWei.brand());
}
}
这样便实现了一个根据不同的参数实例化不同品牌的手机类并返回,并且对调用者来说屏蔽了实例化的细节。
在简单工厂模式中创建实例的方法通常为静态方法,因此简单工厂模 式又叫作静态工厂方法模式。
三、抽象工厂模式
抽象工厂模式在简单工厂模式上添加了一个创建不同工厂的抽象接口(抽象类或接口实现),该接口可叫超级工厂。
实现方法:首先通过抽象接口创建出不同的工厂对象,然后根据不同的工厂对象创建不同的对象。
可以将简单工厂模式理解为针对一个产品维度进行分类,抽象工厂针对的是多个产品维度分类,如小米公司不仅造小米手机也造小米电脑,华为也一样。如果使用简单工厂模式,就势必会存在多个独立的工厂,这种设计显然不够优雅。
抽象工厂就能很好的解决这些问题,定义一个抽象工厂,在抽象工厂中定义好要生产的产品(手机或者电脑),然后在抽象工厂的实现类中返回产品给用户。
JAVA代码实现如下:
抽象工厂的定义如下
这个类是抽象工厂的核心类,定义了两个方法createPhone()和createComputer(),用户需要手机时调用createPhone()创建一个手机(华为和小米都可),电脑同理。
public abstract class AbstractFactory {
public abstract Phone createPhone(String name);
public abstract Computer createComputer(String name);
}
定义手机和电脑的实现类
//手机工厂实现类
public class PhoneFactory extends AbstractFactory{
@Override
public Phone createPhone(String name) {
if(name.equals("小米")){
return new XiaoMiPhone();
}else if (name.equals("华为")){
return new HuaWeiPhone();
}else{
return null;
}
}
@Override
public Computer createComputer(String name) {
return null;
}
}
//电脑工厂实现类
public class ComputerFactory extends AbstractFactory{
@Override
public Phone createPhone(String name) {
return null;
}
@Override
public Computer createComputer(String name) {
if(name.equals("小米")){
return new XiaoMiComputer();
}else if(name.equals("华为")){
return new HuaWeiComputer();
}else{
return null;
}
}
}
定义手机和电脑接口
public interface Phone {
String call();
}
public interface Computer {
String internet();
}
定义手机电脑实现类
public class XiaoMiPhone implements Phone {
@Override
public String call() {
return "我是小米手机";
}
}
public class HuaWeiPhone implements Phone {
@Override
public String call() {
return "我是华为手机";
}
}
public class XiaoMiComputer implements Computer{
@Override
public String internet() {
return "我是小米电脑";
}
}
public class HuaWeiComputer implements Computer{
@Override
public String internet() {
return "我是华为电脑";
}
}
测试代码以及结果
public class User {
public static void main(String[] args) {
//利用抽象工厂创建手机产品
AbstractFactory phoneFactory=new PhoneFactory();
Phone xiaoMiPhone=phoneFactory.createPhone("小米");
Phone huaWeiPhone=phoneFactory.createPhone("华为");
//利用抽象工厂创建电脑产品
AbstractFactory computerFactory=new ComputerFactory();
Computer xiaoMiComputer=computerFactory.createComputer("小米");
Computer huaWeiComputer=computerFactory.createComputer("华为");
System.out.println(xiaoMiPhone.call());
System.out.println(huaWeiPhone.call());
System.out.println(xiaoMiComputer.internet());
System.out.println(huaWeiComputer.internet());
}
}
以上代码使用我们定义好的抽象工厂,在需要生产产品时,根据不同的工厂生成不同的产品。
四、简单工厂和抽象工厂模式的优缺点
4.1简单工厂模式优缺点
优点:
1.工厂类包含必要的逻辑判断,可以决定创建哪一个产品的实例。
2.客户端无需知道所创建具体产品的类名,只需知道参数(手机品牌)即可
3.可以引入配置文件,不修改客户端代码的情况下更换和添加新的具体产品类。
缺点:
1.工厂类单一,职责太重
2.增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
3.扩展性差,新加产品需要修改工厂逻辑,种类太多会导致逻辑复杂
4.2抽象工厂模式优缺点
优点:
1.具有简单工厂模式的优点
2.可以在类的内部对产品族进行约束
2.增加了扩展性,当增加一个新的产品族(例如oppo品牌)时,不需要修改原代码
缺点:
当产品族中需要增加一个新的产品时(例如小米品牌要卖耳机,要在抽象工厂里加一个造耳机的抽象方法),所有的工厂类都需要进行修改(重写抽象工厂的所有抽象方法)
总结
对于产品种类相对较少的情况,可以考虑使用简单工厂模式。当产品种类比较多的情况下,尤其是一系列相关联的产品例如手机、电脑、耳机等,可以考虑使用抽象工厂模式。两种模式各有优缺点,具体如何使用还要根据实际场合来分析,两种模式的最终目的都是为了解耦。