Вот метод из моего приложения для Android:
public ViewHolderBase buildView(PlayerResult playerResult)
{
View result = inflater.inflate(
R.layout.player_result,
null);
this.helper = new ViewHelper(result);
ViewHolderBase holder = createViewHolder();
TextView playerName = helper.findTextView(R.id.playerName);
holder.setPlayerNameTextView(playerName); // <-- alleged violation
TableLayout tableLayout = helper.findTableLayout(R.id.tlPossibleResults);
populateTableLayout(holder, tableLayout, playerResult);
holder.setView(result); // <-- another one
return holder;
}
Android Studio «считает», что эти две строчки нарушают закон Деметры:
holder.setPlayerNameTextView(playerName);
holder.setView(result);
Я не понимаю. Вот определение:
Закон Деметры для функций требует, чтобы метод m объекта O мог вызывать только методы следующих типов объектов:
- О сам
- параметры m
- Любые объекты, созданные / экземпляры в пределах m
- Объекты прямого компонента O
- Глобальная переменная, доступная для O, в области m
Так? holder
переменная создается / создается в m
.
Честно говоря, его создание делегировано методу createViewHolder
... Должно ли это иметь значение? (побочный вопрос).
Это не для IDE - если вместо этого я создаю экземпляр holder
, предупреждения все равно будут отображаться.
Вопрос:
Android Studio ошибается? Или мое понимание Закона Деметры отсутствует? Если последнее верно, как мне провести рефакторинг этого бита для удовлетворения требований LoD?
createViewHolder
является абстрактным в этом классе (я использую шаблон абстрактного метода). Он переопределяется в производном классе, и его реализация однострочная:return new RangeViewHolder();
. Но, как я уже сказал, даже если я заменюcreateViewHolder
прямым встроенным экземпляром (= new RangeViewHolder()
), предупреждения останутся - person Konrad Morawski   schedule 12.01.2014