`

设计模式之Factory(详解)

阅读更多
工厂模式定义:提供创建对象的接口.

为何使用?
工厂模式是我们最常用的模式了,著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。

为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑实用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。

我们以类Sample为例, 如果我们要创建Sample的实例对象:

Sample sample=new Sample();

可是,实际情况是,通常我们都要在创建sample实例时做点初始化的工作,比如赋值 查询数据库等。

首先,我们想到的是,可以使用Sample的构造函数,这样生成实例就写成:

Sample sample=new Sample(参数);

但是,如果创建sample实例时所做的初始化工作不是象赋值这样简单的事,可能是很长一段代码,如果也写入构造函数中,那你的代码很难看了(就需要Refactor重整)。

为什么说代码很难看,初学者可能没有这种感觉,我们分析如下,初始化工作如果是很长一段代码,说明要做的工作很多,将很多工作装入一个方法中,相当于将很多鸡蛋放在一个篮子里,是很危险的,这也是有背于Java面向对象的原则,面向对象的封装(Encapsulation)和分派(Delegation)告诉我们,尽量将长的代码分派“切割”成每段,将每段再“封装”起来(减少段和段之间偶合联系性),这样,就会将风险分散,以后如果需要修改,只要更改每段,不会再发生牵一动百的事情。

在本例中,首先,我们需要将创建实例的工作与使用实例的工作分开, 也就是说,让创建实例所需要的大量初始化工作从Sample的构造函数中分离出去。

这时我们就需要Factory工厂模式来生成对象了,不能再用上面简单new Sample(参数)。还有,如果Sample有个继承如MySample, 按照面向接口编程,我们需要将Sample抽象成一个接口.现在Sample是接口,有两个子类MySample 和HisSample .我们要实例化他们时,如下:

Sample mysample=new MySample();
Sample hissample=new HisSample();

随着项目的深入,Sample可能还会"生出很多儿子出来", 那么我们要对这些儿子一个个实例化,更糟糕的是,可能还要对以前的代码进行修改:加入后来生出儿子的实例.这在传统程序中是无法避免的.

但如果你一开始就有意识使用了工厂模式,这些麻烦就没有了.

 

 

 

今天我去市场,要决定是买水果等产品,还是选择种水果的产品。具体怎么操作自己选择。来到市场,我发现主要有一些水果:苹果(Apple),葡萄(Grape)和鸭梨(Pear)。到底买什么好呢?我一阵思量。俗话说:“饭后一只烟,赛过活神仙。饭后吃苹果,西施见我躲。”为了老婆的漂亮,我决定买苹果。

 

 

下面开始Factory模式研究,当然是用我上面举的例子来说明。
Simple Factory模式
专门定义一个类来负责创建其它类的实例,被创建的实例通常都具有共同的父类。
Factory Method模式
将对象的创建交由父类中定义的一个标准方法来完成,而不是其构造函数,究竟应该创建何种对象由具体的子类负责决定。 Abstract Factory模式

提供一个共同的接口来创建相互关联的多个对象。

 

 

一、Simple Factory模式:

1、在这里,我们先定义水果(Fruit)接口:

public interface Fruit {
	void plant();	// 水果是被种植的
	void enableEat();	// 水果能吃
}

 

2、苹果(Apple)是对水果(Fruit)接口的实现:

public class Apple implements Fruit{
	public void plant(){
		System.out.println("种苹果!");
	}

	public void enableEat(){
		System.out.println("苹果好吃!");
	}
}

 

3、葡萄(Grape)是对水果(Fruit)接口的实现:

public class Grape implements Fruit{
	public void plant(){
		System.out.println("种葡萄!");
	}
	public void enableEat(){
		System.out.println("葡萄好吃!");
	}
}

 

4、鸭梨(Pear)是对水果(Fruit)接口的实现:

public class Pear implements Fruit{
	public void plant(){
		System.out.println("种鸭梨!");
	}
	public void enableEat(){
		System.out.println("鸭梨好吃!");
	}
}

 

5、定义买水果(BuyFruit)这一过程类:

public class BuyFruit {
	/**
	 * 简单工厂方法
	 * @param which
	 * @return
	 */
	public static Fruit buyFruit(String which){
		if (which.equalsIgnoreCase("apple")) {	// 如果是苹果,则返回苹果实例
			return new Apple();
		} else if (which.equalsIgnoreCase("pear")){	// 如果是鸭梨,则返回鸭梨实例
			return new Strawberry();
		} else if (which.equalsIgnoreCase("grape")) { // 如果是葡萄,则返回葡萄实例
			return new Grape();
		} else{
			return null;
		}
	}
}

 

6、 编写测试类:

public class FruitTest {
	public static void	main(String args[]){
		BuyFruit buy = new BuyFruit();	 // 开始买水果这个过程
		buy.buyFruit("apple").enableEat(); // 调用苹果的enableEat()方法
	}
}

 

7、 说明:
A:我要购买苹果,只需向工厂角色(BuyFruit)请求即可。而工厂角色在接到请求后,会自行判断创建和提供哪一个产品。
B:但是对于工厂角色(BuyFruit)来说,增加新的产品(比如说增加草莓)就是一个痛苦的过程。工厂角色必须知道每一种产品,如何创建它们,以及何时向客户端提供它们。换言之,接纳新的产品意味着修改这个工厂。
C:因此Simple Factory模式的开放性比较差。
有什么办法可以解决这个问题吗?那就需要Factory Method模式来为我们服务了。

二、Factory Method模式:

1、同样,我们先定义水果(Fruit)接口:

public interface Fruit {
	void plant();	// 水果是被种植的
	void enableEat();	// 水果能吃
}

 

2、苹果(Apple)是对水果(Fruit)接口的实现:

public class Apple implements Fruit{
	public void plant(){
		System.out.println("种苹果!");
	}
	public void enableEat(){
		System.out.println("苹果好吃!");
	}
}

 

3、葡萄(Grape)是对水果(Fruit)接口的实现:

public class Grape implements Fruit{
	public void plant(){
		System.out.println("种葡萄!");
	}
	public void enableEat(){
		System.out.println("葡萄好吃!");
	}
}

 

4、鸭梨(Pear)是对水果(Fruit)接口的实现:

public class Pear implements Fruit{
	public void plant(){
		System.out.println("种鸭梨!");
	}
	public void enableEat(){
		System.out.println("鸭梨好吃!");
	}
}

 

5、在这里我们将买水果(BuyFruit)定义为接口类:

public interface BuyFruit{
	/**
	 * 工厂方法
	 * @return
	 */
	public Fruit buyFruit();	 // 定义买水果这一过程
}

 

6、买苹果是(BuyApple)对买水果(BuyFruit)这个接口的实现

public class BuyApple implements BuyFruit{
	public Fruit buyFruit(){
		return new Apple();	// 返回苹果实例
	}
}

 

7、买鸭梨是(BuyPear)对买水果(BuyFruit)这个接口的实现

public class BuyPear implements BuyFruit{
	public Fruit BuyPear (){
		return new Pear();	// 返回鸭梨实例
	}
}

 

8、买葡萄是(BuyGrape)对买水果(BuyFruit)这个接口的实现

public class BuyGrape implements BuyFruit{
	public Fruit BuyGrape (){
		return new Grape ();	// 返回葡萄实例
	}
}

 

9、编写测试类:

public class FruitTest {
	public static void	main(String args[]){
		BuyApple buy = new BuyApple(); // 开始买水果这个过程
		buy.buyFruit().enableEat();			// 调用苹果的enableEat()方法
	}
}

 

10、说明:
A:工厂方法模式和简单工厂模式在结构上的不同是很明显的。工厂方法模式的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。工厂方法模式可以允许很多具体工厂类从抽象工厂类中将创建行为继承下来,从而可以成为多个简单工厂模式的综合,进而推广了简单工厂模式。
B:工厂方法模式退化后可以变得很像简单工厂模式。设想如果非常确定一个系统只需要一个具体工厂类,那么就不妨把抽象工厂类合并到具体的工厂类中去。由于反正只有一个具体工厂类,所以不妨将工厂方法改成为静态方法,这时候就得到了简单工厂模式。
C:如果需要加入一个新的水果,那么只需要加入一个新的水果类以及它所对应的工厂类。没有必要修改客户端,也没有必要修改抽象工厂角色或者其他已有的具体工厂角色。对于增加新的水果类而言,这个系统完全支持“开-闭”原则。
D:对Factory Method模式而言,它只是针对一种类别(如本例中的水果类Fruit),但如果我们还想买肉,那就不行了,这是就必须要Abstract Factory Method模式帮忙了。

 

 

 

三、Abstract Factory模式

1、同样,我们先定义水果(Fruit)接口:

public interface Fruit {
	void plant();	// 水果是被种植的
	void enableEat();	// 水果能吃
}

 

2、苹果(Apple)是对水果(Fruit)接口的实现:

public class Apple implements Fruit{
	public void plant(){
		System.out.println("种苹果!");
	}
	public void enableEat(){
		System.out.println("苹果好吃!");
	}
}

 

3、葡萄(Grape)是对水果(Fruit)接口的实现:

public class Grape implements Fruit{
	public void plant(){
		System.out.println("种葡萄!");
	}
	public void enableEat(){
		System.out.println("葡萄好吃!");
	}
}

 

4、鸭梨(Pear)是对水果(Fruit)接口的实现:

public class Pear implements Fruit{
	public void plant(){
		System.out.println("种鸭梨!");
	}
	public void enableEat(){
		System.out.println("鸭梨好吃!");
	}
}

 

5、定义肉(Meat)接口:

public interface Meat {
	void feed();	// 肉是喂养的
	void enableEat();	// 肉能吃
}

 

6、猪肉(BigMeat)是对肉(Meat)接口的实现:

public class BigMeat implements Meat{
	public void feed(){
		System.out.println("养猪!");
	}
	public void enableEat(){
		System.out.println("猪肉好吃!");
	}
}

 

7、牛肉(CowMeat)是对肉(Meat)接口的实现:

public class CowMeat implements Meat {
	public void feed(){
		System.out.println("养牛!");
	}
	public void enableEat(){
		System.out.println("牛肉好吃!");
	}
}

 

8、我们可以定义买货人(Buyer)接口:

public interface Buyer {
	/**
	 * 买水果工厂方法
	 * @param whichFruit
	 * @return
	 */
	public Fruit buyFruit(Fruit whichFruit);
	/**
	 * 买肉的工厂方法
	 * @param whichMeat
	 * @return
	 */
	public Meat buyMeat(Meat whichMeat);
}

 

9、我(MyBuyer)是对买货人(Buyer)接口的实现:

public class MyBuyer implements Buyer{
	/**
	 * 买水果工厂方法
	 */
	public Fruit buyFruit(Fruit whichFruit){
		 return whichFruit;
	}

	/**
	 * 买肉的工厂方法
	 */
	public Meat buyMeat(Meat whichMeat){
		 return whichMeat;
	}
}

 

10、编写测试类:

public class MyBuyerAbstractTest {
	public static void	main(String args[]){
		Fruit apple = new Apple();	 	// 苹果实例
		Meat big = new BigMeat();		// 猪肉实例
		MyBuyer my = new MyBuyer();		// 我是买者的实例
		my.buyFruit(apple).enableEat();	// 我买苹果
		my.buyMeat(big).enableEat();	// 我买猪肉
	}
} 

 

11、说明:
A:抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,创建多个产品族中的产品对象。这就是抽象工厂模式的用意。
B:抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。

 

 

 

 

 

 

分享到:
评论

相关推荐

    设计模式,设计模式详解

    设计模式是软件工程中的一种重要概念,它代表了在特定情境下解决常见问题的最佳实践。设计模式并不是具体的代码或库,而是一种通用解决方案的描述,可以在多种编程语言中应用。通过对设计模式的理解和运用,开发者...

    设计模式详解及c++代码实现

    我们将探讨抽象工厂(Abstract Factory)、装饰者(Decorator)和工厂方法(Factory Method)这三种重要的设计模式。 首先,抽象工厂模式是一种创建型设计模式,它提供一个接口,用于创建一系列相关的或相互依赖的...

    java23种设计模式详解+源码(绝对详解)

    设计模式是软件工程中的一种最佳实践,用于解决常见的设计问题并提供可重用的解决方案。在Java编程中,有23种经典的GoF(Gang of Four)设计模式,它们被分为三大类:创建型、结构型和行为型。本资源集合了这些模式...

    GoF 23种设计模式的详解与应用

    创建模式:设计模式之Factory,设计模式之Prototype(原型),设计模式之Builder,设计模式之Singleton(单态). 结构模式:设计模式之Facade(外观),设计模式之Proxy(代理),设计模式之Adapter(适配器),设计模式之Composite...

    Java中23种设计模式详解

    Java 中 23 种设计模式详解 在软件设计中,设计模式是解决特定问题的通用解决方案。 Java 中有 23 种常见的设计模式,下面将对每种设计模式进行详细的解释: 1. 抽象工厂模式(Abstract Factory) 抽象工厂模式...

    设计模式详解,设计模式

    "设计模式详解"的压缩包可能包含了关于这些模式的详细讲解、示例代码和实战案例,对于初学者和经验丰富的开发者来说都是宝贵的资源。通过深入学习和实践,你可以提升自己的设计能力,编写出更具弹性和可扩展性的软件...

    设计模式PPT---25种设计模式详解

    这份名为“设计模式PPT——25种设计模式详解”的资料,显然是一个深入探讨设计模式的教程,它通过PDF格式对25种主要的设计模式进行了详尽的阐述。 首先,我们要理解设计模式的基本概念。设计模式不是代码,而是一种...

    java24种设计模式详解

    设计模式是软件工程中的一种最佳实践,它是在特定上下文中解决常见问题的模板或蓝图。...在"java24种设计模式详解"这个资源中,你会找到每种模式的详细讲解和实例,这将有助于你深入理解并掌握它们。

    概括设计模式,举例详解抽象工厂模式

    ### 概述设计模式:以抽象工厂模式为例深入解析 设计模式是在软件工程领域中,为解决特定问题而总结出的、经过验证的解决方案。它们是开发者在长期实践中提炼出来的智慧结晶,旨在提高代码的可读性、可维护性和可...

    设计模式 (20种设计模式代码详解)

    接着,工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的最佳方式。工厂模式让我们能够延迟对象的实例化,或者创建一系列相关或相互依赖的对象,而无需指定它们的具体类。简单工厂模式适用...

    22个编程设计模式详解

    本资源包“22个编程设计模式详解”包含了对这一主题的深入探讨。 设计模式分为三大类:创建型、结构型和行为型模式。创建型模式关注对象的创建,如单例模式(Singleton)、工厂方法模式(Factory Method)和建造者...

    Java的23种设计模式详解

    在软件开发领域,设计模式是经验丰富的开发者们总结出的解决常见问题的模板或最佳实践。在Java编程中,有23种经典的设计模式,它们是面向对象设计的核心部分,帮助我们编写可维护、可扩展且高效的应用程序。以下是这...

    Java设计模式之工厂模式(Factory)

    ### Java设计模式之工厂模式详解 #### 一、引言 设计模式是在软件设计过程中针对常见问题而提出的标准化解决方案。其中,“工厂模式”是面向对象编程中最常用的模式之一,主要目的是封装实例化过程,使代码更加...

    JAVA常用设计模式详解大全.pdf

    ### JAVA常用设计模式详解 #### 一、设计模式概述 设计模式是在软件设计过程中针对特定问题的典型解决方案。这些模式经过长时间的实践检验,被证明是解决特定问题的有效方法。设计模式可以分为三大类:创建型模式...

    JAVA23种设计模式详解

    1. **工厂模式**(Factory Method):这是一种创建型设计模式,它提供了一个接口来创建对象,但允许子类决定实例化哪个类。这样,工厂方法将对象的创建推迟到了子类。 2. **简单工厂模式**(Factory Pattern):这...

    23中设计模式详解

    设计模式是软件工程中的一种最佳实践,用于解决在软件设计中常见的问题,它们代表了经过时间考验的解决方案,可以被重用并应用于类似的问题。在Java编程语言中,设计模式的应用广泛且至关重要,有助于提高代码的...

    Java的23种设计模式详解读+code

    Java设计模式是软件开发中的重要概念,它是一种在特定情境下解决常见问题的...通过阅读提供的"Java的23种设计模式详解读+code"压缩包,你可以深入学习每种模式的实际应用和实现细节,从而更好地在项目中运用这些模式。

    设计模式之“工厂方法模式[Factory Method Pattern]”

    今天我们要探讨的是设计模式中的一个经典成员——工厂方法模式(Factory Method Pattern)。工厂方法模式是创建型设计模式的一种,它提供了一种创建对象的最佳方式。 ### 一、什么是工厂方法模式? 工厂方法模式...

    23种设计模式整理pdf

    设计模式详解 设计模式是软件开发中的一种解决方案,旨在提高代码的可重用性、可维护性和可扩展性。在这篇文章中,我们将对23种常见的设计模式进行整理和解释。 1. Singleton 模式 Singleton 模式是一种创建型模式...

Global site tag (gtag.js) - Google Analytics