SW-Design: Adapters for Class Hierarchy in Delphi (Generics vs. Downcast)

I would like to get some suggestions on the following problem: Let's say you want to write adapters for VCL controls. All adapters must have the same base class, but differ in special packet control (for example, getting a value from TEdit is different from getting a value from TSpinEdit). So, the first idea is to create a class hierarchy, for example

TAdapter = class end; TEditAdapter = class (TAdapter) end; TSpinEditAdapter = class (TAdapter) end; 

Now I want to enter a field to reference the vcl control. In my special adapters, of course, I want to work with a specific subclass. But the base class should also contain a link (for example, if I want to use an adapter to make the control visible).

Option 1 (Downcast in Access Accessor):

 TAdapter = class protected FCtrl : TControl; end; TEditAdapter = class (TAdapter) public property Control : TEdit read GetControl write Setcontrol; end; {...} function TEditAdapter.GetControl : TEdit; begin Result := FCtrl as TEdit; end; 

So, if I implement a specific method, I work with a property control, if I do something in my base class, I use a protected field.

Option 2 (use a common base class):

 TAdapter = class end; TAdapter <T : TControl> = class (TAdapter) protected FCtrl : T; end; TEditAdapter = class (TAdapter <TEdit>) end; 

Which solution would you prefer? Or is there a third solution, which is even better?

Respectfully,

Christian

+6
source share
2 answers

You cannot use generics to solve this problem, because you will be in one of two situations:

  • The property or method that you want to “adapt” (for example, the Text property) is defined in the ancestor class. In this case, you do not need generics, because you can use one adapter for the ancestor and solve the problem for all descendants.
  • The property or method is introduced by the class that you want to adapt. In this case, you cannot use generics, because to access a property or method you will need a general type restriction of this type. Example. Let's say you need an adapter for the Text TMyClass . Suppose TMyClass is the one that introduces the Text property. To access it, you need to declare a generic type as TGeneric<T:TMyClass> and which is not generic.

In my opinion, it is best to write specific adapters for each class, as in your first option. You might be able to use RTTI tricks to make your first option easier to implement, but I'm not sure if it is worth it.

+4
source

The generics version can avoid code duplication, at least in the TAdapter class. Using type T , it will allow a lot of common code.

On the other hand, due to the VCL hierarchy, most of the properties and methods used will already be in TControl . So I'm not sure if there will be many duplicate codes in a non-generic implementation.

I suspect that the non-generic version will generate less code and RTTI, since the implementation of existing generics tends not to duplicate the source, but increases the size of the exe.

Design-based IMHO will add more abstraction to the implementation, but not a general one, it may be closer to the VCL hierarchy to which it will adapt.

So, for your specific case (VCL mapping), since your attempt is to map non-generic classes, I'd rather investigate a non-generic solution.

For a different (non-VCL-based) adapter architecture, I probably would recommend a clean bottom-up generic implementation.

0
source

Source: https://habr.com/ru/post/890748/


All Articles