【发布时间】:2021-02-03 14:26:22
【问题描述】:
我对 ADA 语言非常陌生,在我的学习过程中,我看到了很多使用此 ADA 功能的示例。 在我看来,它可能仅对单元测试有用,以便能够测试父包的私有类型和方法,但我认为以这种方式编码没有任何优势,似乎破坏了封装。
在单元测试之外使用它们是一种好习惯吗?
【问题讨论】:
标签: ada encapsulation
我对 ADA 语言非常陌生,在我的学习过程中,我看到了很多使用此 ADA 功能的示例。 在我看来,它可能仅对单元测试有用,以便能够测试父包的私有类型和方法,但我认为以这种方式编码没有任何优势,似乎破坏了封装。
在单元测试之外使用它们是一种好习惯吗?
【问题讨论】:
标签: ada encapsulation
子包可以看作是其父包的扩展。
例如,它可用于提供不直接链接到您的基础包的功能。
典型的例子是Input-Output包。
想象一下下面的包:
package Temperature is
type Kelvin_Temp is private;
type Celsius_Temp is private;
function build (temp : Positive) return Kelvin_Temp;
function build (temp : Integer) return Celsius_Temp;
function to_celsius (temp : in Kelvin_Temp) return Celsius_Temp;
function to_kelvin (temp : in Celsius_Temp) return Kelvin_Temp;
private
type Kelvin_Temp is 0.0 .. 10_000.0;
type Celsius_Temp is -273.0 .. 10_000.0;
end Temperature;
此包提供直接链接到定义的类型的基本操作。
如果你想扩展它以提供文本格式的 I/O 怎么办? 您可以决定将操作放在 Temperature 包中,但如果您想添加其他类型的 I/O,例如数据库 I/O,您将拥有很多不直接链接到您的类型在同一个文件中。
你可以定义
package Temperature.Text_IO is
procedure Put(temp : Celsius_Temp);
procedure Put(temp : Kelvin_Temp);
end Temperature.Text_IO;
和
package Temperature.Database_IO is
procedure insert (Temp : in Celsius_Temp);
procedure insert (Temp : in Kelvin_Temp);
end Temperature.Database_IO;
这正是 IO in the standard library 所做的事情
从封装的角度来看,您的私有类型将在包层次结构之外保持私有,因此您不会破坏封装。
【讨论】:
type Child_T is new Parent_T with private;我见过这样的东西,我不太喜欢
您可以查看 FOSDEM 2018 上的此演示文稿,讨论(私有)包和执行安全:
【讨论】:
存在子包以允许通过扩展进行编程,但在实施时,它们还提供了一种绕过 pkg 应该强制执行的信息隐藏的方法。
虽然设计一个共享一些隐藏信息的 pkg 层次结构可能很方便,但通过扩展编程通常是一个糟糕的想法,它强调易于编写而不是易于阅读,以及编码而不是软件工程。您可能对文章“Breaking the Ada Privacy Act”感兴趣,可在here 获取。
【讨论】: