2010-06-09 5 views
2

Я просто хочу ввести некоторые шаблоны дизайна в свой Java-код, но я не знаю, какой стиль использовать - предпочтительным является наследование или интерфейс? И почему?Выберите наследование или интерфейс для реализации шаблона проектирования в Java?

+0

Что такое «неотъемлемый» ??? –

+0

Наследование я принимаю – Chii

+0

@ Питер Торок: наследование, извините за это :-) –

ответ

9

Дизайн шаблонов - это не просто случайное введение в приложение. Они - разновидности дизайна, а не сыр пармезан, который вы побрызгаете своим кодом после того, как он уже испечен.

Это говорит о том, что Josh Bloch's seminal Эффективная Java настоятельно рекомендует разработчикам использовать интерфейсы для совместного поведения, а не использовать наследование. Это соответствует моему собственному опыту.

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

5

Образцы дизайна не «вводятся» в ваш код - сначала вам нужно заметить, что ваша проблема аналогична проблемам, решаемым многими другими, и что они перегоняли шаблон, который решает проблему. Наиболее известными являются here

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

2

Эти две функции не являются взаимоисключающими. Интерфейс и инструменты определяют типы и совместимость с типом. Наследование позволяет эффективно использовать код. В классическом дизайне иерархия типов выражается с использованием интерфейсов, а повторное использование кода достигается с использованием наследования.

+0

Вы имеете в виду «Две функции не являются взаимоисключающими друг от друга»? –

+0

Да (еще 11) –

1

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

О интерфейсов и наследования:

Интерфейсы которые используются, когда вам нужно во время выполнения полиморфизм. Таким образом, вы определяете интерфейс и можете иметь несколько различных его реализаций. В клиентском коде вы можете просто объявить ссылку как тип интерфейса. Теперь вы не беспокоитесь о фактическом типе объекта, переданного клиенту во время выполнения. Вам просто нужно вызвать метод по ссылке.

interface Car { 
     void startEngine(); 

     void stopEngine(); 
    } 

    class Maruti implements Car { 

     public void startEngine() { 
      System.out.println("Maruti engine started"); 
     } 

     @Override 
     public void stopEngine() { 
      System.out.println("Maruti engine stopped"); 
     } 
    } 

    class Porsche implements Car { 

     @Override 
     public void startEngine() { 
      System.out.println("Porsche engine started"); 
     } 

     @Override 
     public void stopEngine() { 
      System.out.println("Porsche engine stopped"); 
     } 
    } 

В приведенном выше примере в качестве клиента вы просто объявляете ссылку как тип автомобиля. И во время выполнения вы можете иметь объект Maruti или объект Porsche, вы не заботитесь о нем. Что вам нужно, так это просто вызвать startEngine или stopEngine.

Наследование обычно используется для повторного использования и расширяемости кода. Таким образом, у вас есть общий код в двух классах и оба, похоже, относятся к общему типу, тогда вы можете создать родительский класс (несколько раз абстрактно) и переместить общий код в родительский класс. Таким образом, вы можете избавиться от дублирующего кода. Другой вариант использования - расширяемость, иногда у вас нет контроля над исходным кодом класса, и вы хотите добавить/изменить какое-то поведение. Вы можете использовать наследование и переопределить определенные методы.

Существует еще одна вещь, называемая «композиция», которая является предпочтительным способом над наследованием для расширяемости.