`
陌陌天使
  • 浏览: 22569 次
  • 性别: Icon_minigender_2
  • 来自: 长沙
社区版块
存档分类
最新评论

设计模式——工厂模式

阅读更多

今天来说说工厂模式,好记性不如烂博客啊!以例子来说,是最好理解的。

假如说,你要制作一个APP,类似脸萌的APP。它提供好多好多的眼睛,好多好多的发型可供选择。通常,我们的日常生活中要产生大量的类似对象,都是交由工厂来批量生产。那么,世界上的理论总是惊人的相似,正如我们模拟人的大脑视觉运作机制,而产生了神经网络算法一样。把现实世界的工厂搬到代码设计中也是可行的,可就是——工厂模式

从字面来看,得其意二三分。到底什么是工厂模式呢?

实例化对象,用工厂方法代替new操作

意图:

定义一个借口来创建对象,但是让子类来决定哪些类需要被实例化,工厂方法把实例化的工作推迟到子类中去实现。

适合的场所:

有一组类似的对象需要创建

在编码时不能预见需要创建哪种类的实例

系统需要考虑扩展性,不应该以来于产品类实例如何被创建、组合和表达的细节(低耦合)

如下图,客户要请求一个物件,我们就调用工厂接口来实例化一个产品


来一个小小的实例理解一下

以脸萌中的发型实现为例,我们有左偏分发型和右偏分发型,看例子:

一个产生头发的借口,以及实现类

/**
 * 发型接口
 * @author Administrator
 */
public interface HairInterface {

	/**
	 * 画图
	 */
	public void draw();
}

 

/**
 * 右偏分发型
 * @author Administrator
 *
 */
public class RightHair implements HairInterface {

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println("-----------------右偏分发型-------------------");
	}
}

 

 

/**
 * 左偏分发型
 * @author Administrator
 *
 */
public class LeftHair implements HairInterface {

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println("-----------------左偏分发型-------------------");
	}
}

 

public class SunnyTest {

	public static void main(String[] args){
		
//		HairInterface left = new LeftHair();
//		left.draw();
	}
}

得到:

-----------------左偏分发型-------------------

  

这样呢!也就算是实现了,但是还是存在着问题

1.每添加一个发型就要添加一个新的类来实现发行接口,不利于代码维护和管理

2.在客户端要显式调用draw方法

 

那么怎么办呢??这不工厂还没起作用嘛!新建一个HairFactory来统一生产发型,那么也就解决了上面的第二个问题。实现如下:

 

import java.util.Map;

/**
 * 发型工厂
 * @author Administrator
 */
public class HairFactory {
	/**
	 * 根据类型来创建对象
	 * @param key ;类型关键字
	 * @return
	 */
	public HairInterface getHair(String key){
		if("left".equals(key)){
			return new LeftHair();			
		}else if("right".equals(key)){
			return new RightHair();
		}
		return null;
	}
}

 Test.java中

 

		HairFactory factory = new HairFactory();
		HairInterface right =  factory.getHair("right");
		right.draw();

 得到:

 

-----------------右偏分发型-------------------

  

那么现在我们又发现,我们每多一种类型的发型,就要在getHair方法中添加一个if分支,这样也是特别不利于管理的,那么该怎么办呢?

 

JAVA中有一种类的反射机制(不详述),应用类的反射,根据类的名称来创建对象。

在HairFactory中:

 

	/**
	 * 根据类的名称来生产对象
	 * @param className
	 * @return
	 */
	public HairInterface getHairByClass(String className){
		
		try {
			HairInterface hair = (HairInterface) Class.forName(className).newInstance();
			return hair;
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

 此时,Test.java类中传入全路径

 

HairInterface left =factory.getHairByClass("com.sunny.project.LeftHair");
left.draw();

 得到:

-----------------左偏分发型-------------------

 我们这么做就可以根据类名直接创建实例,利于代码的管理

 

 

但精益求精的路上,总是看不爽这么长的参数,有没有办法可以让这个参数简单明了呢?

那自然是有的........

JAVA中有一个属性文件(.properties),以keyvalue形式存储数据

 

我们新建一个type.properties

left=com.sunny.project.LeftHair
right=com.sunny.project.RightHair

 有了这个文件,要怎么来使用呢?这里就涉及到了文件操作,读取该文件找到对应关系

 

Java中有一个Properties类,用来操作properties文件的

import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * properties文件的读取工具
 * @author Administrator
 *
 */
public class PropertiesReader {

	
	public Map<String, String> getProperties() {

		Properties props = new Properties();
		Map<String, String> map = new HashMap<String, String>();
		try {

			InputStream in = getClass().getResourceAsStream("type.properties");
			props.load(in);
			Enumeration en = props.propertyNames();
			while (en.hasMoreElements()) {
				String key = (String) en.nextElement();
				String property = props.getProperty(key);
				map.put(key, property);
//				System.out.println(key + "  " + property);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}
}

 这个时候我们的getHair方法有需要升级了

	/**
	 * 根据类的名称来生产对象
	 * @param className
	 * @return
	 */
	public HairInterface getHairByClassKey(String key){
		
		try {
			Map<String, String> map = new PropertiesReader().getProperties();
			
			HairInterface hair = (HairInterface) Class.forName(map.get(key)).newInstance();
			return hair;
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

 此时客户端实现为

		HairInterface hair = factory.getHairByClassKey("right");
		hair.draw();

 得到:

-----------------右偏分发型-------------------

 我们现在想要增加一个中分发型,要怎么办呢??

新建一个InHair类实现HairInterface

/**
 * 中分发型
 * @author Administrator
 *
 */
public class InHair implements HairInterface {

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println("-----------------中分发型-------------------");
	}
}

 然后还需要做什么呢??是不是在propertied文件中添加对应关系

in=com.sunny.project.InHair

 测试:

		HairInterface hair = factory.getHairByClassKey("in");
		hair.draw();

 得到:

-----------------中分发型-------------------

 这个工厂模式到这里就完全实现了,我们添加新的发型不需要修改HairFactory,只需要添加对应关系和相应的实现类。

 

Software entities should be open for extension,but closed for modification——Bertrand Meyer

对扩展开放,对修改关闭——“开闭原则”

 

参考资料:http://www.imooc.com/video/5316

 

  • 大小: 3.4 KB
3
3
分享到:
评论
1 楼 陌陌天使 2015-05-06  
viphyy 写道
深圳JAVA技术交流群 281463795, 不错,哈哈哈哈

竟然只有20人

相关推荐

    设计模式——工厂模式在开发中的应用(简单计算器)

    这个是http://blog.csdn.net/dawanganban/article/details/9884681博客中java设计模式的源代码。下载前请先看《设计模式——工厂模式在开发中的应用》一文。

    设计模式——工厂方法模式

    工厂方法模式是面向对象设计模式中的一种,它属于创建型模式,主要解决的是当系统需要创建的对象具有多种类型,而具体创建哪种类型的对象在运行时才能确定的问题。在这个压缩包中,`FactoryMethod`可能包含了Java...

    设计模式——简单工厂模式

    **设计模式——简单工厂模式** 简单工厂模式是创建型设计模式的一种,它提供了一种创建对象的最佳方式。在简单工厂模式中,一个专门的类(称为工厂类)负责创建对象,客户端无需知道所创建的对象的具体类,只需要...

    Android之大话设计模式——:抽象工厂模式借鉴.pdf

    Android之大话设计模式——:抽象工厂模式借鉴.pdf

    设计模式——抽象工厂模式

    抽象工厂模式是设计模式中的一种创建型模式,它提供了一种创建对象集合的接口,而无需指定具体类。这种模式的主要目的是为了隔离产品对象的创建和使用,使得系统对产品类的依赖降低到最低,同时也方便了产品的扩展和...

    设计模式——简单工厂 VS 工厂方法

    简单工厂模式,也称为静态工厂模式,是一种创建型设计模式,它提供了一个静态方法来创建对象,而无需暴露实例化逻辑。在简单工厂模式中,一个单一的工厂类负责生产所有相关类型的实例。这种模式适用于产品种类较少且...

    Android之大话设计模式——:抽象工厂模式参考.pdf

    Android之大话设计模式——:抽象工厂模式参考.pdf

    软件设计模式——抽象工厂

    在学习和应用抽象工厂模式时,理解其核心思想——封装变化和解耦,以及如何在实际项目中选择合适的场景使用这一模式,是非常关键的。对于软件工程专业的学生来说,掌握这一模式不仅可以提升编程能力,还能提高对软件...

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

    Java设计模式——工厂设计模式详解 在软件设计中,工厂设计模式是一种常用的设计模式,主要用于实例化有共同接口的类。Java设计模式——工厂设计模式是Java中的一种常用的设计模式,主要用于实例化有共同接口的类。...

    c#设计模式-工厂模式

    《C#设计模式——工厂模式详解》 工厂模式是一种常用的设计模式,它的主要目的是通过抽象出产品创建过程,使得客户端代码不再直接new对象,而是通过工厂来获取对象,从而降低了代码之间的耦合度,提高了系统的可...

    设计模式——GFour

    《设计模式——GFour》是一本深受IT从业者喜爱的经典书籍,尤其在C++开发者中具有广泛影响力。设计模式是软件工程领域中的一种最佳实践,它总结了在特定情境下解决问题的常见方法,使得代码可读性更强,复用性更高,...

    设计模式——刘伟

    设计模式是软件工程中的一种重要概念,它代表了在特定情境下解决常见问题的最佳实践。刘伟先生在讲解设计模式时,通常会深入浅出地介绍这些模式的原理、应用场景以及如何有效地在实际编程中应用它们。设计模式并不是...

    实验二 简单工厂模式.zip_31QS_C#_设计模式——简单工厂模式_设计模式实验

    简单工厂模式是软件设计模式中的一种基础模式,它属于创建型模式,主要解决对象的创建问题,降低了客户端代码与具体产品类之间的耦合度。在本实验中,我们将深入理解和应用C#语言实现简单工厂模式。 简单工厂模式的...

    设计模式——基于C#的工程化实现及扩展

    ### 设计模式——基于C#的工程化实现及扩展 #### 概述 本书旨在向读者展示如何利用C# 2.0语法有效地实现和应用设计模式,使其不仅仅局限于简单的例子,而是能够在实际工程项目中发挥重要作用。全书分为七个部分,...

    设计模式_--_工厂模式和单件模式

    ### 设计模式——工厂模式与单例模式 #### 一、引言 设计模式是软件工程领域中的一个重要概念,它代表了在特定情况下解决常见问题的最佳实践。在本篇文章中,我们将深入探讨两种广泛使用的软件设计模式:工厂模式...

    java 设计模式之工厂模式

    本篇文章将深入探讨Java中的一个基础设计模式——工厂模式,以及它的一些变体,如简单工厂模式和抽象工厂模式,并结合Java的反射机制进行讲解。 首先,工厂模式的核心思想是提供一个创建对象的接口,但让实现这个...

    C#设计模式-工厂模式

    ### C#设计模式——工厂模式详解 #### 一、引言 在软件开发过程中,对象的创建是一个常见的任务。然而,随着需求的变化,这些对象的具体实现可能会经历较大的改动。为了解决这一问题,并确保系统的其他部分不受这些...

    设计模式——原版的设计模式

    设计模式是一种在软件设计中被广泛认可的解决特定问题、经过良好记录并可重用的解决方案。它们代表了在各种编程环境中反复出现的问题的最佳实践。原版的设计模式通常指的是最初由“Gang of Four”(GoF)在他们的...

    JAVA设计模式.chm

    本资源“JAVA设计模式.chm”聚焦于一种重要的设计模式——工厂模式。工厂模式是面向对象设计中的一种经典模式,它在Java程序中扮演着核心角色。 工厂模式的核心思想是提供一个创建对象的接口,但让实现这个接口的类...

Global site tag (gtag.js) - Google Analytics