设计模式——工厂模式

作者: BrightLoong | 来源:发表于2018-05-05 21:47 被阅读32次
    factory
    阅读原文请访问我的博客BrightLoong's Blog

    一.概述

    工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,其通过提供对象创建工厂,将创建对象的具体过程屏蔽起来,使调用的客户端不用关心具体的对象创建过程,提高了灵活性。

    工厂模式属于创建型模式。

    工厂模式根据抽象层的不用,可以分为以下三类:

    1. 简单工厂模式
    2. 工厂方法模式
    3. 抽象工厂模式

    其中“简单工厂模式”并不属于设计模式的一种,通俗的说是一种编程经验。

    二. 简单工厂模式

    简单工厂模式是工厂对象根据传入的参数不同,创建不同的对象实例。

    UML类图解析

    SimpleFactory
    • Product:产品接口,也可以是抽象类。
    • ProductA,ProductB:具体产品实现。
    • Factory:根据传入的参数创建具体的产品的工厂,供客户端调用。

    代码实现

    图形接口定义
    package io.github.brightloong.design.factory;
    
    /**
     * Created by BrightLoong on 2018/5/5.
     */
    public interface Shap {
        void draw();
    }
    
    
    图形实现——Circle
    package io.github.brightloong.design.factory;
    
    /**
     * Created by BrightLoong on 2018/5/5.
     */
    public class Circle implements Shap{
        public void draw() {
            System.out.println("it is a circle");
        }
    }
    
    图形实现——Square
    package io.github.brightloong.design.factory;
    
    /**
     * Created by BrightLoong on 2018/5/5.
     */
    public class Square implements Shap {
        public void draw() {
            System.out.println("it is a square");
        }
    }
    
    
    工厂

    关于工厂,最简单的是传入一个参数,使用 if, else或者case做条件判断返回不同的产品实现,也可以使用反射的方法,来消除这些判断条件。

    package io.github.brightloong.design.factory;
    
    /**
     * Created by BrightLoong on 2018/5/5.
     */
    public class SimpleShapFactory {
        public Shap create(String shapType) {
            if ("circle".equals(shapType)) {
                return new Circle();
            } else if ("square".equals(shapType)) {
                return new Square();
            }
            return null;
        }
    
        /**
         * 可以使用这种方式消除if之类的条件判断
         * @param clz
         * @param <T>
         * @return
         */
        public <T> Shap create(Class<T> clz) {
            Shap shap = null;
            try {
                shap = (Shap) clz.newInstance();
            } catch (InstantiationException e) {
                return null;
            } catch (IllegalAccessException e) {
                return null;
            }
            return shap;
        }
    }
    
    
    客户端调用
    package io.github.brightloong.design.factory;
    
    /**
     * Created by BrightLoong on 2018/5/5.
     */
    public class Client1 {
        public static void main(String[] args) {
            Shap shap = new SimpleShapFactory().create("circle");
            if (shap != null) {
                shap.draw();
            }
    
            Shap shap1 = new SimpleShapFactory().create(Square.class);
            if (shap1 != null) {
                shap1.draw();
            }
        }
    }
    
    

    输出结果

    it is a circle
    it is a square
    

    优点

    • 隐藏了具体的对象创建细节,提高了灵活性。
    • 便于扩展,添加新的产品时候只需要添加一个新的产品类,修改工厂。

    缺点

    • 每添加一个新的产品都要修改工厂类在其中添加判断分支(如果没有用反射的方式),违反了开放-封闭原则。
    • 如果添加的产品过多会导致类膨胀。

    三. 工厂方法模式

    工厂方法模式除了对产品类的抽象外,又添加了对工厂的抽象,不再在工厂中进行调用逻辑的判断处理,而是将这个判断放在了客户端。工厂方法针对每一产品都提供一个工厂类,不同的工厂创建不同的产品实例。

    UML类图解析

    factoryMethod

    工厂方法模式和简单工厂类似,不同的就是这里对工厂进行了抽象,有了一个抽象的工厂角色——AbstarctFactory。

    代码实现

    产品实现和简单工厂模式的一样,这里不再给出。

    AbstractFactory——FactoryMethod
    package io.github.brightloong.design.factory;
    
    /**
     * Created by BrightLoong on 2018/5/5.
     */
    public abstract class  FactoryMethod {
        abstract  Shap createShap();
    }
    
    
    FactoryA——CircleFactory
    package io.github.brightloong.design.factory;
    
    /**
     * Created by BrightLoong on 2018/5/5.
     */
    public class CircleFactory extends FactoryMethod {
        public Shap createShap() {
            return new Circle();
        }
    }
    
    
    FactoryB——SquareFactory
    package io.github.brightloong.design.factory;
    
    /**
     * Created by BrightLoong on 2018/5/5.
     */
    public class SquareFactory extends FactoryMethod {
        public Shap createShap() {
            return new Square();
        }
    }
    
    
    客户端调用
    package io.github.brightloong.design.factory;
    
    /**
     * Created by BrightLoong on 2018/5/5.
     */
    public class Client2 {
        public static void main(String[] args) {
            Shap shap = new SquareFactory().createShap();
            shap.draw();
        }
    }
    
    

    输出

    it is a square
    

    优点

    • 拥有简单工厂模式的优点。
    • 具有简单工厂模式的优点,并且再此基础上满足了开放-封闭原则,系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。

    缺点

    • 随着产品类的增加,要提供与其对应的子类,系统中类个数成对增加,在一定程度上增加了系统的复杂性。

    四. 抽象工厂模式

    上面说道的简单工厂和工厂模式都只能创建一个产品实例,抽象工厂提供了生成多产品的功能。这里很多地方提到了产品族 的说法,比如生产面包的工厂不止生产面包,还会生产饼干、糖果之类的。

    UML类图解析

    factoryMethod

    这里有ProductA和ProductB两个产品抽象,并且分别有两个具体实现,抽象工厂AbstractFactory和之前不同的是这里提供了两个生产产品的方法——crateProductA和crateProductB。

    代码实现

    在之前Shap产品的基础上增加Colro产品,具体代码如下:

    Color
    public interface Color {
       void fill();
    }
    
    Color实现——Red
    public class Red implements Color {
    
       @Override
       public void fill() {
          System.out.println("it is red.");
       }
    }
    
    Color实现——Green
    public class Green implements Color {
    
       @Override
       public void fill() {
          System.out.println("it is green");
       }
    }
    
    抽象工厂—— AbstractFactory
    public abstract class AbstractFactory {
       abstract Color createColor();
       abstract Shape createShape() ;
    }
    
    工厂实现1
    package io.github.brightloong.design.factory;
    
    /**
     * Created by BrightLoong on 2018/5/5.
     */
    public class RedCircleFactory extends AbstractFactory {
        Shap createShap() {
            return new Circle();
        }
    
        Color createColor() {
            return new Red();
        }
    }
    
    
    工厂实现2
    package io.github.brightloong.design.factory;
    
    /**
     * Created by BrightLoong on 2018/5/5.
     */
    public class GreenSquareFactory extends AbstractFactory {
        Shap createShap() {
            return new Square();
        }
    
        Color createColor() {
            return new Green();
        }
    }
    
    
    客户端调用
    package io.github.brightloong.design.factory;
    
    /**
     * Created by BrightLoong on 2018/5/2.
     */
    public class Client3 {
        public static void main(String[] args) {
            AbstractFactory factory = new RedCircleFactory();
            Shap shap = factory.createShap();
            Color color = factory.createColor();
            shap.draw();
            color.fill();
        }
    }
    

    输出

    it is a circle
    it is red.
    

    优点

    • 支持了不同类型的产品,更加灵活。

    缺点

    • 缺点很明显,类膨胀越来越厉害。

    相关文章

      网友评论

        本文标题:设计模式——工厂模式

        本文链接:https://www.haomeiwen.com/subject/tonerftx.html