我应该使用对象还是函数指针?

时间:2014-08-28 11:40:24

标签: oop ada

我有一系列需要以3种不同的方式实现并隔离到3个不同包的函数,我想减少父包规范中的函数原型重复。我想到了接口和抽象函数,但这迫使我仍然有重复。我看到这样做的唯一方法是记录函数指针,但是没有一种OOP方法可以绕过它吗?

这是我想要避免的一个例子

package Parent_P is
  type Something is interface;
  function A(S : Something) return Boolean is abstract;
  function B(S : Something) return Boolean is abstract;
  function C(S : Something) return Boolean is abstract;
  package Child_1 is
    type Something_1 is new Something
    overriding function A(S : Something_1) return Boolean;
    overriding function B(S : Something_1) return Boolean;
    overriding function C(S : Something_1) return Boolean;
  end Child_1;
  package Child_2 is
    type Something_2 is new Something
    overriding function A(S : Something_2) return Boolean;
    overriding function B(S : Something_2) return Boolean;
    overriding function C(S : Something_2) return Boolean;
  end Child_2;
  package Child_3 is
    type Something_3 is new Something
    overriding function A(S : Something_3) return Boolean;
    overriding function B(S : Something_3) return Boolean;
    overriding function C(S : Something_3) return Boolean;
  end Child_3;

理想情况下,我可以拥有这样的东西,但是有了OOP

package Parent_P is
  type Access_A is access function return Boolean;
  type Access_B is access function return Boolean;
  type Access_C is access function return Boolean;
  type Something is record
    A : Access_A := null;
    B : Access_B := null;
    C : Access_C := null;
  end record;
  package Child_1 is
    procedure Set_Pointers(S : in out Something);
  end Child_1;
  package Child_2 is
    procedure Set_Pointers(S : in out Something);
  end Child_2;
  package Child_3 is
    procedure Set_Pointers(S : in out Something);
  end Child_3;

1 个答案:

答案 0 :(得分:2)

如果您使用第二个示例中的访问功能组件的记录,我没有特别的理由可以看到声明标记类型。

辩论应该在你的第一个和第二个例子之间进行。第一个例子,你说你想避免,实际上就是这样做的“OOP方式”(你可以将Something声明为abstract tagged null record而不是interface;它不会没有那么大的差别。这样做的第一个方法的一个优点是它将属于一起的某些子程序联系在一起。实际上,在诸如Ada,C ++或Java之类的静态语言中,OOP中的对象包含子程序指针的常量记录;这就是调度/多态性的工作原理。 (此记录在C ++中称为vtable;它在Ada中没有正式名称,但有时会使用术语“调度表”。)当您声明新类型或类时,多态子程序要么是重写或继承,编译器创建指向重写或继承代码的子程序指针的记录。由于这是常量,程序的其余部分不能修改其中一个“记录”组件以指向不同的子程序,但这通常是一件好事,因为如果记录指向子程序没有,它会导致问题一起工作。这是定义标记类型并以此方式执行的第二个优点:一起工作的子程序还可以操作属于对象(或标记记录)的状态,通过使用记录组件将信息从一个传递到另一个来协同工作

但是,如果函数不会操纵任何状态,并且它们彼此独立(因此 有意义创建一个带有一个函数指针的记录来自一个地方和另一个地方的另一个函数指针),那么包含函数指针的记录可能是一个更好的抽象。

所以我认为无论是以“OOP方式”做事还是定义访问功能的记录取决于你的情况。如果永远不会有任何状态,并且这些功能将彼此独立,那么记录可能就足够了。否则,请使用第一个示例中的标记类型。无论如何,我不确定你要避免的第一个例子是什么。在任何一种情况下,您都需要定义9(3x3)个不同的子程序。如果使用标记类型,则还必须具有所有这些子程序的声明。但是,如果避免这种情况的动机是避免编写这些声明,那真的不是一个充分的理由。