`
tsface
  • 浏览: 9269 次
  • 性别: Icon_minigender_1
  • 来自: 西安
最近访客 更多访客>>
社区版块
存档分类
最新评论

[1]设计模式——简单工厂模式

阅读更多

简单工厂模式

    简单工厂模式:的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了和具体产品的依赖。

 

    上面的这句话怎么理解呢?我们看看下面这段代码,这段代码是客户端的业务逻辑代码:

     

// 文本消息  
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
     return buildTextMsgXml(requestMap);
}  
// 图片消息  
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {  
     respContent = "/:p-(您发送的是图片消息!暂时处理不了哎!";  
}  
// 地理位置消息  
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {  
     respContent = "/:p-(您发送的是地理位置消息!暂时处理不了哎!";  
}  
// 链接消息  
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {  
     respContent = "/:p-(您发送的是链接消息!暂时处理不了哎!";  
}  
// 音频消息  
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {  
     espContent = "/:p-(您发送的是音频消息!暂时处理不了哎!";  
}
//....还有许多

 

    这段代码是客户端的代码,很多刚开始写代码的朋友都会和我一样,用大堆的条件控制语句完成业务逻辑代码,但是这样有一个问题,如果新增了一个“消息”类型,那么我们是不是就要在客户端新增加一个if语句呢?这样写当然是没有错误的,但是它增加了代码的“Bad Smell(代码的坏味道) ”,而且增加了客户端的维护成本,也不符合软件设计的“开闭原则”。

    代码如何改进,那么我们不妨采用一种简单工厂方法来消除客户端的维护成本。

 

    首先定义一个消息处理接口:

    

/*
 * @(#)MessageHandler.java 2014-3-16
 */
package com.lotus.weixin.reqhandler;

import java.util.Map;

/**
 * 消息处理接口
 * @author tsface
 * @version 2014-3-16
 * @since 1.0
 */
public interface MessageHandler
{
	/**
	 * 生成消息的类型
	 * @param megType
	 * @return
	 */
	public String buildXMlStr(Map<String, String> requestMap);
}

 

          不同消息处理类实现消息处理接口,下一个代码片段是文本消息的实现

    

/*
 * @(#)TextMsgHandlerImpl.java 2014-3-16
 */
package com.lotus.weixin.reqhandler.impl;

import java.util.Date;
import java.util.Map;

import com.avatar.gdk.util.StringUtils;
import com.lotus.weixin.message.resp.TextMessage;
import com.lotus.weixin.message.utils.MessageUtil;
import com.lotus.weixin.reqhandler.MessageHandler;

/**
 * 文本消息处理类
 * @author tsface
 * @version 2014-3-16
 * @since 1.0
 * @see
 */
public class TextMsgHandlerImpl implements MessageHandler
{

	@Override
	public String buildXMlStr(Map<String, String> requestMap)
	{
		// 发送方帐号(open_id)  
        String fromUserName = requestMap.get("FromUserName");  
        
        String toUserName = requestMap.get("ToUserName");  
        // 消息类型  
        String reqContent = requestMap.get("Content");
		// 回复文本消息  
        TextMessage textMessage = new TextMessage();  
        textMessage.setToUserName(fromUserName);  
        textMessage.setFromUserName(toUserName);  
        textMessage.setCreateTime(new Date().getTime());  
        textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);  
        textMessage.setFuncFlag(0);
		if(StringUtils.isNotEmpty(reqContent) )
		{
			if("?".equals(reqContent))
			{
				textMessage.setContent(MessageUtil.getMainMenu());
			}else if("1".equals(reqContent))
			{
				// 获取网页源代码  
		        //String html = httpRequest("http://ip.taobao.com/service/getIpInfo.php?ip=127.0.0.1");
				textMessage.setContent("你要查看的是时政新闻");
		        
			}else
			{
				textMessage.setContent(MessageUtil.getMainMenu());
			}
		}else
		{
			textMessage.setContent(MessageUtil.getMainMenu());
		}
		return MessageUtil.textMessageToXml(textMessage);
	}
	
}

 

       下面一步我们来封装我们的工厂类,当然工厂类代码还是存在大量的if语句,这是一种不好的做法,如何消除这种代码,我们可以利用Java中的注解,反射机制来消除,本文就不介绍了。

 

 

/*
 * @(#)MessageHandlerFactory.java 2014-3-16
 */
package com.lotus.weixin.reqhandler;

import com.lotus.weixin.message.utils.MessageUtil;
import com.lotus.weixin.reqhandler.impl.LocationMsgHandlerImpl;
import com.lotus.weixin.reqhandler.impl.PicMsgHandlerImpl;
import com.lotus.weixin.reqhandler.impl.TextMsgHandlerImpl;
import com.lotus.weixin.reqhandler.impl.VoiceMsgHandlerImpl;

/**
 * 描述当前类的作用
 * 
 * @author tsface
 * @version 2014-3-16
 * @since 1.0
 * @see
 */
public class MessageHandlerFactory
{
	
	/**
	 * 构造方法私有化
	 */
	private MessageHandlerFactory()
	{
	}

	/**
	 * 生成实例的的方法
	 * @param msgType
	 * @return
	 */
	public static MessageHandler createMsgHandler(String msgType)
	{
		MessageHandler handler = null;
		
		// 文本消息
		if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT))
		{
			handler = new TextMsgHandlerImpl();
		}
		// 图片消息
		else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE))
		{
			handler = new PicMsgHandlerImpl();
		}
		// 地理位置消息
		else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION))
		{
			handler = new LocationMsgHandlerImpl();
		}
		// 链接消息
		else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK))
		{
		}
		// 音频消息
		else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE))
		{
			handler = new VoiceMsgHandlerImpl();
		}
		return handler;
	}
}
 

 

 

       以上代码完成了我们对简单工厂的封装,下面我们看看客户端代码怎么写。有了工厂以后,我们只需用工厂产生我们需要的对象,调用接口提供的方法完成客户代码的解耦工作。

 

 

//获取消息处理接口
MessageHandler createMsgHandler = MessageHandlerFactory.createMsgHandler(msgType);
String xmlStr = createMsgHandler.buildXMlStr(requestMap);
f(StringUtils.isNotEmpty(xmlStr))
{
        return xmlStr;
}else{
        respContent = "/:p-(您发送的消息!暂时处理不了哎!"; 
}
 

 

       以后即使新增了消息类型,那么客户端的代码我们就无需进行改动,只需要修改工厂类就可以实现,如果我们消除工厂类中的判断,改用读取配置文件或者注解来创建对象,那么我们代码就完全符合“对修改关闭,对增加开放”的原则了。

 

开闭原则:1988年,勃兰特·梅耶(Bertrand Meyer)在他的著作《面向对象软件构造(Object Oriented Software Construction)》中提出了开闭原则,它的原文是这样:“Software entities should be open for extension,but closed for modification”。翻译过来就是:“软件实体应当对扩展开放,对修改关闭”

 

 

2014/3/16  tsface 南京

hanily@msn.com

 

 

 

 

 

分享到:
评论

相关推荐

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

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

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

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

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

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

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

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

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

    抽象工厂模式是一种重要的软件设计模式,它属于创建型模式,主要解决的是当系统需要创建一系列相关或相互依赖的对象时,而这些对象的类在运行时可能不确定的问题。在这个模式中,我们通过一个抽象工厂接口来定义创建...

    c#工厂模式——简单工厂,抽象工厂,单件模式实例

    1. **简单工厂模式**: 简单工厂模式是一种静态工厂方法,它创建一个具体的对象而无需暴露创建逻辑。在C#中,我们可以定义一个工厂类,该类包含一个静态方法,用于根据输入参数返回不同类型的实例。例如,一个形状...

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

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

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

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

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

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

    c#工厂模式——简单工厂_抽象工厂实例

    ### C#工厂模式详解——简单工厂与抽象工厂实例解析 #### 一、工厂模式概述 工厂模式是一种常用的设计模式,在面向对象编程中被广泛应用于创建对象。它通过提供一个统一的接口来创建一系列相关的或相互依赖的对象...

    设计模式C#描述之——简单工厂模式

    ### 设计模式C#描述之——简单工厂模式 #### 知识点概述 简单工厂模式是一种常用的设计模式,属于创建型模式之一。该模式的主要目的是为了封装产品对象的创建过程,将这一过程从客户端分离出来,使客户端无须关心...

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

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

    设计模式——刘伟

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

    设计模式——GFour

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

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

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

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

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

    设计模式实现——抽象工厂模式结构实现

    抽象工厂模式是设计模式中的一种创建型模式,它提供了一种创建对象集合的接口,而无需指定具体的类。这种模式允许客户端使用一个通用接口来创建一组相关或相互依赖的对象,而无需关心它们的具体实现。在Java或其他...

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

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

Global site tag (gtag.js) - Google Analytics