`
pz818
  • 浏览: 4987 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

个体现Java接口及工厂模式优点的例子

阅读更多

  随着模式概念的普及,了解模式和使用模式的程序员越来越多,很多人在学习模式的时候,都会有这样一种疑惑:“有必要搞得这么复杂吗?”。的确,因为教程的例子过于简单化(这样方便读者学习),或者是作者选例子的时候并没有很好体现所讲模式的优点,很多情况下如果仅就其例子的问题来说,用模式是太复杂了。因此才导致这样的误解:“模式就是把简单的问题复杂化吗?”。当然不是,随着你开发实践的不断丰富,你终会发现模式强大威力,而且模式也并非贵族化的编程方式,它就是一些经过提炼了的解决问题的方法技巧。
      通过学习模式,程序员开始告别过去准直线式的代码方式,模式开扩了我们的视野,强化了我们面向对象编程的思维方式。然而现在又出现了另一个普遍的问题,盲目应用模式。模式是问题的解决方案,先有问题才有模式,模式是依附于所要解决的问题的而生的。必须了解模式在很多情况下是以提高代码的复杂度为代价来增强灵活性、可复用性。如果在自已的代码中使用某一模式仅只提高了代码的复杂度,而其它方面收效甚微,或者某部份代码根本就不存在灵活性及高复用性的需求,那么我们就没有必要为使用模式而放弃更直观简单的代码写法。


      一流的高手90%精力关注问题的解决方案,因为找到了好的解决方案,再写起代码会很轻松代码也简洁流畅,看这样的代码是一种享受和提高;二流的熟手90%精力关注代码实现,因为问题的解决方案并非最佳,实现的代码也会比较复杂;三流菜鸟记流水帐,90%精力在敲键盘,常常做了大半才发现行不通,回过头来再用90%的时间敲键盘,根本不会用到任何模式,写出来的代码的只有他自已才能看懂。做出来的软件也是支离破碎,做一丁点改动都要大费周折,而且你还不知道改动后会产生什么问题,大有住危房里的感觉。

      在这里还是举一个滥用模式的例子吧。我曾参与过一个大集团公司OA系统的第二期开发,开发沿用原有代码架构并增加新的功能模块。文档很少我读原代码时就被它程序里的代码转来转去搞得头大如斗,最后读懂了:原代码架构总体采用工厂模式,而且是最复杂的抽象工厂模式。它把所有模块类都通过工厂生成还工厂套工厂,并且每一个模块类都有一个接口,每个接口也只有一个模块现实类,因为涉及权限控制还用了代理(proxy)模式。 读懂代码后我开始嵌入代码,发现每新增一个类,都要到六个Java文件中去增加相应代码,而在类中每增加一个方法,也要到它的接口等四个Java文件中去增加相应代码。天呀!!!记得当时我的小姆指常会不听使唤,就是因为频繁的使用Ctrl+C 、Ctrl+V,小姆指按着Ctrl键给累的。整个项目组苦不堪言,真烦透了。项目结束后我回顾发现:代理模式用得还对(现在针对权限这类横向控制有AOP编程这种新的解决办法了)但工厂模式在这里根本就是画蛇添足,不仅没有解决什么问题,反而增加代码复杂度和耦合性,降低了开发效率连维护难度都提高了。而且那种每个类简单的加一个接口的方式,更是没有道理,这让我很想说周星驰说过的一句话:“球~~~不是这么踢~~~~的,接口~~~不是这么用~~~的”。言归正传,我们先来看这样一个常见问题:某系统需要支持多种类型的数据库。用过Oracle、MSSQL等数据库的人都知道,它们的SQL编写方式都各有些不同。比如说Oracle的唯一标识自动+1字段用的是序列,MSSQL改一下字段属性就成了,还有各种各自特有的SQL用法。为了支持多数据库,难道我们要开发多套系统?当然NO。请看下面的解决方案。

      即然数据库存在多种,我们可以将系统中所有对数据库的操作抽象出来,写成一个个方法组合到一个类中,有几种数据库我们就写几个这样的类。具体设计类图如下:



简要说明:

  • OracleDataOperate、SqlserverDataOperate、MysqlDataOperate,分别代表Oracle、Sqlserver、Mysql这三种数据库的操作类。继承自AbstractDataOperate
  • AbstractDataOperate是一个抽象类,包含了那些不同种类数据库都是一样代码的操作方法。继承自DataOperate
  • DataOperate是上面说的数据操作类的统一接口,只有两个方法:取得一条记录、插入一条记录。
  • DataOperateFactory是一个工厂方法,统一用它的方法来得到数据库操作类的实例。
  • SampleClass是我们系统的某个功能模块的类。
  • People是一个实体类,代表一条记录。三个字段 oid唯一标识符、name姓名、date生日。


详细说明:
1、所有系统功能模块类只认DataOperat这个接口还不必管具体的实现类是OracleDataOperate还SqlserverDataOperate。DataOperate源代码如下:
publicinterface DataOperate {
    //根据记录的唯一标识取出一条记录
    People getPeople(String oid);
    //插入一条记录
    boolean insertPeople(People people);
}

2、AbstractDataOperate、OracleDataOperate、SqlserverDataOperate、MysqlDataOperate都是继承DataOperate接口的,没什么好说的,省略。

3、DataOperateFactory。我们看看工厂方法怎么写的。
publicclass DataOperateFactory {
    publicstaticfinalint ORACLE = 0; //定义三个表示数据库类型的常量
    publicstaticfinalint MYSQL = 1;
    publicstaticfinalint SQLSERVER = 2;

    privatestatic DataOperate db;
    privatestaticint dataType = MYSQL;
    /**
     * 根据数据库类型(dataType)取得一个数据库操作类的实例,
     * 这里对DataOperate使用了单例模式,因为OracelDataOperate等都是无状态的工具类,
     * 所以整个系统只保留一个实例就行了。
     *
     * @return 返回的是接口,客户端不必关心具体是用那个实现类
     */
    publicstatic DataOperate getInstance() {
        if (db == null) {
            if (dataType == ORACLE) //根据dateType返回相应的实现类
                returnnew OracelDataOperate();
            if (dataType == MYSQL)
                returnnew MysqlDataOperate();
            if (dataType == SQLSERVER)
                returnnew SqlserverDataOperate();
        }
        return db;
    }
}

4、接下来就看看使用端是如何调用工厂方法和使用数据操作类的。
/**
* 系统某个功能类
*/
publicclass SampleClass {
private DataOperate db; //声明一个数据库操作类,注意这里用的是接口噢
    /**某方法*/
    publicvoid sampleMethod() {
        db = DataOperateFactory.getInstance();//得到单一实例
        People p = db.getPeople("123"); //取得一条记录
        db.insertPeople(p);//再插回去
    }
}

  我们发现SampleClass中根本没有出现OracelDataOperate、MysqlDataOperate等的影子,这就是接口的威力。客户端不必针对OracelDataOperate等写不同的代码,它只关心DataOperate即可,具体要取那个类的逻辑就由DataOperateFactory负责了。

总结:

  • 从例子中我们可以看到什么是面向接口的编程方式。SampleClass使用数据操作类可以不必关心具体是那个类,只要是符合接口的都行
  • 要实例?只须调用DataOperateFactory.getInstance()即可,其它的交于DataOperateFactory这个工厂来做吧,使用端什么都不用关心。
  • 我们要支持新的数据库类型,只须要象OracelDataOperate那样,再写一个继承AbstractDataOperate的类即可,比如SysbaseDataOperate。然后到DataOperateFactory中加入相应代码即可。
  • 如果我们想要可配置性更高,可以用privatestaticint dataType = MYSQL;中的值设置到一个文本文件中。

  对于开发支持多种数据库的系统,强烈建议使用hibernate,我现在做的系统就是用hibernate的,开发时用Mysql,到要给客户时将数据库换了DB2,程序不用做任何改动,真正的无逢移植。不过这样,本文所提到的方法就没什么用了.

分享到:
评论

相关推荐

    设计模式 java

    在例子中,“我爱你”翻译机的构建过程就体现了建造者模式,每个方言对应一个建造过程。 2. 结构模式: - 这部分没有在给定的内容中提及,但结构模式包括适配器模式、装饰器模式、代理模式、桥接模式、组合模式、...

    Java与模式(含示例代码)

    14.6 抽象工厂模式的另一个例子.....211 14.7 “开-闭”原则..............................212 14.8 关于模式的实现.........................213 14.9 女娲造万物的故事.....................214 第15 章 单例...

    单例设计模式的优缺点和设计思想

    单例设计模式是一种在软件工程中广泛使用的创建型设计模式,其核心思想是确保一个类仅有一个实例,并提供一个全局访问点。这种模式在多种场景下具有显著的优势,同时也存在一定的局限性和潜在的问题。 ### 单例设计...

    上转型对象体现多态

    工厂模式的主要优点是将对象的创建与使用分离,提高了系统的灵活性和可扩展性。例如,可以创建一个工厂类来负责创建不同类型的产品对象。 #### 策略模式 策略模式是一种行为型设计模式,它使你能在运行时改变对象...

    Ioc模式和微容器——j道

    1. **引入接口**:通过让`A`类实现一个接口`AInterface`,`B`类通过这个接口与`A`交互,这样即使`A`的具体实现发生了变化,只要保持接口不变,`B`类就不需要修改。 ```java public interface AInterface { void ...

    面试注意事项

    12. 在Java中,如何实现设计模式,如单例模式或工厂模式? 13. 请阐述JDBC的工作流程及注意事项。 14. 什么是AJAX,它如何与Java Web应用交互? 15. 什么是Maven?它在项目管理中扮演什么角色? 16. 请分享一次你在...

    学习Java,你需要知道这些——三大特性之多态

    在Java编程语言中,多态性(Polymorphism)是其三大核心特性之一,与封装和继承并列。...在实际开发中,多态的应用无处不在,如集合框架中的泛型、设计模式中的工厂方法等,都是多态概念的具体体现。

    restful——webservice

    总结来说,这个例子展示了如何利用Restlet框架构建RESTful Web服务,包括URL映射、数据库访问、资源操作和数据转换。尽管Restlet提供了许多优点,但为了提高系统性能和安全性,还可以考虑进一步集成Spring框架、优化...

    2021-2022计算机二级等级考试试题及答案No.9034.docx

    - **适配器类**:为了减少代码冗余,Java提供了多个适配器类,它们实现了接口中的所有方法,但这些方法都为空实现。 #### 26. URL结构 - **HTTP协议**:URL中的`http://`表示使用超文本传输协议(HTTP)。此部分后续...

    C++语言程序设计课后答案(清华大学郑莉

    面向对象编程语言与传统的面向过程编程语言有着本质的区别,主要体现在以下几个方面: - **对象的抽象**:面向对象编程语言将现实世界中的事物抽象为“对象”,每个对象都有自己的状态(属性)和行为(方法)。 - *...

Global site tag (gtag.js) - Google Analytics