`
king_tt
  • 浏览: 2233818 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

【设计模式】学习笔记6:抽象工厂模式(Abstract Factory)

阅读更多

 

 

 

本文出自 http://blog.csdn.net/shuangde800

 

 

——所有工厂都是用来封装对象的创建

——工厂是很有威力的技巧,帮助我们针对抽象编程,而不要针对具体类编程。

 

认识抽象工厂模式

在之前的工厂模式已经创建了一个比萨工厂,但是真正要生产的产品——比萨,却还没有涉及到。

比萨店会生产很多不同的比萨产品,而比萨又有格式不同风格的原料。

所以,我们要建造一个工厂来生产原料,这个工厂将负责创建原料家族中的每一个原料:酱料、芝士、面团等。

 

开始先为工厂定义一个接口,这个接口负责创建所有的原料:

 

public interface PizzaIngredientFactory {

	// 接口中,每个原料都有一个对应的方法创建该原料
	// 下面方法返回各原料对象
	public Dough createDough();
	public Sauce createSauce();
	public Cheese createCheese();
	public Veggies[] createVeggies();
	public Pepperoni createPepperoni();
	public Clams createClam();
 
}

 

 

下面要做的是:

1、给每个比萨店建造一个工厂。需要创建实现PizzaIngredientFactory接口的类,实现接口的方法。

2、实现一组原料类供工厂使用。

3、把这一切组织起来,将新的原料工厂整合进旧的PizzaStore中。

 

下面创建了纽约原料工厂,实现了PizzaIngredientFactory接口:

 

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
 
	public Dough createDough() {
		return new ThinCrustDough();
	}
 
	public Sauce createSauce() {
		return new MarinaraSauce();
	}
 
	public Cheese createCheese() {
		return new ReggianoCheese();
	}
 
	public Veggies[] createVeggies() {
		Veggies veggies[] = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() };
		return veggies;
	}
 
	public Pepperoni createPepperoni() {
		return new SlicedPepperoni();
	}

	public Clams createClam() {
		return new FreshClams();
	}
}



 

然后就可以重新定义“比萨”,这个抽象类:

 

public abstract class Pizza {
	String name;

	Dough dough;
	Sauce sauce;
	Veggies veggies[];
	Cheese cheese;
	Pepperoni pepperoni;
	Clams clam;

	abstract void prepare();//把prepare申明为抽象,在这个方法中,需要手机比萨所需的原料,而这些原料当然是来自原料工厂了

	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");
	}

	void setName(String name) {
		this.name = name;
	}

	String getName() {
		return name;
	}

	public String toString() {
		StringBuffer result = new StringBuffer();
		result.append("---- " + name + " ----\n");
		if (dough != null) {
			result.append(dough);
			result.append("\n");
		}
		if (sauce != null) {
			result.append(sauce);
			result.append("\n");
		}
		if (cheese != null) {
			result.append(cheese);
			result.append("\n");
		}
		if (veggies != null) {
			for (int i = 0; i < veggies.length; i++) {
				result.append(veggies[i]);
				if (i < veggies.length-1) {
					result.append(", ");
				}
			}
			result.append("\n");
		}
		if (clam != null) {
			result.append(clam);
			result.append("\n");
		}
		if (pepperoni != null) {
			result.append(pepperoni);
			result.append("\n");
		}
		return result.toString();
	}
}



然后就是创建真正的比萨了! 比萨店生产的比萨都是继承自Pizza类,假设要生产一个奶酪比萨(CheesePizza):

 

 

// 这是应用了简单工厂模式
// 比萨要用到原料,把生产原料任务委托给了ingredientFactory工厂
public class CheesePizza extends Pizza {
	PizzaIngredientFactory ingredientFactory;
 
	public CheesePizza(PizzaIngredientFactory ingredientFactory) {
		this.ingredientFactory = ingredientFactory;
	}
        // 实现prepare方法
	void prepare() {
		System.out.println("Preparing " + name);
		dough = ingredientFactory.createDough();
		sauce = ingredientFactory.createSauce();
		cheese = ingredientFactory.createCheese();
	}
}

上面这个真正的比萨,是不是很眼熟?没错,起始就是简单工厂模式, Pizza利用相关的工厂生产原料。所生产的原料依赖所使用的工厂,Pizza类根本不关心这些原料,它只知道如何制作比萨。现在,Pizza和原料之间被解耦,无论原料工厂是在北京还是上海,Pizza类都可以轻易地复用。

 

最后,是时候让新的比萨店登场了!

 

public class NYPizzaStore extends PizzaStore {
 
	protected Pizza createPizza(String item) {
		Pizza pizza = null;
		
		// 原料工厂负责生产所有的原料
		PizzaIngredientFactory ingredientFactory = 
			new NYPizzaIngredientFactory();
 
		if (item.equals("cheese")) {
			
			pizza = new CheesePizza(ingredientFactory); // 把工厂传递给每一个比萨,以便使比萨能从工厂中取得原料
			pizza.setName("New York Style Cheese Pizza");
  
		} else if (item.equals("veggie")) {
 
			pizza = new VeggiePizza(ingredientFactory);
			pizza.setName("New York Style Veggie Pizza");
 
		} else if (item.equals("clam")) {
 
			pizza = new ClamPizza(ingredientFactory);
			pizza.setName("New York Style Clam Pizza");
 
		} else if (item.equals("pepperoni")) {

			pizza = new PepperoniPizza(ingredientFactory);
			pizza.setName("New York Style Pepperoni Pizza");
 
		} 
		return pizza;
	}



 

小结:

上面一连串代码到底做了什么?

其实就做了一件事,引入了新类型的工厂——抽象工厂,来创建比萨原料家族。

我们创建了接口类PizzaIngredientFactory,这个接口可以创建产品的家族,利用这个接口,我们的代码将从实际工厂解耦,以便在不同上下文中实现各式各样的工厂,制作出不同的产品。

 

定义抽象工厂模式

抽象工厂提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

 

抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道(或关心)实际产出的具体产品是什么。这样一来,客户就从具体的产品中解藕。

 

生产原料的类图:

 

我们可以发现抽象工厂主要是为“产品”而服务的。

 

 

抽象工厂的方法经常以工厂方法的方式实现(例如createDough(), createSource(),每个方法都被声明为抽象,而子类的方法覆盖这些方法来创建某些对象),抽象工厂的任务是定义一个负责创建一组产品的接口。这个接口内的每个方法都负责创建一个具体产品,同时我们利用实现抽象工厂的子类来提供这些具体的做法,所以,在抽象工厂中利用工厂方法实现生产的做法是相当自然的做法。

 

 

比较工厂方法和抽象工厂

 

抽象工厂和工厂方法都是负责创建对象,但工厂方法用的是继承,而抽象方法用的是对象的组合

利用工厂方法创建对象,需要拓展一个类,并覆盖它的工厂方法。整个工厂方法模式,只不过就是通过子类来创建对象。用这种做法,客户只需要知道他们所使用的抽象类型就可以了,而由子类负责决定具体的类型,将客户从具体类型中解耦。

而抽象工厂用来创建一个产品家族的抽象类型,这个类型的子类定义了产品被产生的方法。要想使用这个工厂,必须先实例化它,然后将它传入一些针对抽象类型所写的代码中。所以和工厂方法一样,也实现解耦。

总之,他们都能将对象的创建封装起来,使应用程序解耦,并降低对特定实现的依赖。

 

 

 

 

分享到:
评论

相关推荐

    设计模式学习笔记

    3. 抽象工厂模式(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。 4. 建造者模式(Builder):将复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示...

    23种设计模式学习笔记及源码

    这个压缩包文件包含了23种设计模式的学习笔记和源码,旨在帮助开发者深入理解并熟练运用这些模式。以下是对每种设计模式的详细解释,以及它们在Java编程中的应用。 1. **单例模式**:确保一个类只有一个实例,并...

    C#设计模式学习笔记

    C#设计模式学习笔记是一份详尽的资源,适合任何希望深入了解如何在C#编程中应用设计模式的开发者。这份笔记涵盖了多种设计模式,旨在提升代码的可读性、可维护性和可扩展性,这些都是软件开发中至关重要的要素。 ...

    GoF 23种设计模式学习笔记

    "GoF 23种设计模式学习笔记" 是一个深入探讨这23个经典设计模式的资源,这些模式最初由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位作者在1994年的著作《设计模式:可复用面向对象软件的基础》中...

    设计模式之美—学习笔记

    在这个“设计模式之美”的学习笔记中,我们将探讨一些主要的设计模式,以及它们在实际开发中的应用。 首先,我们从创建型模式开始。这类模式主要用于对象的创建,如单例模式(Singleton)、工厂模式(Factory ...

    300Java设计模式部分学习笔记

    5. 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或依赖对象的接口,而无需指定它们具体的类。 结构型模式: 结构型模式关注于类和对象的组合。笔记中涉及了以下结构型模式: 1. 适配器模式...

    Java中的design-patterns::open_book:使用通俗易懂的案例,类图,以及配套学习笔记来详解Java的二十种设计模式!

    :hot_beverage: 用Java实现的设计模式〜 ... :check_mark:抽象工厂模式( Abstract Factroy Pattern ) :memo: , :check_mark:建造者模式( Builder Pattern ) :memo: , :check_mark:单例模式( S

    23中设计模式学习笔记.docx

    ### 23种设计模式学习笔记 #### 一、软件设计模式的概念与意义 **概念:** 软件设计模式(Software Design Pattern),又称设计模式,是一套被广泛采用、经过整理和分类的代码设计经验总结。它针对软件设计过程中...

    《设计模式》学习笔记

    ### 设计模式学习笔记 #### 引言 设计模式(Design Patterns)是在软件设计领域内广泛应用的一种实践指南,它提供了一系列解决常见问题的方案。设计模式可以被理解为面向对象软件设计的经验总结,是对特定面向对象...

    Java设计模式尚硅谷笔记

    3. 抽象工厂模式(Abstract Factory):为创建一组相关或相互依赖的对象提供一个接口,而无需指定它们的具体类。 4. 建造者模式(Builder):将复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示...

    《设计模式:可复用面向对象软件的基础》学习并理解 23 种设计模式

    - **抽象工厂模式**(Abstract Factory):提供一个接口,用于创建相关或依赖对象的族,而无需指定它们具体的类。 - **建造者模式**(Builder):将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建...

    23种设计模式的解析与Cpp实现

    - 抽象工厂模式(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。 - 建造者模式(Builder):将一个复杂对象的构建与其表示分离,使同样的构建过程可以创建不同的表示...

    设计模式学习笔记 .txt

    #### Abstract Factory(抽象工厂)模式 - **定义**:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 - **实现方式**:定义一个工厂接口,为不同的产品族提供多个工厂方法。 - **特点**: ...

    23种面向对象设计模式

    文档中的“23种设计模式学习笔记.doc”可能包含了对这23种模式的详细解释和实例,而“设计模式之我爱我家.doc”可能从一个更生活化的角度来阐述设计模式的概念。“软件23种设计模式,超级经典的.pdf”可能是对这些...

    台湾人写的设计模式笔记

    主要分为五种:工厂方法(Factory Method)、抽象工厂(Abstract Factory)、单例(Singleton)、建造者\Builder、原型\(Prototype\)。例如,工厂方法允许在子类中定义实例化对象的具体过程,而单例模式确保一个类只有一个...

    《javascript设计模式》学习笔记五:Javascript面向对象程序设计工厂模式实例分析

    JavaScript设计模式中的工厂模式是一种创建型模式,它提供了一种创建对象的最佳方式。在JavaScript中,工厂模式的主要目的是通过一个公共的接口或者方法来创建对象,这样调用者无需关心对象的具体类型,只需要知道它...

    设计模式之蝉

    “抽象工厂模式”(Abstract Factory pattern)也被简要提及,它是另一个创建型设计模式,用于创建一系列相关或相互依赖的对象。抽象工厂模式与工厂模式的不同之处在于,它不仅仅关注单一产品的创建,而是关注产品...

    23个设计模式图解--学习笔记

    2. **抽象工厂**(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。 3. **建造者**(Builder):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同...

    设计模式的读书总结笔记

    1. 创建型模式:如单例模式(Singleton)、工厂模式(Factory Method)、抽象工厂模式(Abstract Factory)、建造者模式(Builder)和原型模式(Prototype)。这些模式关注对象的创建,旨在降低对象的创建过程与使用...

Global site tag (gtag.js) - Google Analytics