此更改是否改进了我关于 Demeter 法则的设计?
Does this change improve my design with regards to the Law Of Demeter?
假设我需要为第 3 方编写包装器 class,我无法更改。
class的界面是这样的
class Rewriter {
public List<Mapping> getMappings();
}
包装器看起来像这样
class RewriterSpec {
private final Rewriter rewriter;
public RewriterSpec(Rewriter rewriter) {
this.rewriter = rewriter;
}
public addMapping(Mapping m) {
rewriter.getMappings().add(m);
}
}
所以根据我的理解,RewriterSpec
违反了 Demeter 法则,因为它需要有关重写器的结构知识。
现在的问题是,从设计/测试的角度来看,只传递映射列表会更好吗?
class Rewriter {
public List<Mapping> getMappings();
}
包装器看起来像这样
class RewriterSpec {
private final Rewriter rewriter;
public RewriterSpec(List<Mapping> mappings) {
this.mappings = mappings;
}
public addMapping(Mapping m) {
mappings.add(m);
}
}
只通过引用传递列表可以吗?
维基百科声明如下:
https://en.wikipedia.org/wiki/Law_of_Demeter
More formally, the Law of Demeter for functions requires that a method m of an object O may only invoke the methods of the following kinds of objects:[2]
- O itself
- m's parameters
- Any objects created/instantiated within m
- O's direct component objects
- A global variable, accessible by O, in the scope of m
遵循这些原则,你可以在Rewriter接口中定义一个方法,直接将Mapping对象添加到它的列表中,满足原则(一个全局变量,O可访问,在m的范围内)。
class RewriterSpec {
private final Rewriter rewriter;
public RewriterSpec(Rewriter rewriter) {
this.rewriter = rewriter;
}
public addMapping(Mapping m) {
rewriter.addMapping(m);
}
}
考虑到 Rewriter 无法修改,您可以选择以下选项:
class RewriterSpec {
private final Rewriter rewriter;
private final List<Mapping> mappings;
public RewriterSpec(Rewriter rewriter) {
this.rewriter = rewriter;
this.mappings = rewriter.getMappings();
}
public addMapping(Mapping m) {
mappings.addMapping(m);
}
}
假设我需要为第 3 方编写包装器 class,我无法更改。
class的界面是这样的
class Rewriter {
public List<Mapping> getMappings();
}
包装器看起来像这样
class RewriterSpec {
private final Rewriter rewriter;
public RewriterSpec(Rewriter rewriter) {
this.rewriter = rewriter;
}
public addMapping(Mapping m) {
rewriter.getMappings().add(m);
}
}
所以根据我的理解,RewriterSpec
违反了 Demeter 法则,因为它需要有关重写器的结构知识。
现在的问题是,从设计/测试的角度来看,只传递映射列表会更好吗?
class Rewriter {
public List<Mapping> getMappings();
}
包装器看起来像这样
class RewriterSpec {
private final Rewriter rewriter;
public RewriterSpec(List<Mapping> mappings) {
this.mappings = mappings;
}
public addMapping(Mapping m) {
mappings.add(m);
}
}
只通过引用传递列表可以吗?
维基百科声明如下:
https://en.wikipedia.org/wiki/Law_of_Demeter
More formally, the Law of Demeter for functions requires that a method m of an object O may only invoke the methods of the following kinds of objects:[2]
- O itself
- m's parameters
- Any objects created/instantiated within m
- O's direct component objects
- A global variable, accessible by O, in the scope of m
遵循这些原则,你可以在Rewriter接口中定义一个方法,直接将Mapping对象添加到它的列表中,满足原则(一个全局变量,O可访问,在m的范围内)。
class RewriterSpec {
private final Rewriter rewriter;
public RewriterSpec(Rewriter rewriter) {
this.rewriter = rewriter;
}
public addMapping(Mapping m) {
rewriter.addMapping(m);
}
}
考虑到 Rewriter 无法修改,您可以选择以下选项:
class RewriterSpec {
private final Rewriter rewriter;
private final List<Mapping> mappings;
public RewriterSpec(Rewriter rewriter) {
this.rewriter = rewriter;
this.mappings = rewriter.getMappings();
}
public addMapping(Mapping m) {
mappings.addMapping(m);
}
}