现在的位置: 首页 > 综合 > 正文

系统设计时请预留出扩展的余地

2013年09月07日 ⁄ 综合 ⁄ 共 1986字 ⁄ 字号 评论关闭

      最近把lightportal代码down下来一份,运行了一把,看的不多,但是被系统中一个小小的功能点吸引住了,感叹作者优秀的设计能力的同时,也在反思自己设计上的问题。

       先来看下这个小小小小的东东是什么,做过项目的同学都知道,有些资源是需要在系统加载时就要被启动起来的,而且这些东西只需要启动一次,运行时程序只要直接读取就可以了,在j2ee中,一般都用Listener来实现(实现ServletContextListener)将初始化操作写在对应的contextInitialized方法中,大家常用的用于启动Spring容器的org.springframework.web.context.ContextLoaderListener。但是系统的需求总是在变化的,最初Listener初始化中的逻辑可能并不能满足后期业务发展的需要,怎么办呢?那就改吧,在contextInitialized方法中添加一块又一块的补丁--这也是最经常能想到的,更好一些的解决方案是把新增的需求写在另一个listener中,然后在web.xml中配置一下,这个是个不错的解决方案,对于方案1来讲已经进步了很多了--将变动的东西封装到了新的类里,也遵守软件设计的开闭原则,对旧类屏蔽了改动,而只作功能的增加。

      同一个业务系统对不同的用户可能有不同的需求,如客户1可能希望系统初始化时就把一些资源加载到本地,允许有一些数据上的不同步性,有些用户则对数据同步有严格要求,希望系统初始化时永远不要搞这些操作或者有些自己的特殊需求,怎么办?看来方案2也不能很优雅的解决这个问题。这时候我们来看下lightportal是怎么解决这个问题的:

      首先,还是定义一个系统Listener,在contextInitialized方法中执行初始化造作--呵呵,用的还是最基本的j2ee的东西吗

       再次,怎么做到通用与个性化的平衡?仔细看contextInitialized方法中,其实没有任何的业务处理代码,只是一个简单的循环!!业务逻辑代码哪里去了?被封装到一个个具体的类里去了!不过这些类都有一个统一的接口,启动时执行哪些类是定义在配置文件中的,来细看下

      配置文件config.properties

      events.startup=/

                                  org.light.portal.core.event.StartupEventImpl

      这个配置文件有点意思,为什么用/然后另起一行?当一个key有多行的文本值时就需要这么配置了

      然后看程序处理逻辑

      public class ApplicationListener implements ServletContextListener ....

      public void contextInitialized(ServletContextEvent ce) {

             try{

                   for(String event : _EVENTS_STARTUP){//这个_EVENTS_STARTUP就是从配置文件中读取的 events.startup的值,

                         Object eventObject = Class.forName(event).newInstance();;//利用java的反射机制来生成具体对象

                          if(eventObject instanceof StartupEvent){

                               StartupEvent startupEvent = (StartupEvent)eventObject;

                                startupEvent.execute(ce.getServletContext());//执行具体的逻辑

                          }

                     }

             }catch(Exception e){

                   logger.error(e.getMessage());

             }

       }

      总结下这样的实现好处在哪里?

       1.变动的只是配置文件

           配置文件本来就是为了变化而生的,程序的骨架逻辑不会放声任何改动--只是一个再简单不过的for循环,个性的功能在配置文件中得以体现

       2.对修改关闭,对扩展开放

           统一上层接口--StartupEvent,新功能在子类中实现,程序骨架只对上层接口造作,不关系具体的实现类--对接口编程的优秀实践

       3.java反射机制

            java发射机制为动态加载类提供很好的实现方案,在配置文件中配置类的完成路径名,然后反射机制加载具体对象,这个时候反射带来的效率牺牲不值一提

 

 

 

抱歉!评论已关闭.