模式目的

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

工厂方法模式将类的实例化延迟到了子类中进行。

模式结构

组成部分

  • 产品(Product)

    - 定义了产品功能的接口
  • 具体产品(ConcreteProduct)

    - 实现产品接口的具体产品
  • 工厂(Creator)

    - 定义了工厂功能的接口
  • 具体工厂(Concrete)

    - 实现工厂接口的具体工厂

java实现

采用工厂方法模式,实现一个汽车工厂生产奔驰、宝马汽车的例子

产品是汽车,定义接口为ICar

工厂是汽车工厂,定义接口为ICarFactory

代码UML类图如下:

使用宝马工厂的getInstance()方法创建宝马车,使用奔驰工厂的getInstance()方法创建奔驰车。

相关代码如下:

ICar.java

public interface ICar {
/**
* 实现类必须实现run()方法
**/
void run();
}

BmwCar.java

public class BmwCar implements ICar{
@Override
public void run() {
System.out.println("This is Bmw running");
}
}

BenzCar.java

public class BenzCar implements ICar{
@Override
public void run() {
System.out.println("This is Benz running");
}
}

ICarFactory.java

public interface ICarFactory {
/**
* 实现类必须实现getCar()方法
**/
ICar getCar();
}

BmwFactory.java

public class BmwFactory implements ICarFactory {
@Override
public ICar getCar() {
return new BmwCar();
}
}

BenzFactory.java

public class BenzFactory implements ICarFactory {
@Override
public ICar getCar() {
return new BenzCar();
}
}

客户端测试代码及输出如下:

Client.java

public class Client {
public static void main(String[] args) {
ICarFactory carFactory = new BenzFactory();
carFactory.getCar().run(); ICarFactory carFactory2 = new BmwFactory();
carFactory2.getCar().run();
}
}

输出结果:

This is Benz running
This is Bmw running

模式优点

  1. 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
  2. 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。
  3. 使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。

模式缺点

  1. 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
  2. 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。

总结

  1. 工厂方法模式又称为工厂模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
  2. 工厂方法模式包含四个角色:抽象产品是定义产品的接口,是工厂方法模式所创建对象的超类型,即产品对象的共同父类或接口;具体产品实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,它们之间往往一一对应;抽象工厂中声明了工厂方法,用于返回一个产品,它是工厂方法模式的核心,任何在模式中创建对象的工厂类都必须实现该接口;具体工厂是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户调用,返回一个具体产品类的实例。
  3. 工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了面向对象的多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责产品类被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
  4. 工厂方法模式的主要优点是增加新的产品类时无须修改现有系统,并封装了产品对象的创建细节,系统具有良好的灵活性和可扩展性;其缺点在于增加新产品的同时需要增加新的工厂,导致系统类的个数成对增加,在一定程度上增加了系统的复杂性。
  5. 工厂方法模式适用情况包括:一个类不知道它所需要的对象的类;一个类通过其子类来指定创建哪个对象;将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定。

[设计模式]工厂方法模式(Factory Method)的更多相关文章

  1. 大话设计模式--工厂方法模式 Factory Method -- C++实现

    1. 工厂方法模式 定义一个用于创建对象的接口, 让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 和简单工厂模式相比: A: 简单工厂模式最大的优点在于工厂类中包含有必要的逻辑判断, ...

  2. C#设计模式——工厂方法模式(Factory Method Pattern)

    一.概述在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口.如何应对这种变化?如何提供一种封装机制来隔离出“这个易变对象 ...

  3. 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern)

    原文:乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pa ...

  4. 设计模式-03工厂方法模式(Factory Method Pattern)

    插曲.简单工厂模式(Simple Factory Pattern) 介绍工厂方法模式之前,先来做一个铺垫,了解一下简单工厂模式,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背 ...

  5. 【设计模式】工厂方法模式 Factory Method Pattern

    在简单工厂模式中产品的创建统一在工厂类的静态工厂方法中创建,体现了面形对象的封装性,客户程序不需要知道产品产生的细节,也体现了面向对象的单一职责原则(SRP),这样在产品很少的情况下使用起来还是很方便 ...

  6. 二十四种设计模式:工厂方法模式(Factory Method Pattern)

    工厂方法模式(Factory Method Pattern) 介绍定义一个用于创建对象的接口,让子类决定将哪一个类实例化.Factory Method使一个类的实例化延迟到其子类. 示例有SqlMes ...

  7. 工厂方法模式-Factory Method(Java实现)

    工厂方法模式-Factory Method 工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法让实例化的具体内容交给子类工厂来进行. 本文中的例子是这样的. 生产一个身份证, ...

  8. IOS设计模式浅析之工厂方法模式(Factory Method)

    概述 在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何隔离出这个易变对象的变化,使得系统中“其它依赖该对象的对 ...

  9. 设计模式之工厂方法模式(Factory Method Pattern)

    一.工厂方法模式的诞生 在读这篇文章之前,我先推荐大家读<设计模式之简单工厂模式(Simple Factory Pattern)>这篇文档.工厂方法模式是针对简单工厂模式中违反开闭原则的不 ...

随机推荐

  1. 深入浅出-iOS Block原理和内存中位置

    Posted by 微博@Yangsc_o 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0 #简介 今天回顾一下blcok,基本 ...

  2. SQL--SQL详解(DDL,DML,DQL,DCL)

    SQL--SQL详解(DDL,DML,DQL,DCL) 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 什么是SQL? Stru ...

  3. Java——八种基本数据类型(常用类)

    装箱和拆箱 装箱:基本数据类型转为包装类 拆箱:包装类转为基本数据类型 jdk1.5(即jdk5.0)之后的版本都提供了自动装箱和自动拆箱功能 基本数据类型的包装类 举两个例子,看一下 public ...

  4. 动手造轮子:实现一个简单的 AOP 框架

    动手造轮子:实现一个简单的 AOP 框架 Intro 最近实现了一个 AOP 框架 -- FluentAspects,API 基本稳定了,写篇文章分享一下这个 AOP 框架的设计. 整体设计 概览 I ...

  5. sublime Text3 实现2:1:1三分屏效果

    小trick, 水一篇博客 先上效果图 由于写题啥的时候需要重定向输入输出改数据对拍, 设置成这样的效果就非常直观的看数据 直接切题, 首选项--快捷键--default里搜索alt+shift+1( ...

  6. CentOS7.5搭建Hive2.3.3

    一 Hive的下载 软件下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/hive/  这里下载的版本是:apache-hive-2.3.3-bin.t ...

  7. (九)maven-surefire-plugin常用配置

    原文链接:https://www.cnblogs.com/pixy/p/4718176.html 对maven-surefire-plugin有想了解的,看这篇:https://www.cnblogs ...

  8. MySQL 性能优化细节

    服务器层面优化(了解) 将数据保存在内存中,保证从内存读取数据 设置足够大的innodb_buffer_pool_size,将数据读取到内存中. 建议innodb_buffer_pool_size设置 ...

  9. 【Laravel】 常用的artisan命令

    全局篇 查看artisan命令php artisanphp artisan list 查看某个帮助命令php artisan help make:model 查看laravel版本php artisa ...

  10. 移动 Ubuntu16.04 桌面左侧的启动器到屏幕底部_设置方法

    通过命令行,对 Launcher 的位置进行一下调整. 按下 Ctrl + Alt + t 键盘组合键,调出终端,在终端中输入以下命令: gsettings set com.canonical.Uni ...