Подтвердить что ты не робот

Разница между шаблоном адаптера объекта и шаблоном адаптера класса

Как решить, когда использовать адаптер объекта и когда использовать адаптер класса?

Проблема: Чтобы создать веб-сайт для социальных сетей и предоставить им импортные функции из facebook, google plus и orkut. Я не могу решить, использовать адаптер объекта или адаптер класса.

Я рассмотрел "Шаблон адаптера: адаптер класса против адаптера объекта" , но не смог понять суть разницы.

4b9b3361

Ответ 1

Основное различие:

  • Адаптер класса использует наследование и может переносить только класс . Он не может обернуть интерфейс, поскольку по определению он должен выводиться из некоторого базового класса.

  • Адаптер объектов использует состав и может переносить классы или интерфейсы или и то, и другое. Он может это сделать, поскольку он содержит как закрытый, инкапсулированный член, класс или интерфейс экземпляр объекта, который он обертывает.

Разница тонкая. Обычно более поздний подход (предпочтительный состав над наследованием) является предпочтительным, как поясняется в ссылке, которую я приведу здесь:

Объектно-ориентированное программирование (ООП) имеет слишком хорошо известных кандидатов на повторное использование функциональности: Наследование (использование белого ящика) и композиция (повторное использование черного ящика). Если вы попытаетесь повторно использовать код путем наследования из класса вы сделаете подкласс зависимым от родительского класса. Это делает система во многих случаях излишне сложна, менее подвержена проверке и делает обмен функциональностью во время выполнения излишне тяжело. Как [разработчик чистого кода] вы должны следовать Принципу замены Лискова (LSP), когда вы необходимо решить, подходит ли наследование.

Композиция означает, что один класс использует другой. Вы будете дальше содействовать развязыванию, четко определяя интерфейсы. Это также дают вам преимущество в том, что реализации можно легко заменить. Так перед тем, как приступить к применению Лкликовской замены, подумайте о концепции "Положительная композиция над наследством" и спросите почему бы вам не предпочесть композицию сразу.

"Поскольку наследование предоставляет подкласс для подробностей его родительского реализации, он часто говорил, что" наследование прерывается инкапсуляция ". (" Банда четырех ": 1995: 19)

Ответ 2

Адаптер объекта:

$Adapter = new MyEngine(new MyAdapter($options));
$Adapter->write('something');

Адаптер класса

MyAdapter extends BaseAdapter implements AdapterInterface { ... }
$Adapter = new MyAdapter($options);
$Adapter->write('something');

Ответ 3

В простых словах, Адаптер класса использует подклассы и Адаптер объектов использует делегирование с использованием композиции.

Пример:

class MyExistingServiceClass {
    public void show() {
        System.out.println("Inside Service method show()");        
    }
}

interface ClientInterface {
    void display();
}

class MyNewClassAdapter extends MyExistingServiceClass implements ClientInterface {
    void display() {
        show();
    }
}

Выше приведен пример адаптера класса. Мы адаптировали MyExistingServiceClass к ClientInterface, вызвав существующий метод show() изнутри реализации display().

Чтобы преобразовать это в объектный адаптер, код будет выглядеть следующим образом:

class MyNewObjectAdapter implements ClientInterface {

    MyExistingServiceClass existingClassObject;

    void display() {
        existingClassObject.show();
    }
} 

Теперь, когда для использования адаптера объекта вместо класса Adatper,

  • Если нет подкласса класса, который будет адаптирован в соответствии с клиентским интерфейсом. Например, когда MyExistingServiceClass объявлен окончательным.

  • Когда клиент ожидает контракт, который не является интуицией, а реализацией абстрактного класса. В этом случае у нас нет другого пути, кроме как подклассировать ожидаемый класс клиента и, поскольку мы не можем подклассифицировать более одного класса, нет другого способа, кроме использования класса, который должен быть адаптирован как композиция.

    abstract class AbstractClientClass {
        abstract void display();
    }
    
    class MyNewObjectAdapter extends AbstractClientClass { 
    
        MyExistingServiceClass existingClassObject;
    
        void display() {
            existingClassObject.show();
        }
    }
    
  • Если вам нужно адаптировать несколько объектов. Такой случай - это когда вы не работаете непосредственно с объектом, подлежащим адаптации. Хорошим примером здесь может служить класс JTable в javax.swing. Этот класс создает компонент таблицы графического интерфейса пользователя (GUI), заполненный информацией, которую ваш адаптер передает на него. Чтобы отображать данные из вашего домена, JTable предоставляет конструкторы, которые принимают экземпляр TableModel определенный в javax.swing.table. JDK предоставляет существующую абстрактную реализацию TableModel с AbstractTableModel.

    class MyTableModel extends AbstractTableModel {
    
    MyDomainObject[] existingDomainObjects[];
    
    public int getColumnCount() {
        return 4;
    }
    
    public int getRowCount() {
        return existingDomainObjects.length();
    }
    
    public MyDomainObject getValueAt(int i) {
        return existingDomainObjects[i];
    }
    }
    

Здесь мы адаптировали MyDomainObject для использования с AbstractTableModel.

Ответ 4

Адаптер класса использует множественное наследование для адаптации одного интерфейса к другому: (в зависимости от вашего языка программирования: Java и С# не поддерживают множественное наследование)

enter image description here

Адаптер объекта зависит от состава объекта:

enter image description here

Источник изображений: шаблон дизайна (элементы многоразового объектно-ориентированного программного обеспечения)