文档章节

【2016-03-26】《修改代码的艺术》:The Seam Model

rathan0
 rathan0
发布于 2016/03/26 14:25
字数 606
阅读 55
收藏 3
点赞 1
评论 0

Seam定义:

A seam is a place where you can alter behavior in your program without editing in that place。

bool CAsyncSslRec::Init()
{
    if (m_bSslInitialized) {
        return true;
    }
    m_smutex.Unlock();
    m_nSslRefCount++;
    m_bSslInitialized = true;
    FreeLibrary(m_hSslDll1);
    m_hSslDll1=0;
    FreeLibrary(m_hSslDll2);
    m_hSslDll2=0;
    if (!m_bFailureSent) {
        m_bFailureSent=TRUE;
        PostReceiveError(SOCKETCALLBACK, SSL_FAILURE);
}
    CreateLibrary(m_hSslDll1,"syncesel1.dll");
    CreateLibrary(m_hSslDll2,"syncesel2.dll");
    m_hSslDll1->Init();
    m_hSslDll2->Init();
    return true;
}

例如上面这段C++,如果PostReceiveError是一个严重依赖其他子系统的全局函数,并且这个子系统在测试的时候难以交互,用什么方式可以绕过PostReceiveError函数呢?

可以这样:

void CAsyncSslRec::PostReceiveError(UINT type, UINT errorcode)
{
    ::PostReceiveError(type, errorcode);
}

在CAsyncSslRec中写一个同名的方法,然后它的实现委托给全局的PostReceiveError方法。
其中::在C++中是域操作符(scoping operator),在Java中是没有的

class TestingAsyncSslRec : public CAsyncSslRec
{
    virtual void PostReceiveError(UINT type, UINT errorcode)
    {
    }
}

在测试类中写一个同样的方法,可以在测试的时候调用测试类中的PostReceiveError。

以上方法叫做Object seam. 原书定义如下(不翻译了):

We were able to change the method that is called without changing the method that calls it. 


Seam的类型:

  • Preprocessing Seams,主要用于C/C++(跳过没看)

  • Link Seams

  • Object Seams:在OOP中用处比较大


Link Seams的Java例子。

有如下类:

package fitnesse;
import fit.Parse;
import fit.Fixture;
import java.io.*;
import java.util.Date;
import java.io.*;
import java.util.*;
public class FitFilter {
    public String input;
    public Parse tables;
    public Fixture fixture = new Fixture();
    public PrintWriter output;
    public static void main (String argv[]) {
        new FitFilter().run(argv);
    }
    public void run (String argv[]) {
    args(argv);
    process();
    exit(); 
    }
    public void process() {
        try {
            tables = new Parse(input);
            fixture.doTables(tables);
        } catch (Exception e) {
            exception(e);
        }
        tables.print(output);
    }
    ... 
}

在这个类中,引用了fit.Parse 和 fit.Fixture,JVM如何找到这些类呢?通过classpath环境变量。

可以创建同样名字的类,把它们放到别的目录中,修改classpath(enabling point),link到我们加的fit.Parse 和 fit.Fixture,虽然再生产环境中使用有些费解,但是这个方法在测试的时候是一个好的切入点。


在OOP中,继承关系中很多方法调用都是seam,但并不是所有的都是seam,比如这种:

public void method1(){
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
}

因此此处没有enabling point,我们如果想换一个add方法,必须要修改代码

但是下面这种是seam,enabling point是method1的参数(这个好理解,毕竟多态的作用就是消除类型之间的耦合关系):

public void method1(List<Integer> list){
    list.add(1);
}

书中举了个Cell类的例子,异曲同工

public class CustomSpreadsheet extends Spreadsheet
{
    public Spreadsheet buildMartSheet(Cell cell) {
        ...
        cell.Recalculate();
        ... 
    }
}



© 著作权归作者所有

共有 人打赏支持
rathan0
粉丝 4
博文 60
码字总数 36282
作品 0
程序员
Fly的狐狸/Jflyfox

个人博客 博客地址:http://www.jflyfox.com/blog 本网站后台基于Jfinal开发,模板基于beetl,数据库为Mysql。 老版本地址如下 演示地址:http://jflyfox.oschina.mopaas.com/ 管理地址:htt...

Fly的狐狸 ⋅ 2014/11/04 ⋅ 0

发布项目,加入CRUD功能

文章来源:http://blog.ddlisting.com/2016/04/16/fa-bu-xiang-mu-jia-ru-crudgong-neng/ 接着前面三篇: 环境搭建以及使用Ember.js创建第一个静态页面 引入计算属性、action、动态内容 模型...

ubuntuvim ⋅ 2016/04/16 ⋅ 4

从服务器获取数据,引入组件

博文原址:http://blog.ddlisting.com/2016/04/21/yin-ru-zu-jian/ 接着前面四篇: 环境搭建以及使用Ember.js创建第一个静态页面 引入计算属性、action、动态内容 模型,保存数据到数据库 发...

ubuntuvim ⋅ 2016/04/26 ⋅ 0

江南红衣/jfinalshop-2.0

成功不仅是你拥有多少,更重要的是你帮助他人多少,有多少人因你而感动、因你而成长。 最新版地址 请点查看; jfinalshop-3.0 项目说明 本项目是基于jfinalshop2.0开发,JFinal2.0改成了JFi...

江南红衣 ⋅ 2016/10/27 ⋅ 0

spring4+jdk8+tomcat8启动报错,求解

2016-06-03 21:39:26,712 [localhost-startStop-1] DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating instance of bean 'org.springframework.con......

hou_1993 ⋅ 2016/06/03 ⋅ 2

jenkins安装过程中tomcat界面访问问题

1.系统环境: ubutu12.04 vagrant-ubutu(tomcat安装在虚拟机中) java: java version "1.8.0_111" Java(TM) SE Runtime Environment (build 1.8.0_111-b14) Java HotSpot(TM) Client VM (b......

渺渺星辰 ⋅ 2016/11/15 ⋅ 0

tail,head,grep

1 tail tail -n 2 1.txt 表示显示文件后两行 [root@myvm tmp]# cat 1.txt|tail -n 2 manages managen 2 head -n 3 1.txt表示显示文件前3行 [root@myvm tmp]# cat 1.txt|head -n 3 Fri Sep 3......

wzl_up ⋅ 2016/09/30 ⋅ 0

【2016-03-26】《修改代码的艺术》:Sprout & Wrap

事实上,去掉依赖及写测试需要一点时间,很多情况下,人们会选择节省时间的方式(省去测试)。 写测试情况的时间花销: 为要修改的代码写测试,花掉2小时; 修改这部分代码,花掉15分钟; 表...

rathan0 ⋅ 2016/03/27 ⋅ 0

baigo CMS v1.2.2 发布,CMS 建站系统

baigo CMS v1.2.2 发布了。 -------------------v1.2.2------------------- 2016-04-26 修复自动部署 SSO 时存在的 bug 2016-03-21 进一步优化发表、编辑文章时,选择专题的方式 2016-03-08...

baigoStudio ⋅ 2016/05/20 ⋅ 0

模型高级特性,引入模型关联关系

博文原址:模型高级特性,引入模型关联关系 接着前面五篇: 环境搭建以及使用Ember.js创建第一个静态页面 引入计算属性、action、动态内容 模型,保存数据到数据库 发布项目,加入CRUD功能 ...

ubuntuvim ⋅ 2016/04/27 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

spring Email

一、普通邮件 maven依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.2.6.RELEASE</version>......

BobwithB ⋅ 7分钟前 ⋅ 0

spark 整理的一些知识

Spark 知识点 请描述spark RDD原理与特征? RDD全称是resilient distributed dataset(具有弹性的分布式数据集)。一个RDD仅仅是一个分布式的元素集合。在Spark中,所有工作都表示为创建新的...

tuoleisi77 ⋅ 10分钟前 ⋅ 0

思考

时间一天天过感觉自己有在成长吗?最怕的是时光匆匆而过,自己没有收获!下面总结下最近自己的思考。 认识自己 认识另一个自己,人们常说要虚心听取别人意见和建议。然而人往往是很难做到的,...

hello_hp ⋅ 10分钟前 ⋅ 0

IT行业的变革就像世界杯德国对战墨西哥一样难以预测[图]

最近在观看世界杯,尤其是昨天的比赛,上一届卫冕冠军德国队居然0:1告负墨西哥,这创造了历史,首先是墨西哥从来没赢过德国队,其次是德国队36年来首站没输过,再差也是打平,而这次,德国队...

原创小博客 ⋅ 29分钟前 ⋅ 0

解决CentOS6、7,/etc/sysconfig/下没有iptables的问题

一、Centos 6版本解决办法: 1.任意运行一条iptables防火墙规则配置命令: iptables -P OUTPUT ACCEPT 2.对iptables服务进行保存: service iptables save 3.重启iptables服务: service ...

寰宇01 ⋅ 40分钟前 ⋅ 2

数据库备份和恢复

备份:mysqldump -u root -p 数据库>磁盘路径 恢复:mysql -u root -p 数据库<sql脚本的磁盘路径

anlve ⋅ 今天 ⋅ 0

发生了什么?Linus 又发怒了?

在一个 Linux 内核 4.18-rc1 的 Pull Request 中,开发者 Andy Shevchenko 表示其在对设备属性框架进行更新时,移除了 union 别名,这引发了 Linus 的暴怒。 这一次 Linus Torvalds 发怒的原...

问题终结者 ⋅ 今天 ⋅ 0

在树莓派上搭建一个maven仓库

在树莓派上搭建一个maven仓库 20180618 lambo init 项目说明 家里有台树莓派性能太慢。想搭建一个maven私服, 使用nexus或者 jfrog-artifactory 运行的够呛。怎么办呢,手写一个吧.所在这个...

林小宝 ⋅ 今天 ⋅ 0

Spring发展历程总结

转自与 https://www.cnblogs.com/RunForLove/p/4641672.html 目前很多公司的架构,从Struts2迁移到了SpringMVC。你有想过为什么不使用Servlet+JSP来构建Java web项目,而是采用SpringMVC呢?...

onedotdot ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部