代码整洁之道 第8章 边界

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ymybxx/article/details/83934152

所谓的“边界”是指外来代码(三方程序包、开放源代码、其他团队打造的组件和子系统)和自己写的代码之间进行整合的连接区域

1.使用第三方代码

以Map为例
比如应用程序可能构造一个map对象并传递它。我们的初衷可能是map对象的所有接收者都不要删除映射图中的任何东西。但map正好有一个clear方法

Map<Sensor> sensors = new HashMap<Sensor>();
Sensor s = sensors.get(sensorId)

Map 提供了超出/所愿的功能的问题
在系统中不收限制的传递Map的实体,意味着当Map的接口被修改的时,有许多地方都要跟着改。

使用Map更整洁的方式大致如下。Sensors的用户不关心是否用了泛型,那将是实现细节才关心的

public class Sensor {
    private Map sensors = new HashMap();

    public Sensor getById(String id){
        return (Sensor) sensors.get(id);
    }
}

如果你要使用类似Map这样的边界接口,就把它保留在类或近亲类中。
避免从公共api中返回边界接口,或将边界接口作为参数传递给公共api

2.浏览和学习边界

在利用第三方程序包时,该从何入手呢。
我们没有测试第三方代码的职责,但为要使用的第三方代码编写测试,可能最符合我们的利益。
不要在生成代码中实验新东西,而是编写测试来遍览和理解第三方代码。
在学习性测试中,我们如在应用中那样调用第三方代码。我们基本上是在通过核对试验来检测自己对那个api的理解,测试聚焦于我们想从api中得到的东西

3. 学习log4j

public class LogTest { 
    private Logger logger;

    @Before
    public void initialize() {
        logger = Logger.getLogger("logger"); 
        logger.removeAllAppenders();    
        Logger.getRootLogger().removeAllAppenders();
    }

    @Test
    public void basicLogger() {
        BasicConfigurator.configure();
        logger.info("basicLogger"); 
    }

    @Test
    public void addAppenderWithStream() {
        logger.addAppender(new ConsoleAppender( 
                             new PatternLayout("%p %t %m%n"), 
                             ConsoleAppender.SYSTEM_OUT));
        logger.info("addAppenderWithStream"); 
    }

    @Test
    public void addAppenderWithoutStream() {
        logger.addAppender(new ConsoleAppender(
                             new PatternLayout("%p %t %m%n")));
        logger.info("addAppenderWithoutStream");
    }
}

写完这个测试,我们就已经知道怎么去使用log4j了,包括怎么去初始化和配置它,然后我们就可以按照学到的知识把log4j封装成一个我们自己的类,这样它的边界变成我们想要的样子。

4.学习性测试的好处不只是免费

学习性测试是一种精确试验,帮助我们增进对api的理解
当第三方程序包发布了新版本,我们可以运行学习性测验,看看程序包的行为有没有改变
学习性测试确保第三方程序包按照我们想要的方式工作。一旦整合进来,就不能保证第三方代码总与我们的需要兼容。如果第三方程序包的修改与测试不兼容,我们也能马上发现

5.使用尚不存在的代码

还有一种边界,那种将已知和未知分隔开的边界。在代码中总有许多地方是我们的知识未及之处。有时我们并不往边界那边看过去

编写我们想得到的接口,好处之一是它在我们控制之下。这有助于保持客户代码更可读,切集中于它该完成的工作。

实现方式:
用一个Adapter封装与api的互动,当api发生变动时,唯一需要修改就是Adapter

6.整洁的边界

在使用我们控制不了的代码时,必须加倍小心保护投资,确保未来的修改不至于代价太大。

边界上的代码需要清晰的分割和定义了期望的测试。应该避免我们的代码过多的了解第三方代码中的特定信息。

猜你喜欢

转载自blog.csdn.net/ymybxx/article/details/83934152