java设计模式:工厂方法模式(Factory Method)

工厂方法模式

返回设计模式目录

阅读目录:

  • 简单工厂模式

    • 介绍
    • UML类图
    • 参考代码
    • 总结
  • 工厂方法模式
    • 介绍
    • UML类图
    • 参考代码
    • 总结

前言:

  《大话设计模式》里有一小节叫‘活字印刷,面向对象‘的,讲了一个小故事,大意如下:

  话说三国时期,曹操带领大军驻扎于赤壁。军船相连,气势恢宏,眼看要灭掉东吴,统一天下,曹操甚悦,于是大宴群臣。席间曹操诗兴大发,不觉吟道:"喝酒唱歌,人生真爽。……"。众文武齐呼:"丞相好诗!"。于是一臣子速命印刷工匠刻板印刷,以便流传天下。

  样章出来曹操一看,感觉不妥,道:"喝与唱此话过俗,应该为‘对酒当歌‘较好!",于是此臣就命工匠重新来过,此工匠连夜之功就此白费,只得重刻之。

  样章再次出来请曹操过目,曹操细细一品,觉得还是不好,说:"人生真爽太过直接,应改问语才够意境,就改为‘对酒当歌人生几何?……‘吧"。当臣子转告工匠时,工匠晕倒。。。

  这里的问题是三国时期活字印刷还未发明,所以改字的时候,就必须整块板全部重刻!如果有了活字印刷,则只需更改四个字即可,其余工作均未白做。

  第一,要改只需更改要改之字,此为可维护;第二,这些字并非这次用完就无用,完全可以在后来的印刷中重复使用,此乃可复用;第三此诗若要加字,只需另刻字加入即可,这是可扩展;第四字的排列其实可能竖排可能横排,此时只需将活字移动即可满足排列需求,此是灵活性好。编写代码时多考虑封装,继承,多态把程序的耦合度降低,使用面向对象思想使得程序更加的灵活,容易修改,并且易于复用。

  好了,说了这么多,相信大家对设计模式多少有点感觉了。不错,设计模式就是为了让我们的代码更灵活,易扩展,好维护和能复用。现在我们就先从工厂模式总结吧!

一、简单工厂模式

1.介绍

  总结工厂模式之前先得说说简单工厂模式。简单工厂模式(又名静态工厂方法),不属于GOF的23种设计模式之一。这种模式将创建对象的责任交由一个工厂对象,该工厂对象提供静态公有方法向外提供生成对象的服务,所有生成对象的逻辑均包含在该静态方法里,对外不可见。简单工厂是工厂模式里最好理解的模式了,可以将其看作所有工厂模式的基础。

2.UML类图

  假装这里有类图

3.参考代码

//这是客户端,
public class Client {
	public static void main(String[] args) {
		// 客户端只需要传入需要的产品类型,就能得到对应的产品,用户不需要知道创建产品的细节
		Product product = SimpleFactory.create("A");
		// Product product = SimpleFactory.create("B");

		// 调用生成产品的显示价格方法
		product.showPrice();
	}
}

/**
 * 抽象产品角色
 *
 * @author ICE_melt
 *
 */
interface Product {
	// 显示产品价格
	public void showPrice();
}

// 具体产品A
class ConcreateProductA implements Product {

	@Override
	public void showPrice() {
		System.out.println("这是A产品,价格为10RMB,很便宜");

	}
}

// 具体产品B
class ConcreateProductB implements Product {

	@Override
	public void showPrice() {
		System.out.println("这是B产品,价格为600RMB,很贵的");

	}
}

/**
 * 工厂角色(即普通类提供了创建其他类的方法)
 *
 * @author ICE_melt
 *
 */
class SimpleFactory {
	/**
	 * 	简单工厂一般为静态方法,其内包含必要的逻辑判断,能够根据客户端的条件创建具体的产品对象
	 * <br><b>剖析:</b>
	 * <br>现在的产品都是基于<code>Product<code>接口的子类,如果增加产品,继承体系没有问题
	 * <br>但是工厂生成逻辑需要修改(增加if分支判断逻辑),这一点违背了“开放封闭原则”
	 */
	public static Product create(String type) {
		if ("A".equals(type)) {
			return new ConcreateProductA();
		} else if ("B".equals(type)) {
			return new ConcreateProductB();
		} else {
			new RuntimeException(type + "产品类型暂时不能生产,请联系生产厂商!");
		}
		return null;
	}
}

4.总结

  简单工厂模式的优点是分离了产品的创建者和使用者,有利于软件系统结构的优化。局限是有需求变动时不修改代码的话是不能够扩展的。

返回顶部

 二、工厂方法模式

1.介绍

  工厂方法模式,又叫做多态性工厂。该模式定义一个用于创建对象的接口,让子类决定实例化那一个产品对象。工厂方法使一个类的实例化延迟到其子类。

2.UML类图

  假装有类图

3.参考代码

  首先是抽象产品类:

/**
 * 产品抽象
 *
 * @author ICE_melt
 *
 */
public abstract class AbstractProduct {

	public AbstractProduct() {
	}

	// 所有产品都有对外展示的方法
	public abstract void display();

}

  基础抽象产品类的三种产品:

//产品--汽车
public class CarProduct extends AbstractProduct {

	@Override
	public void display() {
		System.out.println("我有四个轮子,在陆地上跑的飞快");

	}

}
//产品--飞机
public class AirplaneProduct extends AbstractProduct {

	@Override
	public void display() {
		System.out.println("我有两个机翼,能在天上飞");

	}

}
//产品--轮船
public class ShipProduct extends AbstractProduct {

	@Override
	public void display() {
		System.out.println("我在海里,速度很快");

	}

}

  然后是工厂接口:

/**
 * 一个工厂接口,负责定义产品对象的生产
 * (工厂接口也可以用抽象方法实现)
 * @author ICE_melt
 *
 */
public interface IFactory {
	/*
	 *
	 * 创建一个产品对象
	 */
	public AbstractProduct produceProduct();
}

  工厂接口的三个具体工厂,每个工厂负责生产一种产品:

//汽车工厂,生产汽车
public class CarFactory implements IFactory {

	@Override
	public AbstractProduct produceProduct() {
		return new CarProduct();
	}

}
//飞机工厂,生产飞机
public class AirplaneFactory implements IFactory {

	@Override
	public AbstractProduct produceProduct() {
		return new AirplaneProduct();
	}

}
//轮船工厂,生产轮船
public class ShipFactory implements IFactory {

	@Override
	public AbstractProduct produceProduct() {
		return new ShipProduct();
	}

}

  客户端代码:

/**
 * 客户端代码
 * @author ICE_melt
 *
 */
public class Client {

	public static void main(String[] args) {
		//这里可以将工厂类的全路径类名写到项目的配置文件里,并添加一个读取该配置的方法
		String factoryConfig = readConfig();
		IFactory factory;
		try {
			//客户端代码只与抽象工厂 和 抽象产品 这两个顶级接口耦合,
			//后台增加 一种新的产品的话,只需要同时增加 该产品的工厂类,
			//不需要修改任何已存在的代码
			factory = (IFactory)Class.forName(factoryConfig).newInstance();
			AbstractProduct product = factory.produceProduct();
			product.display();
		} catch (Exception e) {
			//异常处理
			e.printStackTrace();
		}

	}

	public static String readConfig(){
		//可以将工厂类名全路径写到配置文件里,这样客户端无需
		//更改代码,只需配置即可完成不用产品的的展示需求
		return "com.icemelt.designpattern.factorymethod.AirplaneFactory";
	}
}

4.总结

  工厂方法首先需要屏蔽产品类的具体实现,产品类如何变化,调用者都不需要关心,只需关心产品类的接口,通常接口是相对稳定,只要此接口不发生变化,那么系统上层就不会发生变化(这也是面向接口编程的好处)。其次需要屏蔽工厂方法的具体实现,道理同前。然后我们就能享受工厂方法给代码带来的灵活性的好处:此时所有客户端代码只与两个抽象类(或接口)有关,增加产品只需完成该产品和对应工厂方法的编码工作即可完成需求增加(不需要修改客户端代码和后台已存在的代码,客户需要新增功能只需修改配置即可)

  通常实际应用中业务逻辑会比较复杂,产品类可能并没有统一的接口(也有可能是历史遗留原因),这时候需要想办法加上一层统一的间接关系后才能继续应用本模式。

返回顶部

时间: 2024-10-02 18:21:47

java设计模式:工厂方法模式(Factory Method)的相关文章

php设计模式——工厂方法模式(Factory Method)

二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 1 <?php 2 /* 3 * php设计模式——工厂方法模式(Factory Method) 4 */ 5 6 7 /* 8 * IAp

Android设计模式——工厂方法模式(Factory Method)

二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 1 package com.example.main; 2 3 import android.app.Activity; 4 import

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

插曲.简单工厂模式(Simple Factory Pattern) 介绍工厂方法模式之前,先来做一个铺垫,了解一下简单工厂模式,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背"开闭原则". 1.模式动机 考虑一个简单的软件应用场景,一个软件系统可以提供多个外观不同的按钮(如圆形按钮.矩形按钮.菱形按钮等),这些按钮都源自同一个基类,不过在继承基类后不同的子类有不同的实现方式从而使得它们可以呈现不同的外观,如果我们希望在使用这些按钮时,不需要知道这些具体按钮类的

工厂方法模式(Factory Method Pattern)

2. 工厂方法模式(Factory Method Pattern) 2.1. 模式动机 现在对该系统进行修改,不再设计一个按钮工厂类来统一负责所有产品的创建,而是将具体按钮的创建过程交给专门的工厂子类去完成,我们先定义一个抽象的按钮工厂类,再定义具体的工厂类来生成圆形按钮.矩形按钮.菱形按钮等,它们实现在抽象按钮工厂类中定义的方法.这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引进新的产品,如果出现新的按钮类型,只需要为这种新类型的按钮创建一个具体的工厂类就可以获得该新按钮的实例,这一

工厂模式--工厂方法模式(Factory Method Pattern)

2.1. 模式动机 现在对该系统进行修改,不再设计一个按钮工厂类来统一负责所有产品的创建,而是将具体按钮的创建过程交给专门的工厂子类去完成,我们先定义一个抽象的按钮工厂类,再定义具体的工厂类来生成圆形按钮.矩形按钮.菱形按钮等,它们实现在抽象按钮工厂类中定义的方法.这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引进新的产品,如果出现新的按钮类型,只需要为这种新类型的按钮创建一个具体的工厂类就可以获得该新按钮的实例,这一特点无疑使得工厂方法模式具有超越简单工厂模式的优越性,更加符合"开闭

设计模式之六:工厂方法模式(Factory method Pattern)

工厂方法(Factory Method)模式就是定义一个创建对象的工厂接口,将实际创建工作推迟到子类当中. 核心工厂类不再负责具体产品的创建,仅提供了具体工厂子类必须实现的接口,这样核心类成为一个抽象工厂角色,这样做的好处是工厂方法模式可以使系统在不修改具体工厂角色的情况下进行引进新的产品. 在Factory Method模式中,工厂类与产品类往往具有平行的等级结构,它们之间一一对应. 从上图可以看出,工厂方法模式有四个角色: 抽象工厂角色(ICreator):是工厂方法模式的核心,与应用程序无

《转》java设计模式--工厂方法模式(Factory Method)

本文转自:http://www.cnblogs.com/archimedes/p/java-factory-method-pattern.html 工厂方法模式(别名:虚拟构造) 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method使一个类的实例化延迟到其子类. 概述 当系统准备为用户提供某个类的子类的实例,又不想让用户代码和该子类形成耦合时,就可以使用工厂方法模式来设计系统.工厂方法模式的关键是在一个接口或抽象类中定义一个抽象方法,该方法返回某个类的子类的实例,该

Java设计模式-工厂方法模式(Factory Method)

工厂方法模式(Factory Method) 工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建.在以下的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式. 1:普通工厂模式 就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建 例,按下图写一个普通工厂方法模式 首先,创建共同接口sender public interface Sender

Java设计模式——工厂方法模式(factory method)

工厂方法模式是类的创建模式,用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中. 相信很多人都做过导入导出功能,就拿导出功能来说.有这么一个需求:某一个系统需要支持对数据库中的员工薪资进行导出,并且支持多种格式如:HTML.Excel.PDF等,每种格式导出的结构有所不同,比如:财务跟其他人对导出薪资的HTML格式要求可能会不一样,因为财务可能需要特定的格式方便核算或其他用途.如果使用简单工厂模式,则工厂类必定过于臃肿.因为简单工厂模式只有一个工厂类,它需要处理所有的创建的逻辑.假

Java设计模式-工厂方法模式(Virtual Constructor/Polymorphic Factory)

工厂方法模式(Virtual Constructor/Polymorphic Factory) 工厂方法模式是类的创建模式,又叫做虚拟构造子模式(Virtual Constructor)或者多态性工厂模式(Polymorphic Factory). 工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中. 那么工厂方法模式是在什么场景下使用呢?下面就举例说明: 相信很多人都做过导入导出功能,就拿导出功能来说.有这么一个需求:XX系统需要支持对数据库中的员工薪资进行导出,并