шаблон адаптера и зависимость - PullRequest
2 голосов
/ 12 января 2012

У меня мало сомнений по поводу класса адаптера.Я знаю, какова цель класса адаптера.И когда следует использовать.Я сомневаюсь в классовом строительстве.Я проверил некоторые учебники, и все они говорят, что я должен пройти класс «Adaptee» как зависимость от моего «Adapter».например,

Class SampleAdapter implements MyInterface
{
    private AdapteeClass mInstance;
    public SampleAdapter(AdapteeClass instance)
    {
         mInstance=instance;
    }
}

Этот пример скопирован из Википедии.Как видите, AdapteeClass передается моему объекту как зависимость.Вопрос почему?Если я меняю интерфейс объекта, то очевидно, что я собираюсь использовать «новый» интерфейс, и мне не понадобится «старый».Почему мне нужно создать экземпляр «старого» класса вне моего адаптера.Кто-то может сказать, что я должен использовать внедрение зависимостей, чтобы я мог передавать все, что я хочу, но это адаптер - мне нужно изменить интерфейс конкретного класса.Лично я думаю, что код ниже лучше.

Class SampleAdapter implements MyInterface
{
    private AdapteeClass mInstance;
    public SampleAdapter()
    {
         mInstance= new AdapteeClass();
    }
}

Каково ваше мнение?

Ответы [ 3 ]

8 голосов
/ 12 января 2012

Я бы сказал, что вы всегда должны избегать оператора new в классе, когда речь идет о сложных объектах (за исключением случаев, когда класс равен Builder или Factory), чтобы уменьшить связь и сделать ваш код лучше тестируемым.Объекты вне курса, такие как List, Dictionary или объекты-значения, могут быть созданы внутри метода класса (что, вероятно, и является целью метода класса!)

Допустим, например, что ваш AdapteeClass равен Remote Proxy.Если вы хотите использовать модульное тестирование, ваши модульные тесты должны будут использовать реальный прокси-класс, потому что нет никакого способа заменить его в ваших модульных тестах.

Если вы используете первый подход, вы можете легко внедритьподшучивать или подделывать конструктор при запуске модульного теста, чтобы вы могли протестировать все пути кода.

У Google есть руководство по написанию тестируемого кода , которое описывает это более подробно, но некоторые важные моменты::

Предупреждающие знаки для не тестируемого кода

  • новое ключевое слово в конструкторе или при объявлении поля
  • Статические вызовы метода в конструкторе или при объявлении поля
  • Все, что угодно, кроме присваивания полей в конструкторах
  • Объект не полностью инициализирован после завершения конструктора (обратите внимание на методы инициализации)
  • Поток управления (условная или циклическая логика) вconstructor
  • Код выполняет построение графа сложных объектов внутри конструктора, а не использует фабрику или конструктор.
  • Добавление или использование блока инициализации
1 голос
/ 12 января 2012

AdapteeClass может иметь один или несколько нетривиальных конструкторов. В этом случае вам нужно будет продублировать их все в конструкторе SampleAdapter, чтобы обеспечить одинаковую гибкость. Проходить уже построенный объект проще.

0 голосов
/ 12 января 2012

Я думаю, что создание Adaptee внутри адаптера является ограничением. Что если однажды вы захотите адаптировать уже существующий экземпляр?

Если честно, я бы сделал и то и другое, если это вообще возможно.

Class SampleAdapter implements MyInterface
{

    private AdapteeClass mInstance;

    public SampleAdapter()
       : base (new AdapteeClass())
    {
    }

    public SampleAdapter(AdapteeClass instance)
    {
         mInstance=instance;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...