должен ли я назвать все мои абстрактные классы AbstractFoo

является ли хорошей практикой убедиться, что все абстрактные классы имеют имена с префиксом "Abstract"?

9 ответов


вы можете, но я, как правило, не делаю этого, так как это деталь реализации.

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


Я думаю, что это соглашение об именовании используется только потому, что трудно придумать другое хорошее имя. Если у вас уже есть интерфейс под названием "List", как назвать класс "AbstractList"? Это больше об избежании столкновений имен, а затем о деталях реализации.


Это зависит от ваших обозначениях.

вы также можете назвать их FooBase или просто Foo, если у вас еще нет интерфейса Foo.


Если вы рассмотрите, как это происходит в .NET framework, нет. Возьмем, например, класс abstract Stream. Ничто в имени класса не указывает на то, что оно на самом деле абстрактно.


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

  • AbstractServiceTestCase --> абстрактный префикс кажется полезным
  • AbstractAnimal -- > кажется странным и бесполезным

вы должны, конечно, решить для себя, пока же условие выполняется на протяжении всего проекта.


Я бы не назвал абстрактные классы абстрактные по следующей причине:

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

Shape s = .....;
s.drawTo(myGraphicsContext);

использование объекта (например, прямоугольника) в любом месте, где вы можете использовать его обобщение (например, фигуру), является важной частью объектно-ориентированной концепции и известно как Принцип Подстановки Лисков. (Также очевидно: какое предложение или логика будут делать утверждения о формах, но затем не будут применимы к прямоугольникам?)

Если вы назовете обобщение AbstractShape этот принцип нарушается. Прямоугольник-это не абстрактная форма. Во всяком случае, это"бетонная форма"! Прямоугольник не является абстрактным (в смысле "я не знаю, что это за форма. Может быть прямоугольник, может быть что-то еще."). Код с помощью AbstractShape затем читает неправильно:

AbstractShape s = new Rectangle(...);

Я написал в блоге больше мыслей на эту тему здесь.


Я считаю полезным называть классы таким образом. Он отправляет сообщение о том, что они предназначены для подклассов; не инстанцируются; содержат код, общий для подклассов и т. д.

Это не всегда необходимо. Большинство программистов, вероятно, определили бы " форму "как абстрактный класс и" квадрат"," круг " и т. д. как бетон. Но если это не сразу понятно, это полезный намек.

вы также должны руководствоваться локальными соглашениями и стилем программирования направляющие.


Я думаю, что это отчасти зависит от того, как вы будете использовать класс. Если он предназначен только для внутреннего использования в принуждении производных классов соответствовать интерфейсу, то добавление абстрактного перед ним может быть неплохой идеей. Однако, если вы предоставляете фабрику Foo, которая будет предоставлять экземпляры Foo, которые на самом деле SpecializedFoo1 или SpecializedFoo2, то кажется неудобным возвращать экземпляры AbstractFoo.


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

в качестве примера у меня в настоящее время есть hieararchy (не спрашивайте о обосновании имен, но они значимы в контексте и сопоставляются с имя элемента XML.) Я использую Java, но я думаю, что большинство языков будут аналогичны:

public abstract class Marker {...}
public class Template extends Marker {...}
public class Regex extends Marker {...}

теперь я склоняюсь к:

public abstract class Marker {...}
public class TemplateMarker extends Marker {...}
public class RegexMarker extends Marker {...}

, а не

public abstract class AbstractMarker {...}
public class Template extends AbstractMarker {...}
public class Regex extends AbstractMarker {...}

или

public abstract class AbstractMarker {...}
public class TemplateMarker extends AbstractMarker {...}
public class RegexMarker extends AbstractMarker {...}

Я лично это помню Marker является абстрактной функциональной концепцией и что подклассы являются конкретными реализациями.