Базовый класс определяет много защищенных методов: это хороший дизайн ООП? - PullRequest
3 голосов
/ 22 августа 2010

Я написал базовый класс, который определил много защищенных методов . Эти методы вызываются в его подклассах. Методы определяют основные операции для своих подклассов. Например:

class Base{
   protected void foo(){}
   protected void bar(){}
}

class Sub1 extends Base{//The sub class only needs Base.foo()
   public void po(){
     ...
     foo();
     ...
   }
}

class Sub2 extends Base{//The sub class only needs Base.bar()
   public void ko(){
     ...
     bar();
     ...
   }
}

class Sub3 extends Base{//The sub class needs both Base.bar() and Base.foo()
   public void lo(){
     ...
     bar();
     ...
     foo();
   }
}

Мне просто интересно, хороший ли это ООП дизайн? Читайте источник, мы знаем, Sub1 вообще не нужно Base.bar(), Sub2 вообще не нужно Base.foo(). Я думаю, это излишне. Но я не знаю лучшего решения, кто-нибудь может дать совет? Спасибо!

Ответы [ 4 ]

3 голосов
/ 22 августа 2010

Как правило, вы должны избегать такого рода объектных зависимостей в вашем дизайне. Если функциональность foo () и bar () не изменяется в производных классах, вы можете поместить его во внешний класс и использовать вместо него:

class Base{

}

class Helper1  {
   public void foo(){}
}

class Helper2  {
   public void bar(){}
}

class Sub1 extends Base{
   private Helper1 a = new Helper1();
   private Helper2 b = new Helper2();

   public void po(){
     ...
     a.foo();
     ...
     b.bar();
   }
}

class Sub2 extends Base{
   private Helper2 b = new Helper2();

   public void ko(){
     ...
     b.bar();
     ...
   }
}

Этот пример foo & bar выглядит не очень хорошо. Ваша проблема может быть в неправильном распределении ответственности по объектам или неправильном использовании наследования. Размещение реального кода поможет написать лучшие ответы.

2 голосов
/ 22 августа 2010

Извините, но вы думаете об этом неправильно.Вопрос не в том, «должен ли sub2 наследовать базу, ему не нужен этот метод»

Вопрос должен быть «Является ли sub2 базой», например, является ли лягушка животным?Да, лягушка может наследовать Animal, но лягушка не должна наследовать Mammal.

Если sub2 является базой , вы на правильном пути, если base это просто набор функций, которые могутбыть полезным, значит что-то не так.

1 голос
/ 23 августа 2010

Я вижу, что это Принцип разделения интерфейса выдаёт одно из правил SOLID.

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

1 голос
/ 22 августа 2010

Мои мысли

1- Если вы разрабатываете проект впервые, попробуйте следовать принципу внедрения зависимостей, поскольку я ясно вижу, что вы создаете объекты Helper1, Helper2 в разных подклассах и, возможно, также дублируете код.

2- Я бы предложил создать Helper1 и Helper 2 в качестве свойств в вашем базовом классе, если вам не нужны разные экземпляры helper1 и helper 2 или, возможно, сделать их виртуальными, чтобы вы могли перезаписать их при необходимости.

3 - вы пишете непосредственно в реализацию, и ваш клиентский код напрямую зависит от конкретных классов, использующих интерфейсы, это сделает ваши классы более тестируемыми.

4- И ЗДЕСЬ ЗОЛОТОЕ ПРАВИЛО: Если проблема, с которой вы сталкиваетесь, не настолько сложна, и вы не видите причины для их изменения в ближайшем будущем, чем продолжаете использовать то, что делаете, НЕ ДЕЛАЙТЕ СВОЕ ЖИЗНЬ СЛОЖНАЯ.

ВСЕ хорошее хорошее программирование хорошо, но если вы видите лучшее и более простое решение, чем использование более простого becoz для использования ABSTRACTION, вы платите за сложность.

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

...