模式开发—运用配置文件和反射机制重构客户端代码

问题引入:我们在开发软件时,往往因为需求,要频繁的修改源码,在不违背开发原则(单一职责、开放封闭……..)的情况下,往往需要增加功能抽象接口或具体的实现类,而客户端就要相应的修改。
为了让系统具有更好的灵活性和扩展性,使得在不修改任何客户端的代码的基础上,更换新的功能实现。
以工厂方法模式为例:

/**

*@Descriptio0n 工厂方法模式
*@Time 20170-01-01
*/

interface Logger{  //抽象产品
    public void writeLog();
}
class FileLogger implements Logger{ //具体产品1文件日志记录器
    public void writeLog(){
        System.out.println("文件日志");
    }
}   
class DatabaseLogger implements Logger{//具体产品2数据库日志文件记录器
    public void writeLog(){
        System.out.println("数据库日志");
    }
}
interface LoggerFactory{//抽象工厂
    public Logger createLogger();
}
class FileLoggerFactory implements LoggerFactory{//具体工厂1
    public Logger createLogger(){
        return new FileLogger();
    }
}
class DatabaseLoggerFactory implements LoggerFactory{//具体工厂2
    public Logger createLogger(){
        return new DatabaseLogger();
    }
}
class Client{ //客户端代码
    public static void main(String[] args){

        LoggerFactory fac;
        fac = new FileLoggerFactory();  //引入配置文件进行管理
        fac.createLogger().writeLog();
    }
}

解决办法:客户端代码中不再使用new关键字来创建工厂对象,将具体工厂类的类名存储在配置文件(如XML)中,通过读取配置文件获取类名字符串,使用Java反射机制,根据类名字符串生成对象。

config.xml

<!---config.xml->
<?xml version="1.0"?>
<config>
    <className>FileLoggerFactory</className>
</config>

XMLUtil.java

//工具类XMLUtil.java
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
public class XMLUtil{
    public static Object getBean(){
        try{
            DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dFactory.newDocumentBuilder();
            Document doc;
            doc = builder.parse(new File("config.xml"));
            NOdeList nl = doc.getElementByTagName("className");
            Node classNode = nl.item(0).getFirstChild();
            String cName = classNode.getNOdeValue();

            //通过类名生成实例对象并将其返回
            Class c = Class.forName(cName);
            Object obj = c.newInstance();
            return obj;
        }
        catch(Exception e){
            e.printStackTrace();
            return null;
        }
    }
}

此时客户端代码便可以如下:

class Client{ //客户端代码
    public static void main(String[] args){

        LoggerFactory fac;

        fac = (LoggerFactory)XMLUtil.getBean();  //引入配置文件进行管理
        fac.createLogger().writeLog();
    }
}

引入XMLUtil类和XML配置文件后,如果要新增日志记录方式,只需增加新的具体产品与具体工厂,根据客户端的需求修改相应的config.xml文件,客户端代码无需做任何修改


其他模式的学习,完全可以按照上面的方法,通过重用XMLUtil类,来简化设计

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值