Ada: packaging concepts [closed]

醉酒当歌 提交于 2019-12-31 03:39:10

问题


This is a follow up of my earlier post here:

Ada: Understanding private types and understanding packaging

An implementation for the Rectangular type was made using one implementation i.e. Rectangular_Method_1 and a specification file and a body file were required for this implementation.

If we want to have another implementation Rectangular_Method_2 available to the user then the main file rectangular_Form.ads can be changed to

-- with Rectangular_Method_1;
-- package Rectangular_Form renames Rectangular_Method_1;
with Rectangular_Method_2;
package Rectangular_Form renames Rectangular_Method_2;

Questions

  1. Is this the right way in software engineering to allow for another implementation in that the test file test_rectangular_form.adb remains the same for a different implementation?

  2. If we create a second implementation Rectangular_Method_2, Is there a need to create a separate specification file in addition to the compulsory new body for this new implementation? There is the need however to provide the same procedures/functions for Vector_Basis_r, Set_Horz, Get_Horz etc in the new implementation so that we can call them in test_rectangular_form.adb.

Thanks...


回答1:


If you use GNAT, you can use GPR files for the project. In there you can change the filename for specific packages, for example:

for Specification (Rectangular_Form) use "Rectangular_Method_1.ads";
for Implementation (Rectangular_Form) use "Rectangular_Method_1.adb";

you can even set this depending on an environment variable.

If your spec files all should look the same, you can use a Rectangular_Form.ads and only use the Implementation line from above.

An example GPR file could look like this:

project Example is

   type Methods is ("normal", "something_else");
   Method : Methods := external ("METHOD", "normal");

   package Naming is
      case Method is
         when "normal" =>
            for Implementation ("Example") use "example_normal.adb";
         when "something_else" =>
            for Implementation ("Example") use "example_something.adb";
      end case;
   end Naming;

end Example;

Then, you can use gnatmake -P example.gpr to compile it depending on your METHOD variable, or using a -XMETHOD=... parameter for gnatmake or just use the provided default value.

The example_*.adb should all contain the body of the package Example, not Example_Normal, etc..




回答2:


Another way to do this would be to use tagged types.

package Rectangular is
   type Instance is abstract tagged private;

   procedure Vector_Basis_r (A : in Long_Float; D : out Instance);
   procedure Set_Horz (R : in out Instance; H : Long_Float);
   function Get_Horz (R : Instance) return Long_Float;
private
   type instance is tagged null record;
end Rectangular;

with Rectangular;
package Rectangular_Method_1 is
    type Instance is new Rectangular.Instance with private;
    ...
private
    type Instance is new Rectangular.Instance with 
    record
        Horz, Vert: Long_Float;
    end record;
end Rectangular_Method_1;

(similar implementation for Rectangular_Method_2).

Then I believe you can write your code that uses it this way:

with Rectangular_Method_1;
with Rectangular_Method_2;
...
--  My_Rectangle : Rectangular_Method_1.Instance;
My_Rectangle : Rectangular_Method_2.Instance;

My_Rectangle.Set_Horiz(Whatever_Value);
...

In other words, all you'd have to change when switching between the two is the type names. Your client could even get rid of those changes by using a single subtype at the top.

subtype Rectangle_Instance is Rectangular_Method_2.Instance;

This would also give you the ability to move common code/fields up into the base class (package), which I think is sort of what you were after.



来源:https://stackoverflow.com/questions/10408459/ada-packaging-concepts

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!