工厂模式详解

在java中每当看到new 就会想到“具体”,代码绑定着具体的类导致代码脆弱尤其是不利于进行修改. new 关键字本身没有错,需要的是我们针对接口编程,从而隔离掉系统可能发生的一系列改变。重要设计原则:对扩展开放,对修改关闭。

Pizza orderPizza(String type) {
	Pizza pizza;
	if (type.equals(“cheese”)) {
		pizza = new CheesePizza();
	} else if (type.equals(“greek”) {
		pizza = new GreekPizza();
	} else if (type.equals(“pepperoni”) {
		pizza = new PepperoniPizza();
	} else if (type.equals(“clam”) {
		pizza = new ClamPizza();
	} else if (type.equals(“veggie”) {
		pizza = new VeggiePizza();
	}
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
}

披萨预定系统上面所看到,if -else部分代码随着菜单改变需要经常变动,而下面部分代码是不需要改变的,知道哪些改变哪些不变,我们需要进行封装啦!

建立一个SimplePizzaFactory类,当需要披萨时就要工厂做一个,orderPizza()方法则不需要知道到底是什么类型披萨。

public class SimplePizzaFactory {
	public Pizza createPizza(String type) {
	Pizza pizza = null;
	if (type.equals(“cheese”)) {
	pizza = new CheesePizza();
	} else if (type.equals(“pepperoni”)) {
	pizza = new PepperoniPizza();
	} else if (type.equals(“clam”)) {
	pizza = new ClamPizza();
	} else if (type.equals(“veggie”)) {
	pizza = new VeggiePizza();
	}
	return pizza;
	}
}

SimplePizzaFactory类只做一件事根据用户传进来的参数创建披萨,这样如果发生改变每次直接修改SimplePizzaFactory类,比先前写在用户代码中维护性要提高一些。

修改我们客户端代码为:

public class PizzaStore {
	SimplePizzaFactory factory;
	public PizzaStore(SimplePizzaFactory factory) {
	this.factory = factory;
	}
	public Pizza orderPizza(String type) {
			Pizza pizza;
			pizza = factory.createPizza(type);
			pizza.prepare();
			pizza.bake();
			pizza.cut();
			pizza.box();
			return pizza;
	}
		// other methods here
}

orderPizza()方法通过简单传入披萨类型使用工厂创建披萨。pizza = factory.createPizza(type);把new操作符替换为对象创建方法,这里不再使用具体实例化,解耦合。

定义简单工厂:上述用到的思想简单工厂其实不是一种设计模式,反而像是一种编程习惯,通过看上述披萨店的实现类图,能更好理解问题!

小概念:设计模式中,实现一个接口并不一定只是指 implement 实现某个java接口,而是泛指实现某个超类型(可以是类或接口)的某个方法。

现在需求是加盟披萨店:加盟店需要提供不同风味的披萨(纽约、芝加哥、加州。。。)现在样子会变成如下:

NYPizzaFactory nyFactory = new NYPizzaFactory();

PizzaStore nyStore = new PizzaStore(nyFactory);

nyStore.order(“Veggie”);

ChicagoPizzaFactory chicagoFactory = new ChicagoPizzaFactory();

PizzaStore chicagoStore = new PizzaStore(chicagoFactory);

chicagoStore.order(“Veggie”);

现在想实现目标就是:加盟店和创建披萨在一起同时还能保持弹性。看看PizzaStore的改变

package factoryMethod;

public abstract class PizzaStore {

	abstract Pizza createPizza(String item);

	public Pizza orderPizza(String type) {
		Pizza pizza = createPizza(type);
		System.out.println("--- Making a " + pizza.getName() + " ---");
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
	}
}

abstract Pizza createPizza(String item);可以看到PizzaStore现在作为超类;让NYPizzaStore, ChicagoPizzaStore,CaliforniaPizzaStore都继承它,每个子类各自决定如何制造披萨。下图看到具体怎么进行

NYPizzaStore, ChicagoPizzaStore具体实现代码如下:

package factoryMethod;

public class NYPizzaStore extends PizzaStore {

	Pizza createPizza(String item) {
		if (item.equals("cheese")) {
			return new NYStyleCheesePizza();
		} else if (item.equals("veggie")) {
			return new NYStyleVeggiePizza();
		} else if (item.equals("clam")) {
			return new NYStyleClamPizza();
		} else if (item.equals("pepperoni")) {
			return new NYStylePepperoniPizza();
		} else
			System.out.println("parameter is wrong ");
			return null;
	}
}
package factoryMethod;

public class ChicagoPizzaStore extends PizzaStore {

	Pizza createPizza(String item) {
        	if (item.equals("cheese")) {
            		return new ChicagoStyleCheesePizza();
        	} else if (item.equals("veggie")) {
        	    	return new ChicagoStyleVeggiePizza();
        	} else if (item.equals("clam")) {
        	    	return new ChicagoStyleClamPizza();
        	} else if (item.equals("pepperoni")) {
            		return new ChicagoStylePepperoniPizza();
        	} else return null;
	}
}

说了这么多,忽略了一件事就是披萨本身!

<strong>package factoryMethod;

import java.util.ArrayList;

public abstract class Pizza {
	String name;
	String dough;
	String sauce;
	ArrayList<String> toppings = new ArrayList<String>();

	void prepare() {
		System.out.println("Preparing " + name);
		System.out.println("Tossing dough...");
		System.out.println("Adding sauce...");
		System.out.println("Adding toppings: ");
		for (int i = 0; i < toppings.size(); i++) {
			System.out.println("   " + toppings.get(i));
		}
	}

	void bake() {
		System.out.println("Bake for 25 minutes at 350");
	}

	void cut() {
		System.out.println("Cutting the pizza into diagonal slices");
	}

	void box() {
		System.out.println("Place pizza in official PizzaStore box");
	}

	public String getName() {
		return name;
	}

	public String toString() {
		StringBuffer display = new StringBuffer();
		display.append("---- " + name + " ----\n");
		display.append(dough + "\n");
		display.append(sauce + "\n");
		for (int i = 0; i < toppings.size(); i++) {
			display.append((String) toppings.get(i) + "\n");
		}
		return display.toString();
	}
}
</strong>

现在简单的列出一些具体披萨子类:

package factoryMethod;

public class NYStyleCheesePizza extends Pizza {

	public NYStyleCheesePizza() {
		name = "NY Style Sauce and Cheese Pizza";
		dough = "Thin Crust Dough";
		sauce = "Marinara Sauce";
		toppings.add("Grated Reggiano Cheese");
	}
}

。。。子类实现还有很多。

现在开始正式认识工厂方法模式:

上图是创建者类图,下面给出产品类类图:

工厂模式的定义:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

这里披萨工厂模式完整的类图:

下面是一些重要的设计原则:

package net.dp.factory.factoryMethod;

public class DependentPizzaStore {

	public Pizza createPizza(String style, String type) {
		Pizza pizza = null;
		if (style.equals("NY")) {
			if (type.equals("cheese")) {
				pizza = new NYStyleCheesePizza();
			} else if (type.equals("veggie")) {
				pizza = new NYStyleVeggiePizza();
			} else if (type.equals("clam")) {
				pizza = new NYStyleClamPizza();
			} else if (type.equals("pepperoni")) {
				pizza = new NYStylePepperoniPizza();
			}
		} else if (style.equals("Chicago")) {
			if (type.equals("cheese")) {
				pizza = new ChicagoStyleCheesePizza();
			} else if (type.equals("veggie")) {
				pizza = new ChicagoStyleVeggiePizza();
			} else if (type.equals("clam")) {
				pizza = new ChicagoStyleClamPizza();
			} else if (type.equals("pepperoni")) {
				pizza = new ChicagoStylePepperoniPizza();
			}
		} else {
			System.out.println("Error: invalid type of pizza");
			return null;
		}
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
	}
}

上面这段代码我们可以清楚看到createPizza将依赖8个具体类,很清楚减少代码中的依赖是好事;设计原则:要依赖抽象,不要依赖具体类

应用上面的原则可以把createPizza将依赖8个具体类进行修正为如下图:

几个指导方针帮助遵循上述原则:

(1)变量不可以持有具体类的引用。(如果使用new 就会持有具体类的引用,可以改用工厂避开)

(2)不要让类派生自具体类。(如果派生自具体类,就会依赖具体类。请派生自一个抽象(前面说了抽象是广义指接口或者抽象类))

(3)不要覆盖基类中已实现的方法。

需要清楚的是要完全遵守这些指导方针是不可能的,只能说应该尽量去遵守这个原则,我们知道任何java程序都有违反指导方针的地方!

举例说,如果一个不太会改变的类,那么在代码中直接初始化没什么问题。想想实例化字符串对象。

这里是工厂模式代码免积分下载:http://download.csdn.net/detail/huruzun/7391259

工厂模式详解

时间: 2024-11-07 15:09:16

工厂模式详解的相关文章

Java研究之学习设计模式-简单工厂模式详解

 简介: 从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例. 类图: 从UML类图中,可以看出,简单工厂模式的意思,就是把一个类内部,需要生成的部分,提取出来,变为一个工厂,通过工厂来new对象. 假设我们要吃苹果了,我们可以在代码中new一个苹果出来:当我们需要吃香蕉了,我们在代码中new一个香蕉出来.这种做法你会不会觉得麻烦

Java研究之学习设计模式-抽象工厂模式详解

 简介:          当每个抽象产品都有多于一个的具体子类的时候,工厂角色怎么知道实例化哪一个子类呢?比如每个抽象产[1] 品角色都有两个具体产品.抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化.每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例. 每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构:而抽象工厂模式针对的是多个产品等级结构.(摘自百度百科) 话语说得太抽象,程序员最好的表示方式

创建和使用解耦——工厂模式详解(工厂方法+抽象工厂)

1.前言 直接new一个对象是最简单的创建对象的方式,但大量出现在业务代码中会带来至少两个问题.1:创建对象的细节直接暴露在业务代码中,修改实现细节必须修改相关的大量客户端代码.2:直接面向具体类型编程,违反了面向接口编程的原则,系统进行扩展时也不得不进行大量修改.要使得系统具有的良好的可扩展性以及后期易于维护,必须实现对产品的获取和对产品的使用解耦.要做到这两点,首先要对客户端代码屏蔽掉创建产品的细节,其次,客户端必须面向产品的抽象编程,利用java的多态特性在运行时才确定具体的产品.而这,正

二、设计模式总览及工厂模式详解

二.架构师内功心法之设计模式 2.架构师内功心法之设计模式 2.1.课程目标 1.通过对本章内容的学习,了解设计模式的由来. 2.介绍设计模式能帮我们解决哪些问题. 3.剖析工厂模式的历史由来及应用场景. 2.2.内容定位 不用设计模式并非不可以,但是用好设计模式能帮助我们更好地解决实际问题,设计模式最重要的 是解耦.设计模式天天都在用,但自己却无感知.我们把设计模式作为一个专题,主要是学习设计模式 是如何总结经验的,把经验为自己所用.学设计模式也是锻炼将业务需求转换技术实现的一种非常有效 的方

C++工厂模式详解——设计模式(2)

一.简单工厂模式: 简单工厂模式是工厂模式中最简单的一种,他可以用比较简单的方式隐藏创建对象的细节,一般只需要告诉工厂类所需要的类型,工厂类就会返回需要的产品类,但客户端看到的只是产品的抽象对象,无需关心到底是返回了哪个子类.客户端唯一需要知道的具体子类就是工厂子类.除了这点,基本是达到了依赖倒转原则的要求. 假如,我们不用工厂类,只用CreateOperate和它的子类,那客户端每次使用不同的子类的时候都需要知道到底是用哪一个子类,当类比较少的时候还没什么问题,但是当类比较多的时候,管理起来就

设计模式之 简单工厂模式详解

定义:从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例.简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现.             定义中最重要的一句话就是,由一个工厂对象决定创建出哪一种产品类的实例,这个LZ在下面会专门举一个现实应用中的例子去展现. 另外给出简单工厂模式的类图,本类图以及上面的

2018.4.4 设计模式之简单工厂模式与抽象工厂模式详解(一)

1设计模式 简介 设计模式时一套被反复使用的多数人知晓的.经过分类编目的.代码设计经验的总结.设计模式使代码设计真正工程化,模式是软件工程的基石. 2.什么是GOF(四人帮 . Gang of Four) Design Patterns-Elementes of ReusableObject -Oriented Software (中文译名:设计模式-可复用的面向软件元素) 四位作者合成GOF,他们所提出的设计模式主要是基于鱼虾的面向对象设计原则 对接口编程儿不是对实现编程: 优先使用对象组合而

JS设计模式——工厂模式详解

工厂模式是另外一种关注对象创建概念的创建模式.它的领域中同其它模式的不同之处在于它并没有明确要求我们使用一个构造器.取而代之,一个工厂能提供一个创建对象的公共接口,我们可以在其中指定我们希望被创建的工厂对象的类型. 简单工厂模式:使用一个类(通常为单体)来生成实例 复杂工厂模式:使用子类来决定一个变量成员应该为哪个具体的类的实例. 简单工厂模式 var BicycleShop = function () { }; BicycleShop.prototype = { sellBicycle: fu

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

一.简单工厂模式 简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类 的实例.属于创建型模式,但它不属于 GOF,23 种设计模式 (参考资料: http://en.wikipedia.org/wiki/Design_Patterns#Patterns_by_Type). 简单工厂模式适用于的场景: 1.适用 于工厂类负责创建的对象较少的场景,    2.且客户端只需要传入工厂类的参数,对于如何创 建对象的逻辑不需要关心. 简单工厂模式缺点: 1