博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【设计模式】(三)工厂模式(Factory Pattern)
阅读量:2039 次
发布时间:2019-04-28

本文共 4796 字,大约阅读时间需要 15 分钟。

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

1. 简单工厂模式

1.1 简单工厂的介绍

顾名思义,这个模式本身很简单,而且使用在业务较简单的情况下。

它由三种角色组成(关系见下面的类图):

  1. 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
  2. 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
  3. 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。

1.2 简单工厂的结构

1.3 简单工厂的实现

创建一个产品接口:

package com.siyi.simplefactory;public interface Shape {    void draw();}

创建产品类:

package com.siyi.simplefactory;public class Rectangle implements Shape {    @Override    public void draw() {        System.out.println("Inside Rectangle::draw() method.");    }}
package com.siyi.simplefactory;public class Square implements Shape {    @Override    public void draw() {        System.out.println("Inside Square::draw() method.");    }}
package com.siyi.simplefactory;public class Circle implements Shape {    @Override    public void draw() {        System.out.println("Inside Circle::draw() method.");    }}

创建一个工厂类:

package com.siyi.simplefactory;public class ShapeFactory {    //使用 getShape 方法获取形状类型的对象    public static Shape getShape(String shapeType) {        if (shapeType == null) {            return null;        }        if (shapeType.equalsIgnoreCase("CIRCLE")) {            return new Circle();        } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {            return new Rectangle();        } else if (shapeType.equalsIgnoreCase("SQUARE")) {            return new Square();        }        return null;    }}

Main方法执行查看效果:

package com.siyi.simplefactory;public class Main {    public static void main(String[] args) {        //获取 Circle 的对象,并调用它的 draw 方法        Shape shape1 = ShapeFactory.getShape("CIRCLE");        //调用 Circle 的 draw 方法        shape1.draw();        //获取 Rectangle 的对象,并调用它的 draw 方法        Shape shape2 = ShapeFactory.getShape("RECTANGLE");        //调用 Rectangle 的 draw 方法        shape2.draw();        //获取 Square 的对象,并调用它的 draw 方法        Shape shape3 = ShapeFactory.getShape("SQUARE");        //调用 Square 的 draw 方法        shape3.draw();    }}

运行结果:

Inside Circle::draw() method.Inside Rectangle::draw() method.Inside Square::draw() method.

1.4 简单工厂的优缺点

优点:

  • 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象
  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
  • 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

缺点:

  • 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
  • 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
  • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,同样破坏了“开闭原则”;在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护
  • 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构

2. 工厂方法模式

2.1 工厂方法的介绍

工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。

工厂方法模式组成:

  1. 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
  2. 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
  3. 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
  4. 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有 的代码。可以看出工厂角色的结构也是符合开闭原则的!

2.2 工厂方法的结构

2.3 工厂方法的实现

生产不同产品工厂的抽象类:

package com.siyi.factorymethod;public interface PhoneFactory {    Phone makePhone();}

生产手机的工厂(ConcreteFactory):

package com.siyi.factorymethod;public class ApplePhoneFactory implements PhoneFactory {    @Override    public Phone makePhone() {        return new IPhone();    }}--------------------------------------------------------------package com.siyi.factorymethod;public class XiaoMiPhoneFactory implements PhoneFactory {    @Override    public Phone makePhone() {        return new XiaoMi();    }}

具体手机对应的类:

package com.siyi.factorymethod;public class XiaoMi implements Phone {    public XiaoMi() {    }        @Override    public void show() {        // TODO Auto-generated method stub        System.out.println("make xiaomi phone!");    }}-------------------------------------------------------package com.siyi.factorymethod;public class IPhone implements Phone {    public IPhone() {    }        @Override    public void show() {        // TODO Auto-generated method stub        System.out.println("make iphone!");    }}

Main:

package com.siyi.factorymethod;public class Main {    public static void main(String[] arg) {        Phone xiaoMiPhone = new XiaoMiPhoneFactory().makePhone();        Phone applePhone = new ApplePhoneFactory().makePhone();        xiaoMiPhone.show();        applePhone.show();    }}

运行结果:

make xiaomi phone!make iphone!

2.4 工厂方法的优缺点

优点:

  1. 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户端隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需要产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
  2. 基于工厂角色和产品角色的多态性设计是工厂方法的关键,他能够让工厂模式自主的创建产品对象,而如何创建这个对象的细节完全封装在工厂类。
  3. 使用工厂方法模式最大的优点就是你新加类的时候不用动源代码,只要写新的产品新的工厂来继承对应的类就行了。

缺点:

  1. 假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦。比如说,每增加一个产品,相应的也要增加一个子工厂,会加大了额外的开发量。

转载地址:http://iryof.baihongyu.com/

你可能感兴趣的文章
CCColorLayer [[[self alloc] initWithColor:color]报错
查看>>
Markdown语法
查看>>
iOS Assembly Tutorial: Understanding ARM
查看>>
Mac下用命令行直接批量转换文本编码到UTF8
查看>>
【GAN实战】chapter1 GAN简介
查看>>
【python】python解决视频转音频
查看>>
vim基本操作
查看>>
ctags的基本使用
查看>>
linux基本命令
查看>>
使用taglist插件
查看>>
adb调试
查看>>
在Android上安装busybox工具包
查看>>
cscope
查看>>
基于linux搭建sshd
查看>>
基于linux搭建zmodem服务
查看>>
基于linux搭建samba服务
查看>>
基于linux搭建TFTP服务
查看>>
基于linux搭建NFS服务
查看>>
ubuntu下配置交叉编译器
查看>>
BeagleBone Black入门
查看>>