Создание абстракций из настраиваемых абстракций
Достаточно часто встречаются случаи, когда настраиваемый пакет, который предоставляет подходящую структуру данных, может быть использован для построения реализации другой абстракции.
Предположим, что существует пакет Generic_Lists спецификация которого имеет следующий вид:
generic
type Element is private; package Generic_Lists is type List is private; Underflow : exception; procedure Insert_At_Head(Item : in out List; Value : in Element); procedure Remove_From_Head(Item : in out List; Value : out Element); procedure Insert_At_Tail(Item : in out List; Value : in Element); procedure Remove_From_Tail(Item : in out List; Value : out Element); function Full(Item : List) return Boolean; function Empty(Item : List) return Boolean; -- возвращает пустой инициализированный список function Init return List; private . . . end Generic_Lists; |
Мы можем конкретизировать этот настраиваемый модуль для создания экземпляра нового пакета, который будет сохранять для нас значения типа Integer.
Необходимо обратить внимание на то, что конкретизацию такого настраиваемого модуля следует осуществлять в приватной секции пакета.
Это позволяет избежать нарушения абстракции и предотвращает возможность появления каких-либо дополнительных трудностей разработки.
После этого, настраиваемый модуль может быть использован следующим образом:
with Generic_Lists;
package Stacks is type Stack is private; Underflow : exception; procedure Push(Item : in out Stack; Value : in Integer); procedure Pop(Item : in out Stack; Value : out Integer); function Full(Item : Stack) return Boolean; function Empty(Item : Stack) return Boolean; -- возвращает пустой инициализированный стек function Init return Stack; private -- конкретизация настраиваемого модуля для получения нового пакета package Lists is new Generic_Lists(Integer); type Stack is new Lists.List; -- как и раньше, тип Stack наследует все операции типа List end Stacks; |
Тело пакета Stack будет таким же как и описывалось ранее.
Следует заметить, что в данном случае мы можем навязать приватность без изменения того, что тип выполняет для клиента.