这个改变是否改善了我对Demeter法的设计?

时间:2017-01-18 09:04:19

标签: java law-of-demeter

让我们说我需要为第三方课程写一个Wrapper,我无法改变。

该类的界面如下所示

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违反了得墨忒耳法,因为它需要有关重写者的结构知识。

现在,问题是,从设计/测试的角度来看,传递映射列表会更好吗?

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);
    }
}

可以通过引用传递List吗?

1 个答案:

答案 0 :(得分:0)

维基百科声明如下:

with carcode

  

更正式地说,函数的Demeter法则要求对象O的方法m只能调用以下类型对象的方法:[2]

     
      
  • O本身
  •   
  • m的参数
  •   
  • 在m
  • 中创建/实例化的任何对象   
  • O的直接组件对象
  •   
  • 一个全局变量,可由O访问,范围为m
  •   

通过遵循这些原则,您可以在Rewriter接口中定义一个方法,直接将Mapping对象添加到其列表中以满足原则(一个全局变量,可由O访问,在m的范围内)。

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);
    }
}

考虑到无法修改重写器,您可以选择以下内容:

args = array(
    'post_type'  => 'product',  
    'orderby'    => 'meta_value_num',
    'order'      => 'DESC',
    'meta_query' => array(
        array(
            'key'     => 'flower-type',
            'value'   => 'fresh-roses',
            'compare' => '=',
        ),
    ),
);