原文地址:Java 设计模式之工厂模式(二)

博客地址:http://www.extlight.com

一、背景

本篇内容是 Java 设计模式创建型模式的第二篇。上一篇主题为 《Java 设计模式之单例模式(一)》

二、简单介绍

在介绍工厂模式之前,我们需要了解设计模式中应该遵循的原则。

五大原则:

  1. 单一职责原则(SRP):就一个类而言,应该仅有一个引起它变化的原因。即一个类中应该只有一类逻辑。

  2. 开放-封闭原则(OCP):软件实体(类、模块、函数等等)应该可以扩展,但是不可修改。即开放扩展,封闭修改。

  3. 依赖倒转原则(DIP):高层模块不应该依赖底层模块。两个都应该依赖抽象;抽象不应该依赖细节。细节应该依赖抽象。即面向接口编程,而不是面向实现编程。

  4. 里氏代换原则(LSP):子类型必须能够替换掉他们的父类型。

  5. 合成/聚合复用原则(CARP):尽量使用合成/聚合,尽量不要使用类继承。

迪米特法则:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一方法的话,可以通过第三者转发这个调用

三、实现方式

工厂模式有 3 种:简单工厂模式、工厂方法模式和抽象工厂模式。

本篇文章只讲解简单工厂模式、工厂方法模式。因为简单工厂模式和工厂方法模式是针对单独一类产品的创建方式,而抽象工厂模式是针对产品族考虑。

我们以创建轿车为例,未使用工厂模式:

public abstract class Car {

	public abstract void run();
} public class Benz extends Car { @Override
public void run() {
System.out.println("开奔驰");
} } public class Bmw extends Car{ @Override
public void run() {
System.out.println("开宝马");
} } public class Client { public static void main(String[] args) {
Car car1 = new Benz();
car1.run(); Car car2 = new Bmw();
car2.run();
}
}

在 Client 类中既有创建对象逻辑又有调用方法逻辑,且与多个类发生耦合。违背了单一职责原则和迪米特法则。

UML 类图表示如下:

3.1 简单工厂模式

简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

工厂类:

public class CarFactory {

	public static Car createCar(String type) {
Car car = null;
switch (type) {
case "benz":
car = new Benz();
break;
case "bmw":
car = new Bmw();
break;
} return car;
}
}

客户端调用:

public class Client {

	public static void main(String[] args) {

		Car car1 = CarFactory.createCar("benz");
car1.run(); Car car2 = CarFactory.createCar("bmw");
car2.run(); }
}

总结:Client 类与 Car 的子类解耦,它不需要知道 Car 实例具体创建细节,只需要通知工厂类需要怎样的实例。这样,减少了与外部类(Car 的子类)的通信,遵循了迪米特法则。

UML 类图表示如下:

3.2 工厂方法模式

简单工厂模式设计和使用非常简单。当我们需要新品牌的车子(如:奥迪)时,只需要在 CarFactory 的静态方法中添加一个判断即可。但是,这种写法违背了开放封闭原则,我们在编码是尽量不要修改业务代码。

为了解决这一问题,我们可以使用工厂方法模式。

工厂方法模式同样属于类的创建型模式又被称为多态工厂模式。工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。

创建父类工厂:

public interface CarFactory {

	Car createCar();
}

工厂实现类:

public class BenzFactory implements CarFactory {

	@Override
public Car createCar() {
return new Benz();
} } public class BmwFactory implements CarFactory { @Override
public Car createCar() {
return new Bmw();
} }

客户端调用:

public class Client {

	public static void main(String[] args) {

	    CarFactory cf1 = new BenzFactory();
Car car1 = cf1.createCar();
car1.run(); CarFactory cf2 = new BmwFactory();
Car car2 = cf2.createCar();
car2.run();
}
}

当我们需要添加奥迪车时,创建 Audi 实体类继承 Car 和 AudiFactory 工厂类去实现 CarFactory 接口方法即可。

总结:不用修改业务代码,只需创建新的类即可实现功能扩展,遵循了开放封闭原则。但是,Client 类中出现创建对象逻辑,违背责任单一原则。每新增一类产品就需要创建 N 个类文件,增加项目结构的复杂度。

UML 类图表示如下:

Java 设计模式之工厂模式(二)的更多相关文章

  1. 浅析JAVA设计模式之工厂模式(二)

    1 工厂方法模式简单介绍 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory),在这样的模式中,核心工厂不再是一个详细的类.而是一个抽象工厂,提 ...

  2. 浅析JAVA设计模式之工厂模式(一)

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

  3. Java设计模式之工厂模式(Factory模式)介绍(转载)

    原文见:http://www.jb51.net/article/62068.htm 这篇文章主要介绍了Java设计模式之工厂模式(Factory模式)介绍,本文讲解了为何使用工厂模式.工厂方法.抽象工 ...

  4. java设计模式2————工厂模式

    1.工厂模式介绍: 1.1.实现了创建者与调用者的分离 1.2.详细分类: 简单工厂模式 工厂方法模式 抽象工厂模式 1.3.所遵循的OOP原则: 开闭原则:对扩展开放,对修改关闭 依赖倒转原则:面向 ...

  5. java 设计模式之工厂模式与反射的结合

    工厂模式: /**  * @author Rollen-Holt 设计模式之 工厂模式  */   interface fruit{     public abstract void eat(); } ...

  6. Java设计模式之-----工厂模式(简单工厂,抽象工厂)

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...

  7. Java设计模式之工厂模式(简单工厂模式+工厂方法模式)

    摘自http://blog.csdn.net/jason0539/article/details/23020989 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是 ...

  8. Java设计模式:工厂模式

    问题提出 Java的工厂模式与现实生活中的工厂的模型是很相似的.工厂是用来做什么?当然是用来生成产品.因此在Java的工厂模式的关键点就是如何描述好产品和工厂这2个角色之间的关系. 下面来仔细描述一下 ...

  9. JAVA 设计模式之 工厂模式详解

    一.简单工厂模式 简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类 的实例.属于创建型模式,但它不属于 GOF,23 种设计模式 (参考资料: ht ...

随机推荐

  1. Java集合详解8:Java的集合类细节精讲

    Java集合详解8:Java集合类细节精讲 今天我们来探索一下Java集合类中的一些技术细节.主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充.可能不全面,还请谅解. 本文参考:http:// ...

  2. canvas图形的组合与裁切

    当两个或两个以上的图形存在重叠区域时,默认情况下一个图形画在前一个图像之上.通过指定图像globalCompositeOperation属性的值可以改变图形的绘制顺序或绘制方式,globalAlpha ...

  3. python:小乌龟turtle

    turtle的意思是乌龟,也是python中自带的图形函数,使用turtle的方法也很形象,就好像在画布上有一个小乌龟(在画布上是一个箭头),然后你可以让它动来动去,它经过的地方就被留下了记号. 例如 ...

  4. 快速切题 poj 3026 Borg Maze 最小生成树+bfs prim算法 难度:0

    Borg Maze Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8905   Accepted: 2969 Descrip ...

  5. C# 解决串口接收数据不完整

    方法1: 使 用缓存机制完成.首先通过定义一个成员变量List<byte> buffer = new List<byte> (4096);用来存放所有的数据,在接收函数里,通过 ...

  6. PHP回调函数call_user_func()和call_user_func_array()的使用

    call_user_func():把第一个参数作为回调函数调用 用法:call_user_func ( callable $callback [, mixed $parameter [, mixed ...

  7. SpringMVC中的适配器

    适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作 适用场景: 1.已经存在的类的接口不符合我们的需 ...

  8. 表单隐藏域与display:none

    有时候前端进行表单填写是分步骤的,每一步的时候其他步骤相关的表单视图不可见: 针对"不可见",以下有两种处理方式: ①display:none 这种方式呢,比较简单,就是将三个步骤 ...

  9. TF随笔-8

    #!/usr/bin/env python2 # -*- coding: utf-8 -*- """ Created on Mon Jul 10 09:35:04 201 ...

  10. windows上操作git基本命令

    今天准备整理一下代码,重温一下Git的基本命令,好久不用忘得差不多了. 1. 进入某个目录: 进入D盘,然后进入D盘的名为git的文件夹: $ cd D: $ cd Git 2. 返回上一级目录: $ ...