如何通过高内聚低耦合 英文消除Bug

jOOQ:如何通过高内聚消除Bug_ImportNew_传送门
jOOQ:如何通过高内聚消除Bug
(点击上方公众号,可快速关注)请先看下面这段代码,直觉告诉我们类似这样的方法可能会带来问题:CompilationTask getTask(
Writer out,
JavaFileManager fileManager,
DiagnosticListener
diagnosticListener,
Iterable options,
Iterable classes,
compilationUnits);这是为什么呢?让我们接着深入研究。这是一个来自Java编辑器的Javadoc的一个示例:Iterable compilationUnits1 =
fileManager.getJavaFileObjectsFromFiles(
Arrays.asList(files1)); compiler.getTask(null, fileManager, null,
null, null, compilationUnits1)
.call();这会带来什么问题呢?我们有很多非常类型分散的参数,它们很可能被设为null。这降低了上述方法的复用性,或者按照JArchitect那帮家伙所说的,我们可能处于“痛苦地带”,因为这些方法具备低层次的稳定性和抽象性。低稳定性: 在Java编辑器的将来版本,极有可能我们需要另一个指定的参数,例如另一个实现Iterable的类实例。这会增加API的不兼容性。低抽象性: 即使上述方法是一个接口方法,它也很少有机会被实现多次。因为以一种有用的方式来满足上述约束是很困难的。要规避这类单一方法带来的问题,一种有效途径是使用建造者模式,正如Petri Kainulainen精彩地描述的那样。高内聚解决“痛苦地带”可能你认为对于编译器API来说这并不是很重要。但“高内聚”的最大价值,例如一个理想的稳定/抽象平衡,是能够使你的代码具有很高地重用性。它的美妙之处不仅在于能使你的开发者花费更少的时间完成特定的任务,还意味着你的代码能够很好地避免错误。举个例子,请从JOOQ的网站下载数据类型转化的逻辑代码。上面只是一个单一数据类型转换API的调用层级指引的提取,它被整个框架所使用。所有API都通过那里指引。因此如果存在任何数据类型转换的bug,只有两种极端的表现:定位到上面树的单一方法/单一叶子节点扩展到整棵树换句话说,任何与数据类型转化相关的bug要么只是表面问题,要不就是全面的灾难性问题。这基本上意味着几乎不可能存在区域性的回归测试,因为任何数据类型转换的回归测试都会使得数百个单元测试和集成测试运行失败。如何达到高内聚方法很简单:通过不断地重构。一个新功能应该从不只是局部地引入。举个例子,我们这里考虑问题: [#3023]DefaultRecordMapper没有将嵌入UDT映射为嵌入的POJO,因此我们想将JOOQ的RecordMapperProvider功能应用到嵌入式记录。为什么呢?想象我们有一个PERSON表,它包含Oracle对象类型的ADDRESS和STREET属性。是的,你只是标准化了这些数据,但请想象我们正在使用UDT:CREATE TYPE street_type AS OBJECT ( street VARCHAR2(100), no VARCHAR2(30)); CREATE TYPE address_type AS OBJECT ( street street_type, zip VARCHAR2(50), city VARCHAR2(50));现在,我们想要将这些数据递归映射到自定义的嵌入式POJO:public class Street {
public S} public class Address {
public S} public class Person {
public String firstN
public String lastN
public A}这个映射可以通过下面代码完成:// The configuration object contains the// Mapping algorithm implementationPerson person = DSL.using(configuration)
.selectFrom(PERSON)
.where(PERSON.ID.eq(1)) // We want to make the mapping algorithm recursive// to automatically map Address and Street as well
.fetchOneInto(Person.class);映射一个记录到一个POJO已经实现了,但递归地映射没有实现。当我们实现了递归的方式,我们就会想要重构现有的代码。上述的自定义映射SPI在JOOQ3.1中被引入。它很简单,我们只需具备一个ConvertAll类型的单独实现点就行。基于高内聚代码实现意味着:我们只需实现这个新的功能一次;实现该新功能比写这篇博客花费更少地精力;嵌入式记录映射和对话将以一种形式为所有用例服务;我们再增加了一个很棒的新功能同时,仅增加了很少的复杂度(降低了引入bug的风险)。你不断地重构了吗?我们无法预见完美的设计,它是慢慢地成长起来的。今天,我们知道了很多关于Java和集合的事情,话费了一些时间简单地介绍了新的Streams API。没有人能够随便就在JDK 1.2中实现如此一个伟大的新API,即使以那时的角度看,它已经相当不错了。这对于你来说意味着两件事情:对于你的主要核心代码,要使它达到一个高内聚的状态很重要。如果你有一个电子银行的卖主,你的付款和回扣逻辑应该像上面一个精确,具备一个平衡的稳定性/抽象性比例。对于你的次要代码(例如用户界面、数据库访问),你应该依靠第三方软件,因为其他人花费了更多的时间使他们的代码具有高层次的质量。(用户界面方面:例如Vaadin、ZK,数据库访问方面:例如Hibernate、JOOQ、Spring Data,只列举一部分)。还有,如果你想要一个高内聚架构中的新功能,可能唯一需要完成的事情是这四行代码。出处:ImportNew-will链接:/12472.htmlImportNew 专注 Java 技术分享,欢迎关注。微信号:ImportNew(长按上图 ↑↑↑ 可自动识别二维码)/all-posts点击“阅读原文”,查看更多 Java 文章。↓↓
觉得不错,分享给更多人看到
ImportNew 微信二维码
分享这篇文章
7月2日 15:24
ImportNew 最新头条文章
ImportNew 热门头条文章jOOQ:如何通过高内聚消除Bug - ImportNew
请先看下面这段代码,直觉告诉我们类似这样的方法可能会带来问题:
CompilationTask getTask(
Writer out,
JavaFileManager fileManager,
DiagnosticListener&? super JavaFileObject&
diagnosticListener,
Iterable&String& options,
Iterable&String& classes,
Iterable&? extends JavaFileObject&
compilationUnits
这是为什么呢?让我们接着深入研究。这是一个来自Java编辑器的Javadoc的一个示例:
Iterable&? extends JavaFileObject& compilationUnits1 =
fileManager.getJavaFileObjectsFromFiles(
Arrays.asList(files1));
compiler.getTask(null, fileManager, null,
null, null, compilationUnits1)
这会带来什么问题呢?我们有很多非常类型分散的参数,它们很可能被设为null。这降低了上述方法的复用性,或者,我们可能处于“痛苦地带”,因为这些方法具备。
低稳定性: 在Java编辑器的将来版本,极有可能我们需要另一个指定的参数,例如另一个实现Iterable的类实例。这会增加API的不兼容性。
低抽象性: 即使上述方法是一个接口方法,它也很少有机会被实现多次。因为以一种有用的方式来满足上述约束是很困难的。
要规避这类单一方法带来的问题,一种有效途径是使用,正如Petri Kainulainen精彩地描述的那样。
高内聚解决“痛苦地带”
可能你认为对于编译器API来说这并不是很重要。但“高内聚”的最大价值,例如一个理想的稳定/抽象平衡,是能够使你的代码具有很高地重用性。它的美妙之处不仅在于能使你的开发者花费更少的时间完成特定的任务,还意味着你的代码能够很好地避免错误。举个例子,请从的网站下载数据类型转化的逻辑代码。
上面只是一个单一数据类型转换API的调用层级指引的提取,它被整个框架所使用。所有API都通过那里指引。因此如果存在任何数据类型转换的bug,只有两种极端的表现:
定位到上面树的单一方法/单一叶子节点
扩展到整棵树
换句话说,任何与数据类型转化相关的bug要么只是表面问题,要不就是全面的灾难性问题。这基本上意味着几乎不可能存在区域性的回归测试,因为任何数据类型转换的回归测试都会使得数百个单元测试和集成测试运行失败。
如何达到高内聚
方法很简单:通过。一个新功能应该从不只是局部地引入。举个例子,我们这里考虑问题: ,因此我们想将JOOQ的RecordMapperProvider功能应用到嵌入式记录。为什么呢?想象我们有一个PERSON表,它包含Oracle对象类型的ADDRESS和STREET属性。是的,你只是标准化了这些数据,但请想象我们正在使用UDT:
CREATE TYPE street_type AS OBJECT (
street VARCHAR2(100),
no VARCHAR2(30)
CREATE TYPE address_type AS OBJECT (
street street_type,
zip VARCHAR2(50),
city VARCHAR2(50)
现在,我们想要将这些数据递归映射到自定义的嵌入式POJO:
public class Street {
public class Address {
public class Person {
public String firstN
public String lastN
这个映射可以通过下面代码完成:
// The configuration object contains the
// Mapping algorithm implementation
Person person = DSL.using(configuration)
.selectFrom(PERSON)
.where(PERSON.ID.eq(1))
// We want to make the mapping algorithm recursive
// to automatically map Address and Street as well
.fetchOneInto(Person.class);
映射一个记录到一个POJO已经实现了,但递归地映射没有实现。当我们实现了递归的方式,我们就会想要现有的代码。上述的在中被引入。它很简单,我们只需具备一个ConvertAll类型的单独实现点就行。
基于高内聚代码实现意味着:
我们只需实现这个新的功能一次;
实现该新功能比写这篇博客花费更少地精力;
嵌入式记录映射和对话将以一种形式为所有用例服务;
我们再增加了一个很棒的新功能同时,仅增加了很少的复杂度(降低了引入bug的风险)。
你不断地重构了吗?
我们无法预见完美的设计,它是慢慢地成长起来的。今天,我们知道了很多关于Java和集合的事情,话费了一些时间简单地介绍了新的Streams API。没有人能够随便就在JDK 1.2中实现如此一个伟大的新API,即使以那时的角度看,它已经相当不错了。
这对于你来说意味着两件事情:
对于你的主要核心代码,要使它达到一个高内聚的状态很重要。如果你有一个电子银行的卖主,你的付款和回扣逻辑应该像上面一个精确,具备一个平衡的稳定性/抽象性比例。
对于你的次要代码(例如用户界面、数据库访问),你应该依靠第三方软件,因为其他人花费了更多的时间使他们的代码具有高层次的质量。(用户界面方面:例如、,数据库访问方面:例如、、,只列举一部分)。
还有,如果你想要一个高内聚架构中的新功能,可能唯一需要完成的事情是。
原文链接:
- 译文链接: [ 转载请保留原文出处、译者和译文链接。]
关于作者:
(新浪微博:)
Hi,请到伯乐在线的小组发帖提问,支持微信登录。链接是: http://group.jobbole....
关于ImportNew
ImportNew 专注于 Java 技术分享。于日 11:11正式上线。是的,这是一个很特别的时刻 :)
ImportNew 由两个 Java 关键字 import 和 new 组成,意指:Java 开发者学习新知识的网站。 import 可认为是学习和吸收, new 则可认为是新知识、新技术圈子和新朋友……
新浪微博:
推荐微信号
反馈建议:@
广告与商务合作QQ:
– 好的话题、有启发的回复、值得信赖的圈子
– 写了文章?看干货?去头条!
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 活跃 & 专业的翻译小组
– 国内外的精选博客文章
– UI,网页,交互和用户体验
– JavaScript, HTML5, CSS
– 专注Android技术分享
– 专注iOS技术分享
– 专注Java技术分享
– 专注Python技术分享
& 2017 ImportNew卓多姿_网易新闻
用微信扫码二维码
分享至好友和朋友圈
本文来源:大洋网-信息时报
责任编辑:王晓易_NE0011
用微信扫码二维码
分享至好友和朋友圈
加载更多新闻
热门产品:   
:        
:         
热门影院:
阅读下一篇
用微信扫描二维码
分享至好友和朋友圈查看: 53|回复: 0
jOOQ:如何通过高内聚消除Bug
主题帖子积分
论坛元老, 积分 465256, 距离下一级还需 9534743 积分
论坛元老, 积分 465256, 距离下一级还需 9534743 积分
请先看下面这段代码,直觉告诉我们类似这样的方法可能会带来问题:
CompilationTask getTask(, B0 F) |' S4 t0 T6 p* `6 q
& & Writer out,2 A( c" M( S1 f3 \% u
& & JavaFileManager fileManager,
& & DiagnosticListener&? super JavaFileObject& ! f7 N1 G% S2 B0 i$ [
& && &&&diagnosticListener,
& & Iterable&String& options,1 [1 f4 d$ w&&J* w& c3 Z
& & Iterable&String& classes,0 t! o6 [$ x/ d( l$ c
& & Iterable&? extends JavaFileObject& ! W9 H&&h2 U& {
& && &&&compilationUnits3 D1 D( c6 {3 O&&M- j
4 C& P' z. u8 P9 ~
&&这是为什么呢?让我们接着深入研究。这是一个来自Java编辑器的Javadoc的一个示例:
Iterable&? extends JavaFileObject& compilationUnits1 =
& & fileManager.getJavaFileObjectsFromFiles(, [' X0 }7 }2 ^4 s3 g
& && &&&Arrays.asList(files1));
* n$ g) ^. Q' ^& d. M
compiler.getTask(null, fileManager, null, 4 r% }' ~8 G; t" T$ j1 M& }
& && && && && &&&null, null, compilationUnits1)
& && &&&.call();- E$ l" {4 I- ~&&X# t3 |
' S. h7 x&&e! j' f4 @
&&这会带来什么问题呢?我们有很多非常类型分散的参数,它们很可能被设为null。这降低了上述方法的复用性,或者按照JArchitect那帮家伙所说的,我们可能处于“痛苦地带”,因为这些方法具备低层次的稳定性和抽象性。% e$ m+ n, I8 D. _' v) t
低稳定性: 在Java编辑器的将来版本,极有可能我们需要另一个指定的参数,例如另一个实现Iterable的类实例。这会增加API的不兼容性。
低抽象性: 即使上述方法是一个接口方法,它也很少有机会被实现多次。因为以一种有用的方式来满足上述约束是很困难的。
&&要规避这类单一方法带来的问题,一种有效途径是使用建造者模式,正如Petri Kainulainen精彩地描述的那样。高内聚解决“痛苦地带”% S; A3 Z) v, |&&Y& Q# T1 ?
&&可能你认为对于编译器API来说这并不是很重要。但“高内聚”的最大价值,例如一个理想的稳定/抽象平衡,是能够使你的代码具有很高地重用性。它的美妙之处不仅在于能使你的开发者花费更少的时间完成特定的任务,还意味着你的代码能够很好地避免错误。举个例子,请从JOOQ的网站下载数据类型转化的逻辑代码。$ Z# V3 l8 \! S& e% B4 W
96a86e37b67dae0b3931.png (273.12 KB, 下载次数: 0)
22:33 上传
8 m$ E3 F6 E) h* S4 T" p' y
&&上面只是一个单一数据类型转换API的调用层级指引的提取,它被整个框架所使用。所有API都通过那里指引。因此如果存在任何数据类型转换的bug,只有两种极端的表现:
定位到上面树的单一方法/单一叶子节点8 b$ K&&R$ z3 ?; D% @3 g( z
扩展到整棵树; k: a# h- g1 e2 L& c( y7 ?
&&换句话说,任何与数据类型转化相关的bug要么只是表面问题,要不就是全面的灾难性问题。这基本上意味着几乎不可能存在区域性的回归测试,因为任何数据类型转换的回归测试都会使得数百个单元测试和集成测试运行失败。如何达到高内聚
&&方法很简单:通过不断地重构。一个新功能应该从不只是局部地引入。举个例子,我们这里考虑问题: [#3023]DefaultRecordMapper没有将嵌入UDT映射为嵌入的POJO,因此我们想将JOOQ的RecordMapperProvider功能应用到嵌入式记录。为什么呢?想象我们有一个PERSON表,它包含Oracle对象类型的ADDRESS和STREET属性。是的,你只是标准化了这些数据,但请想象我们正在使用UDT:
CREATE TYPE street_type AS OBJECT (- K( s&&?3 W; k" \
&&street VARCHAR2(100),$ V. ]0 o4 v+ o8 K; ~$ x
&&no VARCHAR2(30)+ h- ?% t% u7 J* D
);- _& I9 T( S% e6 S
CREATE TYPE address_type AS OBJECT (
&&street street_type,* ?1 B+ }7 N& b* F
&&zip VARCHAR2(50),# z% X&&q% b9 \6 l* D8 M
&&city VARCHAR2(50)
);5 O" A7 \# T1 v3 d6 n' ~
&&现在,我们想要将这些数据递归映射到自定义的嵌入式POJO:
public class Street {+ A* U6 N: \" l2 L* q
& & public S
& & public S
}1 b' s5 X3 F% c" i8 C! c7 x4 Y/ G
: ~+ E' t7 N, E( A+ `&&k
public class Address {: V. d4 W/ P; I9 J8 Z
& & public S
& & public S
& & public S& s2 o# E5 s9 r' w7 f
}6 ?$ |+ r% P* H2 U& I, ^
4 l8 K* a! g) P&&@. Y7 ?
public class Person {+ {, ?# j3 [1 r( n% A
& & public String firstN
& & public String lastN
& & public A2 x&&Y5 U! z1 A' s- |3 S
&&这个映射可以通过下面代码完成:' `0 d4 @: v) T7 |% e1 F, n
// The configuration object contains the
// Mapping algorithm implementation
Person person = DSL.using(configuration)
& && && && && && & .selectFrom(PERSON): D2 _6 f3 e2 h# @&&f6 B& T4 ]) V
& && && && && && & .where(PERSON.ID.eq(1))) t- V0 Q( f* D8 K" Q( B3 n7 c
// We want to make the mapping algorithm recursive
// to automatically map Address and Street as well
& && && && && && & .fetchOneInto(Person.class);
+ l$ c3 d/ X1 g% l&&f3 o2 v
&&映射一个记录到一个POJO已经实现了,但递归地映射没有实现。当我们实现了递归的方式,我们就会想要重构现有的代码。上述的自定义映射SPI在JOOQ3.1中被引入。它很简单,我们只需具备一个ConvertAll类型的单独实现点就行。
&&基于高内聚代码实现意味着:
我们只需实现这个新的功能一次;/ {3 r: x8 x' v: ^5 F5 {
实现该新功能比写这篇博客花费更少地精力;
嵌入式记录映射和对话将以一种形式为所有用例服务;
我们再增加了一个很棒的新功能同时,仅增加了很少的复杂度(降低了引入bug的风险)。你不断地重构了吗?
&&我们无法预见完美的设计,它是慢慢地成长起来的。今天,我们知道了很多关于Java和集合的事情,话费了一些时间简单地介绍了新的Streams API。没有人能够随便就在JDK 1.2中实现如此一个伟大的新API,即使以那时的角度看,它已经相当不错了。
&&这对于你来说意味着两件事情:
对于你的主要核心代码,要使它达到一个高内聚的状态很重要。如果你有一个电子银行的卖主,你的付款和回扣逻辑应该像上面一个精确,具备一个平衡的稳定性/抽象性比例。! D8 E- f- k& m0 p
对于你的次要代码(例如用户界面、数据库访问),你应该依靠第三方软件,因为其他人花费了更多的时间使他们的代码具有高层次的质量。(用户界面方面:例如Vaadin、ZK,数据库访问方面:例如Hibernate、JOOQ、Spring Data,只列举一部分)。
&&还有,如果你想要一个高内聚架构中的新功能,可能唯一需要完成的事情是这四行代码。
游戏咖啡屋-最好的游戏编程源码技术网站!1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关 交流QQ群:
2、本站所有主题由该帖子作者发表,该帖子作者与享有帖子相关版权
4、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
哈...今天心情不错,来游戏咖啡区签到了...
注册账号后积极发帖的会员
积极宣传本站,为本站带来更多的用户访问量
经常在论坛发帖,且发帖量较大
曾经为论坛做出突出贡献目前已离职的版主
Powered by}

我要回帖

更多关于 什么是高内聚低耦合 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信