2017-01-18 4 views
1

Предположим, мне нужно написать 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 нарушает Закон Деметры, поскольку она требует структурных знаний о Rewriter ,

Теперь вопрос: было бы лучше с точки зрения дизайна и тестирования просто перейти в список сопоставлений?

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

Это нормально, чтобы просто передать список по ссылке?

ответ

0

Википедия гласит следующее:

https://en.wikipedia.org/wiki/Law_of_Demeter

Более формально, Закон Деметры для функций требует, чтобы метод м объекта O может вызывать только методы следующих видов объектов: [2]

  • сам по себе O
  • параметры M'S
  • Любые объекты, созданные/экземпляр в м
  • компонент прямого Выходов объекты
  • глобальную переменную, доступную на О, в рамках м

Следуя этим принципам, можно определить метод в интерфейс 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); 
    } 
} 
+0

Привет @ luc14n0 в целом это хороший совет, но, к сожалению, я не могу изменить интерфейс ReWriter. – helpermethod

+0

Учтите, что класс Rewriter не модифицируется. – jakubbialkowski

+0

Возможно, вы можете расширить конструктор RewriterSpec, чтобы также присвоить ссылку на карту в Rewriter. –