这里先借鉴一下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模式。