`
tianhandigeng
  • 浏览: 374291 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

实战学习设计模式之Decorator装饰模式

阅读更多

     这里先借鉴一下Jdon中关于装饰器模式的一个解释:

装饰模式:Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这两种实体在Decorator模式中是必须的.

Decorator定义 :
动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活.

为什么使用Decorator ?
我们通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的.

使用Decorator的理由是:这些功能需要由用户动态决定加入的方式和时机.Decorator提供了"即插即用"的方法,在运行期间决定何时增加何种功能.

    我觉得其实也就是相当于我们实际生活中的包装的概念。这里来看一个实例,我们知道在使用Hibernate的时候对于创建SessionFactory的话只要一次就够了,这时候我们就可以对SessionFactory进行一个简单的包装来实现这样的目的:

package cn.jcenterhome.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
public class SessionFactory {
	private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
	private static org.hibernate.SessionFactory sessionFactory;
	public static synchronized void buildSessionFactory() throws SQLException {
		if (sessionFactory == null) {
			Map<String, String> jchConfig = JavaCenterHome.jchConfig;
			String dbHost = jchConfig.get("dbHost");
			String dbPort = jchConfig.get("dbPort");
			String dbName = jchConfig.get("dbName");
			String dbUser = jchConfig.get("dbUser");
			String dbPw = jchConfig.get("dbPw");
			String dbCharset = jchConfig.get("dbCharset");
			if (connect(dbHost, dbPort, dbName, dbUser, dbPw, dbCharset)) {
				Properties extraProperties = new Properties();
				extraProperties.setProperty("hibernate.connection.url", "jdbc:mysql://" + dbHost + ":"
						+ dbPort + "/" + dbName + "?zeroDateTimeBehavior=convertToNull");
				extraProperties.setProperty("hibernate.connection.username", dbUser);
				extraProperties.setProperty("hibernate.connection.password", dbPw);
				extraProperties.setProperty("hibernate.connection.characterEncoding", dbCharset);
				extraProperties.setProperty("hibernate.connection.characterSetResults", dbCharset);
				Configuration configuration = new Configuration();
				configuration = configuration.configure(CONFIG_FILE_LOCATION);
				configuration = configuration.addProperties(extraProperties);
				sessionFactory = configuration.buildSessionFactory();
			}
		}
	}
	public static Session getSession() throws SQLException {
		if (sessionFactory == null) {
			buildSessionFactory();
		}
		return sessionFactory.getCurrentSession();
	}
	public static void rebuildSessionFactory() throws SQLException {
		sessionFactory = null;
		buildSessionFactory();
	}
	public static org.hibernate.SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	private static boolean connect(String dbHost, String dbPort, String dbName, String dbUser, String dbPw,
			String dbCharset) throws SQLException {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		Connection conn = DriverManager.getConnection("jdbc:mysql://" + dbHost + ":" + dbPort + "/" + dbName
				+ "?useUnicode=true&characterEncoding=" + dbCharset, dbUser, dbPw);
		if (conn != null) {
			if (!conn.isClosed()) {
				conn.close();
				conn = null;
			}
			return true;
		}
		return false;
	}
}

 上面只是一个简单的应用,但是思想就是这样了,我觉得学习设计模式思想很重要,不是说一定要用设计模式来写代码,但是用了设计模式以后确实简单多了。对接口重新包装,对类重新包装,不仅可以重新包装自己写的接口,还可以重新包装我们所有的jar中的接口,目的就一个:使得功能更加完善,更好用。

 

   一句话:以后如果实现功能的拓展我们就可以考虑是否采用用Decorator模式。

分享到:
评论
11 楼 crud0906 2011-02-18  
这个不是装饰模式,装饰模式中装饰者与被装饰者要实现同一接口
10 楼 Loudyn 2011-02-17  
jansel 写道
装饰?

你都已经引用了JDON的解释了,你看一下你的实现是那么回事吗?既然是油漆工,那么肯定只是在被装饰的地方做做表面文章,而不是啥都变了。你这个已经不是油漆工了,而是拆迁工了。

另外,这个也不是Facade,也是打不着边。

9 楼 bradwoo8621 2011-02-17  
这类多线程要挂的吧.. synchronized一个方法也没啥用啊.
8 楼 superwwt 2011-02-17  
decorator就是decorator, 这名字很生动。
lz这个和decorator有啥关系??

7 楼 kfc_davy 2011-02-17  
装饰模式 就是wrapper一下吧,LZ的代码就是普通的构造sessionfactory吧
6 楼 pouyang 2011-02-17  
加点图就好多了
5 楼 zuiyanwangyue 2011-02-17  
我感觉很像是代理模式吧 反正往哪个模式上靠都不是很严格 楼主只不过写了工具类 与设计模式一毛钱的关系都没有
要知道设计模式是很严肃性的东西啊
4 楼 jansel 2011-02-17  
装饰?

你都已经引用了JDON的解释了,你看一下你的实现是那么回事吗?既然是油漆工,那么肯定只是在被装饰的地方做做表面文章,而不是啥都变了。你这个已经不是油漆工了,而是拆迁工了。

另外,这个也不是Facade,也是打不着边。
3 楼 cectsky 2011-02-16  
<div class="quote_title">peterwei 写道</div>
<div class="quote_div">
<div class="quote_title">tianhandigeng 写道</div>
<div class="quote_div">
<p>     这里先借鉴一下Jdon中关于装饰器模式的一个解释:</p>
<p>装饰模式:Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这两种实体在Decorator模式中是必须的.</p>
<p><strong>Decorator定义</strong> :<br>动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活.</p>
<p><strong>为什么使用Decorator</strong> ?<br>我们通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的.</p>
<p>使用Decorator的理由是:这些功能需要由用户动态决定加入的方式和时机.Decorator提供了"即插即用"的方法,在运行期间决定何时增加何种功能.</p>
<p>    我觉得其实也就是相当于我们实际生活中的包装的概念。这里来看一个实例,我们知道在使用Hibernate的时候对于创建SessionFactory的话只要一次就够了,这时候我们就可以对SessionFactory进行一个简单的包装来实现这样的目的:</p>
<pre name="code" class="java">package cn.jcenterhome.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
public class SessionFactory {
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static org.hibernate.SessionFactory sessionFactory;
public static synchronized void buildSessionFactory() throws SQLException {
if (sessionFactory == null) {
Map&lt;String, String&gt; jchConfig = JavaCenterHome.jchConfig;
String dbHost = jchConfig.get("dbHost");
String dbPort = jchConfig.get("dbPort");
String dbName = jchConfig.get("dbName");
String dbUser = jchConfig.get("dbUser");
String dbPw = jchConfig.get("dbPw");
String dbCharset = jchConfig.get("dbCharset");
if (connect(dbHost, dbPort, dbName, dbUser, dbPw, dbCharset)) {
Properties extraProperties = new Properties();
extraProperties.setProperty("hibernate.connection.url", "jdbc:mysql://" + dbHost + ":"
+ dbPort + "/" + dbName + "?zeroDateTimeBehavior=convertToNull");
extraProperties.setProperty("hibernate.connection.username", dbUser);
extraProperties.setProperty("hibernate.connection.password", dbPw);
extraProperties.setProperty("hibernate.connection.characterEncoding", dbCharset);
extraProperties.setProperty("hibernate.connection.characterSetResults", dbCharset);
Configuration configuration = new Configuration();
configuration = configuration.configure(CONFIG_FILE_LOCATION);
configuration = configuration.addProperties(extraProperties);
sessionFactory = configuration.buildSessionFactory();
}
}
}
public static Session getSession() throws SQLException {
if (sessionFactory == null) {
buildSessionFactory();
}
return sessionFactory.getCurrentSession();
}
public static void rebuildSessionFactory() throws SQLException {
sessionFactory = null;
buildSessionFactory();
}
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
private static boolean connect(String dbHost, String dbPort, String dbName, String dbUser, String dbPw,
String dbCharset) throws SQLException {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection conn = DriverManager.getConnection("jdbc:mysql://" + dbHost + ":" + dbPort + "/" + dbName
+ "?useUnicode=true&amp;characterEncoding=" + dbCharset, dbUser, dbPw);
if (conn != null) {
if (!conn.isClosed()) {
conn.close();
conn = null;
}
return true;
}
return false;
}
}</pre>
<p> 上面只是一个简单的应用,但是思想就是这样了,我觉得学习设计模式思想很重要,不是说一定要用设计模式来写代码,但是用了设计模式以后确实简单多了。对接口重新包装,对类重新包装,不仅可以重新包装自己写的接口,还可以重新包装我们所有的jar中的接口,目的就一个:使得功能更加完善,更好用。</p>
<p> </p>
<p>   一句话:以后如果实现功能的拓展我们就可以考虑是否采用用Decorator模式。</p>
<p> </p>
<p><span style="color: #ff0000;">你确定你这个是Decorator模式?而不是别的?颠覆了我以前的思想。</span></p>
</div>
<p> </p>
</div>
<p> </p>
<p>你不说,我还真没看内容,好像是外观。。。</p>
2 楼 peterwei 2011-02-15  
<div class="quote_title">tianhandigeng 写道</div>
<div class="quote_div">
<p>     这里先借鉴一下Jdon中关于装饰器模式的一个解释:</p>
<p>装饰模式:Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这两种实体在Decorator模式中是必须的.</p>
<p><strong>Decorator定义</strong> :<br>动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活.</p>
<p><strong>为什么使用Decorator</strong> ?<br>我们通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的.</p>
<p>使用Decorator的理由是:这些功能需要由用户动态决定加入的方式和时机.Decorator提供了"即插即用"的方法,在运行期间决定何时增加何种功能.</p>
<p>    我觉得其实也就是相当于我们实际生活中的包装的概念。这里来看一个实例,我们知道在使用Hibernate的时候对于创建SessionFactory的话只要一次就够了,这时候我们就可以对SessionFactory进行一个简单的包装来实现这样的目的:</p>
<pre name="code" class="java">package cn.jcenterhome.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
public class SessionFactory {
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static org.hibernate.SessionFactory sessionFactory;
public static synchronized void buildSessionFactory() throws SQLException {
if (sessionFactory == null) {
Map&lt;String, String&gt; jchConfig = JavaCenterHome.jchConfig;
String dbHost = jchConfig.get("dbHost");
String dbPort = jchConfig.get("dbPort");
String dbName = jchConfig.get("dbName");
String dbUser = jchConfig.get("dbUser");
String dbPw = jchConfig.get("dbPw");
String dbCharset = jchConfig.get("dbCharset");
if (connect(dbHost, dbPort, dbName, dbUser, dbPw, dbCharset)) {
Properties extraProperties = new Properties();
extraProperties.setProperty("hibernate.connection.url", "jdbc:mysql://" + dbHost + ":"
+ dbPort + "/" + dbName + "?zeroDateTimeBehavior=convertToNull");
extraProperties.setProperty("hibernate.connection.username", dbUser);
extraProperties.setProperty("hibernate.connection.password", dbPw);
extraProperties.setProperty("hibernate.connection.characterEncoding", dbCharset);
extraProperties.setProperty("hibernate.connection.characterSetResults", dbCharset);
Configuration configuration = new Configuration();
configuration = configuration.configure(CONFIG_FILE_LOCATION);
configuration = configuration.addProperties(extraProperties);
sessionFactory = configuration.buildSessionFactory();
}
}
}
public static Session getSession() throws SQLException {
if (sessionFactory == null) {
buildSessionFactory();
}
return sessionFactory.getCurrentSession();
}
public static void rebuildSessionFactory() throws SQLException {
sessionFactory = null;
buildSessionFactory();
}
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
private static boolean connect(String dbHost, String dbPort, String dbName, String dbUser, String dbPw,
String dbCharset) throws SQLException {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection conn = DriverManager.getConnection("jdbc:mysql://" + dbHost + ":" + dbPort + "/" + dbName
+ "?useUnicode=true&amp;characterEncoding=" + dbCharset, dbUser, dbPw);
if (conn != null) {
if (!conn.isClosed()) {
conn.close();
conn = null;
}
return true;
}
return false;
}
}</pre>
<p> 上面只是一个简单的应用,但是思想就是这样了,我觉得学习设计模式思想很重要,不是说一定要用设计模式来写代码,但是用了设计模式以后确实简单多了。对接口重新包装,对类重新包装,不仅可以重新包装自己写的接口,还可以重新包装我们所有的jar中的接口,目的就一个:使得功能更加完善,更好用。</p>
<p> </p>
<p>   一句话:以后如果实现功能的拓展我们就可以考虑是否采用用Decorator模式。</p>
<p> </p>
<p><span style="color: #ff0000;">你确定你这个是Decorator模式?而不是别的?颠覆了我以前的思想。</span></p>
</div>
<p> </p>
1 楼 cectsky 2011-02-15  
平时总说,在一个class上再包一层,总是包啊包,其实,我们已经在使用装饰器这种dp了,只是我们平时可能说的比较口语化,但是思想是相通的。这也就是为什么没有做过实际东西的人,看设计模式没什么感觉的原因了。相见恨晚!

相关推荐

    Android源码设计模式解析与实战.PDF(完整版)

    综上所述,Android源码设计模式解析与实战不仅是一本关于技术实现的书籍,更是一次深度学习如何优化代码结构、提高程序效率的过程。通过上述对几种典型设计模式的详细介绍,希望能帮助读者更好地理解和运用这些模式...

    中文版_源码设计模式解析与实战.pdf

    《中文版_源码设计模式解析与实战.pdf》是一本专为Android开发者设计的进阶书籍,它深入探讨了设计模式在实际开发中的应用,并结合Android的源码进行了详细的解析。这本书不仅涵盖了基础的设计模式概念,还通过丰富...

    深入浅出设计模式附书源码Java版源码

    总的来说,深入浅出设计模式附书源码Java版源代码是一份宝贵的资源,对于想要提升Java设计能力的开发者来说,它提供了一个实践和学习设计模式的绝佳平台。通过实际操作和调试代码,你可以更好地理解和掌握这些模式,...

    X-gen PPT下载——《研磨设计模式》 实战

    《研磨设计模式》实战是IT领域中关于软件设计的一份重要资料,它主要探讨了设计模式在实际项目中的应用。设计模式是软件工程中经过长期实践总结出的通用问题解决方案,是解决常见设计问题的经验总结。这份PPT可能是...

    二十三种设计模式【PDF版】

    设计模式之 Decorator(装饰器) Decorator 是个油漆工,给你的东东的外表刷上美丽的颜色. 设计模式之 Bridge(桥连) 将牛郎织女分开(本应在一起,分开他们,形成两个接口),在他们之间搭建一个桥(动态的结合) 设计模式...

    Python编程实战-运用设计模式、并发和程序库创建高质量程序.pdf

    《Python编程实战-运用设计模式、并发和程序库创建高质量程序》这本书深入探讨了如何利用Python语言的强大功能来构建高效、可靠且可扩展的软件。它涵盖了三个关键领域:设计模式、并发处理以及Python标准库的运用,...

    Python编程实战:运用设计模式、并发和程序库创建高质量程序

    在阅读《Python编程实战:运用设计模式、并发和程序库创建高质量程序》这本迷你书时,读者将有机会深入学习上述概念,并通过实例学习如何在实际项目中应用。通过这份资料,开发者不仅可以提升个人技能,还能为团队...

    设计模式相关资料

    5. **实战应用**:设计模式并不仅仅停留在理论层面,而是要实际应用到项目中。通过分析和重构代码,我们可以识别出潜在的设计模式,并用它们来优化现有架构。此外,很多知名框架和库,如Spring、Hibernate等,都大量...

    china-pub版-设计模式

    此外,设计模式本身也在不断发展和完善之中,新的模式不断涌现,现有的模式也在不断完善。 总之,设计模式是面向对象设计中的重要工具,它不仅帮助设计者解决常见问题,还促进了软件开发的标准化和高效化。通过对...

    设计模式培训

    设计模式是软件工程中的一种重要...设计模式的学习并非一蹴而就,它需要时间和实践去沉淀。在培训过程中,我们将提供丰富的案例和实战练习,帮助学员从理论到实践,真正掌握设计模式的精髓,让编程变得更简单、更方便。

    Android源码设计模式解析与实战 pdf 版

    其次,结构型设计模式,如适配器模式(Adapter)、代理模式(Proxy)和装饰器模式(Decorator),在Android UI组件和数据绑定中起着关键作用。适配器模式使得不同的接口能够协同工作,如ListView的Adapter将数据源...

    设计模式详解,设计模式

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

    设计模式-可复用面向对象软件的基础

    2. 结构型模式:关注如何将类或对象组合成更大的结构,例如适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、装饰模式(Decorator)、外观模式(Facade)、享元模式(Flyweight)和代理模式...

    软件设计模式与体系结构孙云山课后习题234章答案.zip

    在IT领域,设计模式是软件开发中的重要概念,它们代表了在特定上下文中解决常见问题的最佳实践。孙云山老师的“软件设计模式与体系结构”课程深入探讨了这些模式及其在构建复杂系统中的应用。本资料集合包含了课后...

    设计原则与模式,java23种设计模式项目实战pdf文档视频资源.rar

    通过这个Java23种设计模式项目实战的PDF文档和视频资源,开发者可以学习如何在实际项目中应用这些模式,提高代码质量,优化设计,降低维护成本。这些资源对于想要提升自己Java编程技能和项目实践经验的开发者来说,...

    Java设计模式demo

    在《Android源码设计模式解析与实战》这本书中,作者可能通过示例代码展示了如何在Android开发中应用这些设计模式。例如,单例模式在Android中的应用非常广泛,如应用程序的全局上下文Context;工厂模式可能用于创建...

    关于《设计模式》的好书,佷很有用

    总的来说,《设计模式》这本书不仅涵盖了基本的设计模式理论,还提供了丰富的实战案例,是每个想要提升软件设计能力的开发者必读之作。通过学习并掌握这些设计模式,开发者可以更好地应对复杂系统的设计挑战,编写出...

    Android源码设计模式解析与实战

    Android源码设计模式解析与实战是一本关于Android开发的高级技术...它不仅能帮助读者从宏观角度掌握设计模式的精髓,也能通过实例分析和实战演练,加深对Android源码设计思想的理解,从而更好地应用于实际开发之中。

    C++设计模式课件26_设计模式总结.pdf

    通过对C++设计模式的学习和实践,开发者不仅可以提高代码质量和可维护性,还能增强解决问题的能力。理解并熟练掌握这些模式对于成为一名优秀的软件工程师至关重要。此外,随着技术的发展,新的设计模式也会不断出现...

    Android源码设计模式解析与实战.pdf

    根据提供的文件信息,“Android源码设计模式解析与实战.pdf”主要关注的是在Android开发中如何应用设计模式,并通过具体的源代码实例来进行深入分析与实践。下面将围绕这一主题展开详细的介绍,包括设计模式的基本...

Global site tag (gtag.js) - Google Analytics