当前位置: 游戏平台 > 互联网科技 > 正文

设计模式——工厂模式

时间:2020-01-09 19:57来源:互联网科技
factory阅读原文请访问我的博客BrightLoong'sBlog 概述 前言:早已断断续续把23种设计模式学习了一遍,可是实际运用的不是很理想。如果刻意用设计模式,你会发现一个很小的项目,很小的

图片 1factory阅读原文请访问我的博客BrightLoong's Blog

概述

前言:早已断断续续把23种设计模式学习了一遍,可是实际运用的不是很理想。如果刻意用设计模式,你会发现一个很小的项目,很小的功能其实处处都是可以按标准模式去编码的,这个也许就是所谓的过度设计的问题;而不用设计模式,代码又写得愚蠢臃肿,除了堆砌代码实现功能之外你看不到程序更别提思想上的一丝闪光点。也许正像网上很多人说的那样,到一定境界自动就会高效运用到项目中去了。当然现在也不能放弃学习它,下面就把创建型模式再整理一遍,下次用到的时候可以对照查一查看一下,希望可以“一劳永逸”。
一、概述
1、创建型模式,就是用来创建对象的模式,抽象了实例化的过程。它帮助一个系统独立于如何创建、组合和表示它的那些对象。
2、两个主旋律:第一,将系统使用哪些具体类的信息封装起来;第二,隐藏了这些类的实例是如何被创建和组织的。外界对于这些对象只知道它们共同的接口,而不清楚其具体的实现细节。
3、作用
创建者模式作用可以概括为如下两点((1)和(2)引用网上博文):
(1)封装创建逻辑,绝不仅仅是new一个对象那么简单。
(2)封装创建逻辑变化,客户代码尽量不修改,或尽量少修改。

一.概述

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

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

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

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

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

  在前面两章中,分别介绍了简单工厂模式和工厂方法模式,我们知道简单工厂模式的优点是去除了客户端与具体产品的依赖,缺点是违反了“开放-关闭原则”;工厂方法模式克服了简单工厂模式的缺点,将产品的创建工作放到具体的工厂类,每个工厂类负责生成一个产品。但是在实际应用中,一个工厂类只创建单个产品的情况很少,一般一个工厂类会负责创建一系列相关的产品,如果我们要设计这样的系统,工厂方法模式显然不能满足应用的需求,本章要介绍的抽象工厂模式,可以很好地解决一系列产品创建的问题。

 二、五种模式
1、单件模式(Singleton Pattern)
图片 2
单件模式(Singleton Pattern)解决的是实体对象的个数问题,贴一段代码说明一下:

二. 简单工厂模式

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

图片 3SimpleFactory

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

定义

图片 4图片 5Code
using System;
using System.Collections;
using System.Collections.Generic;

图形接口定义
package io.github.brightloong.design.factory;/** * Created by BrightLoong on 2018/5/5. */public interface Shap { void draw();}

  “提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。”

//创建型设计模式总结-单例模式
namespace CreateTypePattern
{
    //饿汉式
    sealed class Singleton
    {
        //私有的唯一实例成员,在类加载的时候就创建好了单例对象
        private static readonly Singleton instance = new Singleton();

图形实现——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"); }}
  • 最初的定义出现于《设计模式》(Addison-Wesley,1994)。

        //私有的构造方法,避免外部创建类实例
        private Singleton()
        {
        }

图形实现——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"); }}

结构图

        //静态方法,返回此类的唯一实例
        public static Singleton GetInstance()
        {
            return instance;
        }

工厂

关于工厂,最简单的是传入一个参数,使用 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) { return new Circle(); } else if ("square".equals) { return new Square(); } return null; } /** * 可以使用这种方式消除if之类的条件判断 * @param clz * @param <T> * @return */ public <T> Shap create(Class<T> clz) { Shap shap = null; try { shap =  clz.newInstance(); } catch (InstantiationException e) { return null; } catch (IllegalAccessException e) { return null; } return shap; }}

 图片 6

    }

客户端调用
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; if (shap != null) { shap.draw(); } Shap shap1 = new SimpleShapFactory().create(Square.class); if (shap1 != null) { shap1.draw(); } }}

输出结果

it is a circleit is a square
  • 隐藏了具体的对象创建细节,提高了灵活性。
  • 便于扩展,添加新的产品时候只需要添加一个新的产品类,修改工厂。
  • 每添加一个新的产品都要修改工厂类在其中添加判断分支(如果没有用反射的方式),违反了开放-封闭原则。
  • 如果添加的产品过多会导致类膨胀。

  先对上面结构图的几个角色进行说明:

    //客户端调用
    public class Program
    {
        static void Main()
        {
           Singleton instance= Singleton.GetInstance();
           Singleton instance1 = Singleton.GetInstance();

三. 工厂方法模式

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

图片 7factoryMethod

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

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

  • AbstractFactory:抽象工厂接口,里面应该包含所有产品创建的抽象方法;
  • ConcreteFactory1和ConcreteFactory2:具体的工厂,创建具有特定实现的产品对象;
  • AbstractProductA和AbstractProductB:抽象产品,它们可能有多种不同的实现方式;
  • ProductA1、ProductA2、ProductB1和ProductB2:具体的产品,是抽象产品的具体实现。

           Console.WriteLine(object.ReferenceEquals(instance,instance1)); //引用指向同一个对象
           Console.WriteLine(instance.Equals(instance1)); //同一个对象

AbstractFactory——FactoryMethod
package io.github.brightloong.design.factory;/** * Created by BrightLoong on 2018/5/5. */public abstract class FactoryMethod { abstract Shap createShap();}

  从结构图中可以看到,抽象工厂方法最大的好处是能够很方便的变换产品系列(例如id<AbstractFactory> factory =[ [ConcreteFactory1 alloc] init],只需要将ConcreteFactory1换成ConcreteFactory2,就可以创建ProductA2和ProductB2)。另外,抽象工厂方法让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中(例如id<AbstractProductA> product = [factory createProductA],客户端根本不知道具体的类名是ProductA1还是ProductA2)。

           Console.ReadLine();
        }
    }

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(); }}

  但是,抽象工厂方法也是存在缺点的,比如说现在我们要增加一个新的产品,首先,我们需要增加三个类:AbstractProductC、ProductC1、ProductC2;另外,我们还需要更改三个类:AbstractFactory、ConcreteFactory1、ConcreteFactory2,这样,很明显是违背“开放-关闭原则”。这也是可以理解的,没有任何一个设计模式是完美没有瑕疵的,这就好比世界上没有打不败的武功一样。我们可以做的就是在实际的需求中,尽可能的将变化点进行隔离,以达到变化发生的时候,对整个系统的影响最小,变化所带来的变更和成本最低。

}

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(); }}

示例

2、工厂方法模式(Factory Pattern)
图片 8
在工厂方法中,工厂类成为了抽象类,其实际的创建工作将由其具体子类来完成。工厂方法的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中去,强调的是“单个对象”的变化。

客户端调用
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
  • 拥有简单工厂模式的优点。
  • 具有简单工厂模式的优点,并且再此基础上满足了开放-封闭原则,系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。
  • 随着产品类的增加,要提供与其对应的子类,系统中类个数成对增加,在一定程度上增加了系统的复杂性。

  还是继续简单工厂模式和工厂方法模式的应用场景,这里将场景稍微改变一下:我们知道,绘制统计图形的方案有多种,我们既可以使用OWC来绘制统计图形,也可以使用HTML 5来绘制统计图形,或者其他的一些第三方插件来进行绘图,等等。这里我们用OWC和HTML 5绘制统计图形来说明抽象工厂模式(注意:示例和场景只是为了说明设计模式的思想,并不是说实际开发中我们就会这么使用)。先来看看新应用场景使用抽象工厂模式实现的结构图:

图片 9图片 10Code
using System;
using System.Collections;
using System.Collections.Generic;

四. 抽象工厂模式

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

图片 11factoryMethod

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

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

图片 12 

//创建型设计模式总结-工厂方法模式
namespace CreateTypePattern
{
    interface IProduct
    {

Color
public interface Color { void fill();}

  根据结构图,我们来看看部分源码(完整代码在后面会提供下载)。

    }
    class ProductA : IProduct
    {

Color实现——Red
public class Red implements Color { @Override public void fill() { System.out.println("it is red."); }}

  AbstractLine.h:

    }
    class ProductB : IProduct
    {

Color实现——Green
public class Green implements Color { @Override public void fill() { System.out.println("it is green"); }}
1 @protocol AbstractLine <NSObject>
2 
3 - (void)drawLine;

    }
    interface IFactory
    {
        IProduct CreateProduct();
    }

抽象工厂—— AbstractFactory
public abstract class AbstractFactory { abstract Color createColor(); abstract Shape createShape() ;}

  AbstractPie.h:

    class FactoryA : IFactory
    {
        public IProduct CreateProduct() { return new ProductA(); }
    }

工厂实现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(); }}
1 @protocol AbstractPie <NSObject>
2 
3 - (void)drawPie;

    class FactoryB : IFactory
    {
        public IProduct CreateProduct() { return new ProductB(); }
    }

工厂实现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(); }}

  AbstractFactory.h:

    //客户端调用
    public class Program
    {
        static void Main()
        {
            IFactory factory = new FactoryA();
            Console.WriteLine(factory.CreateProduct().GetType());
            Console.WriteLine("---------------------------------");
            factory = new FactoryB();
            Console.WriteLine(factory.CreateProduct().GetType());
            Console.ReadLine();
        }
    }

客户端调用
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 circleit is red.
  • 支持了不同类型的产品,更加灵活。
  • 缺点很明显,类膨胀越来越厉害。
1 @protocol AbstractFactory <NSObject>
2 
3 - (id<AbstractLine>)createLine;
4 - (id<AbstractPie>)createPie;

}

  客户端调用代码:

3、抽象工厂模式(Abstract Factory)

编辑:互联网科技 本文来源:设计模式——工厂模式

关键词: