其他分享
首页 > 其他分享> > 晋城

晋城

作者:互联网

抽象工厂模式详解

 一,概述

  抽象工厂模式为一个产品家族提供了统一的创建接口。当需要这个产品家族的某一系列的时候,可以从抽象工厂中选出相对应的系列来创建一个具体的工厂类别。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

  在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

  相关术语:

二,产品族和产品等级结构图

  我们以一个品牌为一个产品族,电脑、手机、路由器为产品等级,每一个品牌都有自己的产品族,这就构成一个完整产品群;

  横向代表一族,纵向代表一个等级,横纵交集代表某一个品牌的某一个产品(比如下图中交集的点为电脑),请看下图;

  

 三,UML图

  这个类图其实比较简单,简单说明下:

  产品顶级接口:主要被产品抽象类实现;

  产品抽象类:某个具体产品要实现的类;

  具体实现类:具体产品实现,比如华为路由器实现自抽象类AbstractRouter;

  工厂接口:工厂接口中定义创建每个产品方法;

  具体华为工厂:实现工厂接口,创建华为一族产品(路由器、手机、电脑);

  

 四,具体代码实现

  代码中我们以华为产品为例,分别定义华为电脑、手机、路由器产品,从UML类图中可以看出我们的产品结构层级比较清晰,现在我们先设计我们产品。

  下面开始定义产品;

  产品顶级接口;

复制代码
package pattern.abstractfactory.product;
/**
 * 定义产品接口
 * @author ningbeibei
 */
public interface InterfaceProduct {
    void get();
}
复制代码

  定义计算机抽象类并实现产品InterfaceProduct 接口;

复制代码
package pattern.abstractfactory.product;
/**
 * 定义计算机产品抽象类,并实现产品接口InterfaceProduct
 * @author ningbeibei
 */
public abstract class AbstractComputers implements InterfaceProduct {
    public abstract void get();
}
复制代码

  定义手机抽象类并实现产品InterfaceProduct 接口;

复制代码
package pattern.abstractfactory.product;
/**
 * 定义手机抽象类,并实现产品接口InterfaceProduct
 * @author ningbeibei
 */
public abstract class AbstractPhone  implements InterfaceProduct {
    public abstract void get();
}
复制代码

  定义路由器抽象类并实现产品InterfaceProduct 接口;

复制代码
package pattern.abstractfactory.product;
/**
 * 定义路由器产品抽象类,并实现InterfaceProduct接口
 * @author ningbeibei
 */
public abstract class AbstractRouter implements InterfaceProduct{
    public abstract void get();
}
复制代码

  定义华为电脑具体实现类,继承AbstractComputers抽象类;

复制代码
package pattern.abstractfactory.product;
/**
  * 华为电脑实现类
 * @author ningbeibei
 */
public class HuaWeiComputer extends AbstractComputers{
    @Override
    public void get() {
        System.out.println("华为笔记本");
    }
}
复制代码

  定义华为手机具体实现类,继承AbstractPhone抽象类;

复制代码
package pattern.abstractfactory.product;
/**
  *  华为手机实现类,
 * @author ningbeibei
 */
public class HuaWeiPhone extends AbstractPhone{
    @Override
    public void get() {
        System.out.println("华为手机");
    }
}
复制代码

  定义华为路由器具体实现类,继承AbstractRouter抽象类;

复制代码
package pattern.abstractfactory.product;
/**
 * 华为路由器
 * @author ningbeibei
 */
public class HuaWeiRouter extends AbstractRouter {
    @Override
    public void get() {
        System.out.println("华为品牌路由器");
    }
}
复制代码

  下面开始定义工厂;

  定义工厂接口;

复制代码
package pattern.abstractfactory.factory;
import pattern.abstractfactory.product.InterfaceProduct;
/**
 * 定义产品工厂接口,
 * @author ningbeibei
 */
public interface InterfactFactory {
    //手机产品
    InterfaceProduct createPhone();
    //电脑产品
    InterfaceProduct createComputer();
    //路由器产品
    InterfaceProduct createRouter();
}
复制代码

  具体工厂实现类,实现 InterfactFactory  接口;

复制代码
package pattern.abstractfactory.factory;
import pattern.abstractfactory.product.HuaWeiComputer;
import pattern.abstractfactory.product.HuaWeiPhone;
import pattern.abstractfactory.product.HuaWeiRouter;
import pattern.abstractfactory.product.InterfaceProduct;
/**
 * 华为工厂
 * @author ningbeibei
 */
public class HuaWeiFactory implements InterfactFactory {
    /**
     * 创建电脑对象并返回
     */
    @Override
    public InterfaceProduct createComputer() {
        return new HuaWeiComputer();
    }
    /**
     * 创建手机对象并返回
     */
    @Override
    public InterfaceProduct createPhone() {
        return new HuaWeiPhone();
    }
    /**
     * 创建路由器对象并返回
     */
    @Override
    public InterfaceProduct createRouter() {
        return new HuaWeiRouter();
    }
}
复制代码

  测试类;

复制代码
package pattern.abstractfactory;
import pattern.abstractfactory.factory.HuaWeiFactory;
import pattern.abstractfactory.factory.InterfactFactory;
import pattern.abstractfactory.product.InterfaceProduct;
/**
 * 抽象工厂模式测试类
 * @author ningbeibei
 */
public class test {
    public static void main(String[] args) {
        //创建华为品牌工厂
        InterfactFactory huawei = new HuaWeiFactory();
        //通过华为工厂获取华为电脑对象
        InterfaceProduct computer = huawei.createComputer();
        computer.get();
        //通过华为工厂获取华为手机对象
        InterfaceProduct phone = huawei.createPhone();
        phone.get();
        //通过华为工厂获取华为路由器对象
        InterfaceProduct router = huawei.createRouter();
        router.get();
    }
}
复制代码

  运行结果;

五,抽象工厂方法模式如何扩展产品族

  抽象工厂模式对于横向扩展方便,对于纵向扩展非常困难,也就是说:假如我们要扩展一个新的品牌,比如扩展一个小米品牌,小米产品有电脑、手机、路由器,扩展新品牌就是横向扩展,非常方便,但是我们要给小米添加一个电饭煲产品却非常困难,这就是纵向扩展,所以在使用抽象工厂模式时一定要选择合适的场景,也就是在不同场景中使用最适合的模式才是设计模式的精髓。

  下面我们就来横向扩展一个新品牌的产品族,需要添加电脑、手机、路由器具体类(小米品牌)代码如下;

  小米电脑

复制代码
package pattern.abstractfactory.product;
/**
 * 小米电脑,继承自 AbstractComputers 抽象类
 * @author ningbeibei
 */
public class MiComputer extends AbstractComputers {
    @Override
    public void get() {
        System.out.println("小米电脑");
    }
}
复制代码

  小米手机

复制代码
package pattern.abstractfactory.product;
/**
 * 小米手机,继承自 AbstractPhone 抽象类
 * @author ningbeibei
 */
public class MiPhone extends AbstractPhone {
    @Override
    public void get() {
        System.out.println("小米手机");
    }
}
复制代码

  小米路由器

复制代码
package pattern.abstractfactory.product;
/**
  * 小米路由器,继承自 AbstractRouter 抽象类
 * @author ningbeibei
 */
public class MiRouter extends AbstractRouter{
    @Override
    public void get() {
        System.out.println("小米路由器");
    }
}
复制代码

  添加小米具体工厂类

复制代码
package pattern.abstractfactory.factory;
import pattern.abstractfactory.product.InterfaceProduct;
import pattern.abstractfactory.product.MiComputer;
import pattern.abstractfactory.product.MiPhone;
import pattern.abstractfactory.product.MiRouter;
/**
 * 小米工厂,实现 InterfactFactory 接口
 * @author ningbeibei
 */
public class MiFactory implements InterfactFactory{
    //小米手机
    @Override
    public InterfaceProduct createPhone() {
        return new MiPhone();
    }
    //小米电脑
    @Override
    public InterfaceProduct createComputer() {
        return new MiComputer();
    }
    //小米路由器
    @Override
    public InterfaceProduct createRouter() {
        return new MiRouter();
    }
}
复制代码

  最后编写测试类,代码中红色字体为新扩展的品牌产品

复制代码
package pattern.abstractfactory;
import pattern.abstractfactory.factory.HuaWeiFactory;
import pattern.abstractfactory.factory.InterfactFactory;
import pattern.abstractfactory.factory.MiFactory;
import pattern.abstractfactory.product.InterfaceProduct;
/**
 * 抽象工厂模式测试类
 * @author ningbeibei
 */
public class test {
    public static void main(String[] args) {
        // 创建华为品牌工厂
        InterfactFactory huawei = new HuaWeiFactory();
        // 通过华为工厂获取华为电脑对象
        InterfaceProduct computer = huawei.createComputer();
        computer.get();
        // 通过华为工厂获取华为手机对象
        InterfaceProduct phone = huawei.createPhone();
        phone.get();
        // 通过华为工厂获取华为路由器对象
        InterfaceProduct router = huawei.createRouter();
        router.get();

        // 创建小米品牌工厂
        InterfactFactory Mifactory = new MiFactory();
        // 通过小米工厂获取小米电脑对象
        InterfaceProduct micomputer = Mifactory.createComputer();
        micomputer.get();
        // 通过小米工厂获取小米手机对象
        InterfaceProduct miphone = Mifactory.createPhone();
        miphone.get();
        // 通过小米工厂获取小米路由器对象
        InterfaceProduct mirouter = Mifactory.createRouter();
        mirouter.get();
    }
}
复制代码

  运行结果:

 

  注意:通过上面的品牌扩展我们发现,横向扩展容易,纵向扩展非常困难,代码可以非常方便的扩展一个品牌已有的产品,但要扩展一个未定义的产品却异常困难,比如要扩展一个华为平板,需要修改工厂逻辑代码,新增产品结构,这显然不符合设计模式开闭原则,所以在使用时一定要考虑清楚,确定不在有新的产品等级扩展。

六,优点和缺点及使用场景

优点

缺点

使用场景

 七,写的不足之处还望批评指正

  写的不足之处请在评论区指出,便于我及时更正错误,避免给读者带来误解,希望大家多多提意见。

标签:pattern,晋城,InterfaceProduct,工厂,华为,abstractfactory,public
来源: https://www.cnblogs.com/SHAO1994/p/14256655.html