zoukankan      html  css  js  c++  java
  • 设计模式——工厂方法模式详解

    0.前言

    写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦~

    实际上工厂模式分为三种,第一种是简单工厂模式,第二种是工厂方法模式,第三种是抽象工厂模式

    此篇为工厂方法模式的详解,那为什么跳过了简单工厂模式呢,是因为这两种模式差别不大,差异之处会在本文中指出,懂了工厂方法模式,稍微解释就懂了简单工厂模式。所以仔细看哦~

    还有就是抽象工厂模式,限于篇幅,这个模式另外写了一篇,有兴趣可以阅读设计模式——抽象工厂设计模式详解

     

    1.工厂方法模式模式介绍

    工厂方法模式定义:

    定义一个用于创建对象的接口,让子类决定实例化哪个类。

     

    工厂方法模式包括的角色:

    1抽象产品类:所创建产品的父类,给出一个抽象接口或抽象类,以及一般由具体产品类具体实现。

    2具体产品类:抽象产品类的实现类,为实现某个具体产品的对象。

    3抽象工厂类:工厂方法模式的核心(简单工厂模式无此抽象类),与应用程序无关。是具体工厂必须实现的接口或者必须继承的父类。

    4具体工厂类:继承抽象工厂类,实现具体业务逻辑。

     

    工厂方法模式的使用场景:

    1)在任何需要生成复杂对象的地方。

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

    3)工厂方法模式会导致类复杂化,在某些情况简单时,也许不需要使用工厂方法模式。

     

    2. 工厂方法模式实现

    下面是利用工厂方法模式生产产品的实例介绍,便于理解该模式如何运用。

     

    2.1 产品抽象类

    public abstract class Product{
    public abstract void method();
    } 
    


    2.2 具体产品实现类

    public class ProductA extends Product{
    @override
    public void method(){
    System.out.println(“我是具体产品小A~”);
    }
    } 
    
    public class ProductB extends Product{
    @override
    public void method(){
    System.out.println(“我是具体产品小B~”);
    }
    } 


    2.3 抽象工厂类(简单工厂模式无此抽象类)

    public abstract class Factory{  
    /** 
    *抽象工厂方法 
    *具体产生什么由子类决定 
    *@return 具体产品对象 
    */  
    public abstract Product createProduct();  
    }   

    2.4 具体(得到A产品)工厂类

    public class ConcreteFactory extends Product {
    @override
    public Product createProduct(){
        return new ProductA();//若想得到产品B,改为 return new ProductB()即可
    }
    } 
    


    2.5 使用

    Factory factory = new ConcreteFactory();
    Product product = factory.createProduct();
    product.method();


    3. 使用反射对该模式进行优化

    可以向工厂方法的参数中传入一个Class来决定生产哪一个产品,然后通过反射的方法完成,使代码更加简洁。具体实现如下:

    实际上修改的是工厂类(两个),和使用时的部分代码。


    3.1 抽象工厂类

    public abstract class Factory{
    /**
    *抽象工厂方法
    *具体产生什么由子类决定
    *@param clz 产品对象的类型
    *@return 具体产品对象
    */
    public abstract <T extends Product> T createProduct(Class<T> clz);
    } 

    这里使用了Java里的泛型的概念,如果不太清楚泛型,可参考之前写过的Java泛型详解


    3.2 具体的工厂类,通过反射获取实例

    public class ConcreteFactory extends Product {
    @override
    public <T extends Product> T  createProduct(Class<T> clz){
        Product product = null;
        try{
            product = (Product)Class.forName(clz.getName()).newInstance();
        }catch(Exception e){
            e.printStackTrace();
        }
        return (T) product;
    }
    } 

    3.3 使用

    Factory factory = new ConcreteFactory();
    Product product = factory.createProduct(ProductA.class);//根据需要产生不同的产品,传入不同的参数
    product.method();


    这样的方法比较简介明了,并且是动态实现的,当然也可以生成AB两个产品的工厂实现类,分别返回AB两种产品对象。这种拥有多个工厂的方式称为多工厂方法模式


    4. 简单工厂模式

    哈哈,终于到了要介绍你在本篇开头介绍到的简单工厂模式了。

    简单工厂模式是对工厂方法模式的简化,简化掉了抽象工厂类。显然,前提是必须确保工厂类只有一个。

    我们要做的就是将对应的工厂方法改为静态方法即可:

    public class Factory{  
    /** 
    *简单工厂模式的工厂类 
    *@return 具体产品对象 
    */  
    public static Product createProduct(){
            return new ProductA();
            //return new ProductB();
        }
    }   

    使用时:

    Product product = Factory.createProduct();
    product.method();

    以上便完成了整个建造者模式的实现细节。

    最后就是抽象工厂模式,有兴趣可以阅读设计模式——抽象工厂设计模式详解


    5. 工厂方法模式优缺点

    工厂方法模式的优点:

    1)工厂模式完全负责设计原则,降低了对象之间的耦合度

    2)很明显工厂方法模式依赖于抽象的架构,将实例化的任务交由子类去完成,有非常好的拓展性

     

    工厂方法模式的缺点:

    每次为工厂方法模式添加新的产品都需要编写一个新的产品类,并引入抽象层(即如果增加新类型,则需要修改工厂,违背了开放封闭原则(ASD) ),导致类结构的复杂化


  • 相关阅读:
    Python的subprocess子进程和管道进行交互
    python UnicodeEncodeError: 'ascii' codec can't encode characters 解决办法
    如何创建,增加swap
    nginx.conf配置
    15个极好的Linux find命令示例(二)
    15个实用的Linux find命令示例(一)
    vmware 虚拟机 mount :no medium found解决方法
    服务器上的iptables
    源码编译安装MySQL
    ORACLE参数文件
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461556.html
Copyright © 2011-2022 走看看