При построении абстракций с применением тэговых типов, необходимо использовать согласованные наименования как для тэговых типов, так и для ассоциируемых с ними пакетов.
Следует заметить, что соглашения по наименованию часто являются источником "религиозных войн".
В следствие этого существует два различных подхода.
Первый подход, за исключением двух специальных случаев, позволяет установить единые соглашения по наименованию описаний, вне зависимости от использования объектно-ориентированных свойств, и при этом он интегрирует в себе использование объектно-ориентированных свойств:
тэговые типы именуются традиционным образом
для имен пакетов экспортирующих какие-либо абстракции, для которых предполагается множество реализаций, используется префикс Abstract_
для имен пакетов предусматривающих функциональные модули, которые могут быть подмешаны ("mixed in") в основную абстракцию используется суффикс _Mixin
Следующий пример, который состоит из двух частей, демонстрирует использование этого варианта соглашений по наименованию.
Для первой части этого примера предположим, что тип Set_Element описывается где-то в другом месте:
| package Abstract_Sets is
type Set is abstract tagged private; -- пустое множество function Empty return Set is abstract; -- построение множества из одного элемента function Unit (Element: Set_Element) return Set is abstract; -- объединение двух множеств function Union (Left, Right: Set) return Set is abstract; -- пересечение двух множеств function Intersection (Left, Right: Set) return Set is abstract; -- удаление элемента из множества procedure Take (From : in out Set; Element : out Set_Element) is abstract; Element_Too_Large : exception; private type Set is abstract tagged null record; end Abstract_Sets; with Abstract_Sets; package Bit_Vector_Sets is -- одна реализация абстракции множества type Bit_Set is new Abstract_Sets.Set with private; . . . private Bit_Set_Size : constant := 64; type Bit_Vector is ... type Bit_Set is new Abstract_Sets.Set with record Data : Bit_Vector; end record; end Bit_Vector_Sets; with Abstract_Sets; package Sparse_Sets is -- альтернативная реализация абстракции множества type Sparse_Set is new Abstract_Sets.Set with private; . . . private . . . end Sparse_Sets; |
|
type Basic_Window is tagged limited private; |
|
generic type Some_Window is abstract new Basic_Window with private; package Label_Mixin is type Window_With_Label is abstract new Some_Window with private; . . . private . . . end Label_Mixin; generic type Some_Window is abstract new Basic_Window with private; package Border_Mixin is type Window_With_Label is abstract new Some_Window with private; . . . private . . . end Border_Mixin; |
|
package Shape is subtype Side_Count is range 0 .. 100; type Instance (Sides: Side_Count) is tagged private; subtype Class is Instance'Class; . . . -- операции Shape.Instance private . . . end Shape; with Shape; use Shape; package Line is type Instance is new Shape.Instance with private; subtype Class is Instance'Class; . . . -- переопределенные или новые операции private . . . end Line; with Shape; use Shape; generic type Origin is new Shape.Instance; package With_Color_Facet is type Instance is new Origin with private; subtype Class is Instance'Class; -- операции для colored shapes private . . . end With_Color_Facet; with Line; use Line; with With_Color_Facet; package Colored_Line is new With_Color_Facet (Line.Instance); |
|
Red_Line : Colored_Line.Instance; procedure Draw (What : Shape.Instance); |