由JDBC联想到的5中设计模式

JDBC联想到的5中设计模式:

1、策略模式:

主要强调算法封装和自由切换

2、代理模式:

为其它对象提供一种代理以控制对这个对象的访问

3、装饰者模式:

动态添加类的功能,实现继承更灵活的扩展方式

4、门面模式:

系统对外提供一个统一简单的接口,减少系统间的耦合性

5、模版模式:

将代码的公共行为提取出来,达到复用的目的

 

 

一、首先就是策略模式,我们在连接数据库时,并非一种数据库,比如,有时是MySql,有时是Oracle,有时又是SQL Server,都要涉及数据库的切换,此时,我们就可以将数据库连接的算法封装起来,使它们可以相互替换。

首先我们定义一个策略接口,用来表示数据库的连接。

package strategy;

public interface Strategy{

public void getConnDB();

}

然后我们实现了对具体策略类:三大数据库的连接,我们在这里知识强调模式的实现,简单起见,不实现JDBC的连接的具体操作,下面的也是一样。

MySql:

public class MysqlStrategy implements Strategy{

public void getConnDB(){

System.out.println(connect MySQL);

}

}

Oracle:

public class OracleStrategy implements Strategy{

public void getConnectDB(){

System.out.println(connect oracle);

}

}

SQL Server:

public class SQLStrategy implement Strategy{

public void getConnectDB(){

System.out.println(connect SQL Server);

}

}

策略应用场景,方便在运行时动态选择具体要执行的行为

public class ClientContext{

Strategy strategy;

public ClientContext(Strategy strategy){

this.strategy = strategy;

}

public void getConnectDB(){

strategy.getConnectDB();

}

}

下面测试:

public class StrategyTest{

public static void main(String args[]){

 

/**

*策略模式实现对Oracle的连接操作

*/

ClientConext occ = new ClientContext(new OracleStrategy());

occ.getConnDB();

 

/**

*策略模式实现对Mysql的连接操作

*/

ClientConext occ = new ClientContext(new MysqlStrategy());

occ.getConnDB();

 

/**

*策略模式实现对SQL Server的连接操作

*/

ClientConext occ = new ClientContext(new SQLStrategy());

occ.getConnDB();

 

}

}

 

 

这样,就基本完成通过策略模式动态切换数据库连接的算法.如果想实现对DB2,Sybase,PostgreSQL数据库的操作.只需实现策略接口即可.这样就可以任意扩展.同时对客户(StrategyTest)隐藏具体策略(算法)的实现细节,彼此完全独立。完全做到高内聚,低耦合  

到这里,突然改变需求,需要在数据库连接之前增加一些日志的打印输出.按照传统的做法,我们修改每一个具体的实现类,增加这些功能,如果先前我们实现的具体类非常多.这无异是一笔不小的负担.而且也违反了开闭原则(OCP).  

    这里大家可能想到在学习Spring AOP常提到的用AOP打印日志的情景.AOP主要用到了代理模式.这里

我们也通过代理模式来实现.由于抽象策略类是接口,所以我们采用JAVA 反射中提供的代理.  

二、代理模式具体实现 

public class ProxyDB implements InvocationHandler {      

private Object target;      

publicProxyDB(Object target) {     

this.target = target;         

}      

        

  //此处为我们要额外添加的方法进行日志的打印输出    

public void printLog() {     

System.out.println("---------------打印输出点日志----------");        

}      

       

      // 代理业务处理器     

public Object invoke(Object proxy, Method method, Object[] args)     throws Exception {     

printLog() ;     

return  method.invoke(this.target, args);        

 }      

public static void main(String[] args) {            

          // 通过代理模式在连接Mysql前增加日志的打印输出;    

MysqlStrategyms = new MysqlStrategy();     

ProxyDBproxyCorps = new ProxyDB(ms);   Strategy realObject = (Strategy) Proxy.newProxyInstance(ms.getClass().getClassLoader(), ms.getClass().getInterfaces(), proxyCorps);     

realObject.getConnDB();      

         // 通过代理模式在连接 Oracle前增加日志的打印输出;  

OracleStrategyos = new OracleStrategy();     

ProxyDB proxyCorps1 = new ProxyDB(os);

Strategy realObject2 =  (Strategy)Proxy.newProxyInstance(os.getClass().getClassLoader(),os.getClass().getIntegerfaces(),proxyCorps1);

realObject1.getConnDB();

//通过代理模式在连接SQL Server前增加日志的打印输出;

SQLStrategy ss = new SQLStrategy();

ProxyDB proxyCorp2 = new ProxyDB(ss);

Strategy realObject2 = (Strategy)Proxy.newProxyInstance(ss.getClass().getClassLoader(),ss.getClass().getIntegerfaces(),proxyCorp2);

realObject2.getConnDB();

}

}

难道只能通过代理来增加日志功能?这时又突然想到装饰者(Decorator),它本来的目的是对类的实例追加或扩张附加功能,他可以动态的改变一个对象方法的行为,同时也满足设计原则中的开闭原则。

三、装饰者模式(Decorator);

 

public class Decorator implements Strategy{

private Strategy strategy;

public Decorator(Strategy strategy){

this.stratey = strategy;

}

//额外增加的功能,通过装饰者模式动态改变原来对象方法的行为

public void printLog(){

System.out.println(===========先打印输出点日志===========);

}

public void getConnDB(){

printLog();

strategy.getConnDB();

}

 

public static void main(String args[]){

//Oracle连接前增加日志的输出

Decorator decorator = new Decorator(new OracleStrategy());

decorator.getConnDB();

//Mysql连接前增加日志的输出

Decorator decorator1 = new Decorator(new MysqlStrategy());

decorator1.getConnDB();

}

}

 

四、Facade模式:

为了让子系统中的一组接口提供一个统一接口,Facade模式定义了一个更高层的接口,使子系统更加易使用,在构建一个层次话的系统的时候,可以使用Facade模式定义系统的没一层的入口,如果层与层之间是相互依赖的,则可以限定他们仅通过Facade进行通信,从而简化了层与层之间的依赖关系

同时也实现了软件设计模式中的迪米特法则(LCP)。

public class Facade{

//通过连接操作,提供一个统一的接口,统一跟外界打交道,减少对具体实现类的依赖

public void getConn(){

OracleStrategy os = new OracleStrategy();

MysqlStrategy ms = new MysqlStrategy();

SQLStrategy ss = new SQLStrategy();

os.getConnDB();

Ms.getConnDB();

ss.getConnDB();

}

public static void main(String args[]){

new Facade().getConn();

}

}

其实JAVAJDBC数据连接本身也采用了门面模式。

最后一个想到的就是模版模式,这个没有代码,可以参考Spring所提供的jdbc抽象框架,其核心就是jdbc模版。


你可能感兴趣的:(由JDBC联想到的5中设计模式)