What about Class Types?

LandOfConfusion

Too many men
There’s too many people
Making too many problems
And not much love to go round
Can’t you see?
This is a land of confusion.

Genesis, Land of Confusion

…Well, there IMHO there is a problem with the way in which we’re coding. And this problem come from the fact that the classes represent a (rather) static system designed on premise in order to address the needs of a problem which is dynamic in its nature…

There exists different approaches to guess (hence to cover) what will be the concrete needs of the (un)known client (this because most frameworks are written by 3rd parties, isn’t?) somewhere in the future in an (un)known application.

One approach is granularity. Many small classes ready for reuse – usually covering general targets – sometimes aggregated in bigger entities.

Another approach is by using generics in order to decouple the algorithm from the data types.

A third one are by using interfaces. A bunch of them, in order to allow as many uses as possible. And it seems that this is the ‘mode du jour’ today (even if is needed or not).

But with all these approaches (in which one doesn’t exclude the other) there exists a lack of flexibility in adapting them to our code. Of course there are ‘workarounds’ but I don’t want to comment now their quality in public. An example is when we use the is operator:


if aView is TcxGridDBBandedTableView then //an 'If' on each class. How sweet!
  with TcxGridDBBandedTableView(aView) do //Hard Cast. Best Delphi thing.
    FActiveFIeld:=DataController.DataSet.FindField(Controller.FocusedColumn.DataBinding.FilterFieldName);

//...imagine that here we have a gazillion of if's for all Grids, Charts and Card Views...

Another one, quite common, is when we use the RTTI to see that a property exists and if exists we play with it (eg. assign some value to it). This is very ‘nice’ one because we have no support from the compiler (type checking etc.), the code is convoluted and besides that we have the honor (or should I say horror?) to work with pointers and other obscure PropInfo structures (ok, things are much better in Delphi 2010) – and of course is enough slower than a direct assignment.

But what if instead having on premise interfaces, function arguments, generics burned in the 3rd party framework we have a language structure on our side which will say “if the class looks like ‘this’ use it like ‘this’“?

For example, let’s have a class signature. A class type:

TDataAwareHighlighter = class type
public
  procedure Repaint; //we have this just in case - see bellow
published
  property Color: TColor;
  property DataSource: TDataSource;
end;

And to use it…

First write my own custom procedure to ‘alter’ the behavior the 3rd party framework (in this case VCL):


procedure HighlightDataAwareControl(aControl: TDataAwareHighlighter);
//ok, we can put a shorter name here
begin
  case aControl.DataSource.DataSet.State of
    dsInsert: Color:=clClream;
    dsEdit: Color:=clYellow;
  else
    Color:=clWindow;
  end;
end;

As you see, we didn’t use the Repaint method. We included it in the signature though because we wanted to be sure that the component (re)paints itself. (IOW, is a TControl descendant). As an alternative we could have in the class type the InheirtsFrom in order to allow us to use it:

TDataAwareHighlighter = class type
public
  class function InheritsFrom(AClass: TClass): Boolean;
published
  property Color: TColor;
  property DataSource: TDataSource;
end;

And then in our actual code we’ll test if the aControl.InheritsFrom(TControl) returns True.
(of course, this is not mandatory. If you want to have some class with these properties and play with them using a type class, so far so good).

And of course the actual usage will be, in our form:


begin
  HighlightDataAwareControl(TmyDBGrid);
  HighlightDataAwareControl(TmyDBEdit);
  HighlightDataAwareControl(TmyJvDBGrid); //JVCL! Yeah!
end;

Of, course additional tooling like TObject.IsClassTypeOf() will appear after.

Advantages:

  • Greater flexibility in extending different frameworks (hint, hint OPFs, MVCs – these class types can act as mediator helpers between GUI and controllers)
  • Higher code quality –  cleaner, easier to maintain, type checking at compile time
  • Speed – I hope that the compiler will resolve the calls / pointers at the compile time, right?
  • Generics on steroids. – ’nuff said.

Things to discuss:

  • What do you think?
  • The syntax is ok? (Wording etc.)
  • It should have visibility specifiers or just a simple flat list of identifiers?
  • other?

18 thoughts on “What about Class Types?

    • Interfaces have to be explicitly advertised by the implementing class. “Class types” exist completely detached from the implementing class and are more like a stencil that you can hold over any class to see if it fits.
      I would imagine that if this gets implemented it would be little more than a syntactic shortcut for the RTTI-based approach. Then again, I might have totally misunderstood Wing’s description…

      • Yes.

        But also is about the difference between Design-Time and Run Time checking. As you know, the compiler cannot check anything at run-time. If it blows it blows. More safety and, also, runtime execution speed.

        • I can think of a gazillion scenarios where compile-time resolution of these “class types” would simply not be feasible, e.g. when dealing with objects from a TObjectList.

          • Yes, sure – the compile time checking is feasible only when it is feasible in the other (normal) situations. However using RTTI you’re always on your own (things like FindProperty(‘Color’) vs FindProperty(‘Colour’) etc. – also, of course, you must remember to change your RTTI code if your interface changes). But the main point is the ability to express the concrete members in code. Hence is much safer than RTTI. I don’t compare it with the perfection, I compare it with what we have.

    • No, class helpers let you call methods on a class that doesn’t actually implement them. As far as I understood this proposal, it is more about reducing the amount of code you have to write (and thus reducing the chance for mistakes) in order to access properties/methods with a known name/signature on an object without having to query for or even know its class.

    • Nope.

      Do you know TStringList? I bet you know.
      A class helper add functionality:

      TmyStringList = class helper of TStringList; //not sure about syntax
        procedure TrimList;
        procedure CutLines(aMatch: string);
        //etc
      end;
      
  1. “…Well, there IMHO there is a problem with the way in which we’re coding. And this problem come from the fact that the classes represent a (rather) static system designed on premise in order to address the needs of a problem which is dynamic in its nature…”

    Hey Pops, you still awake. 🙂

    The problem is Delphi is suppose to be a high-level software development environment and most developers can’t seem to translate the Delphi components to the patterns of the project’s requirements. I just recently had that happen to me until one day I said “Oh my, now I see it.”

    The ideas you present in this blog post are the “underlying” work that is “supposed” to be used to create components to support higher-level development. In other words you’re discussing the “means to the end”, but you’re viewing it as if it “is the end”.

    Delphi components are to be used in compositions to allow expression of very high-level ideas. Sure Delphi comes with assembly built in, but that’s just one more thing that makes it the best. When developing at the low-level a programmer should have in mind the very thing that you’re questioning.

    • Hyia Son! 🙂

      Nice comment. However no, I don’t see it as ‘the end’ – is a way. Today the life is so complex that nobody can pretend that he has the solution (that’s why I put the quote from ‘The land of confusion’). It is just another language enhancement which (imho) fits very well and add significant value in certain circumstances and it completes the other related language features. I didn’t think at all at class types as a replacement to something.
      Thanks for commenting.

      • I misunderstood your view of things. You apparently see them similiar to myself.

        However, I think I’m going to contend that many (should I say most?) of today’s developer’s are so caught up with “neato’ code” that they aren’t understanding what Delphi is about. I’ve seen projects where people have coded from scratch large libraries of classes to modularize their app. But, if they’d just use multiple TDataModules they would have gotten’ the modularity it took them a month of coding to create.

  2. Hello,

    actually I think this is a great idea. I had a similar idea in the past – I was working on a simple component – an edit control with the “…” button on the right which usually serves as directory/file selector -, but I wanted it to be able to associate with every file dialog – TOpenDialog, TSaveDialog, the Vista dialogs, custom dialogs etc. Unfortunately there is no common base class which provides the operations I need (basically the Execute() method and the Files/FileName properties).

    Anyway, I’m currently working on an interesting approach to tackle this problem. I plan to blog about it once it works properly. (Of course, I should get a blog first 🙂 )

  3. Pingback: Innovation: Array quirks and Generators « Wings of Wind Software

  4. Pingback: The Anti-Case campaign « Wings of Wind Software

  5. Pingback: Community pulse: New ways to enhance Delphi « Wings of Wind Software

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s