Peter Pohl
Peter Pohl

Reputation: 17

Two different objects implement the same Interface in the same way - how to stay DRY

I have the interface:

IColored that guarantees the function getColor.

Now I have two objects:
1. Ferrari
2. RedApple

that both implement this interface/function in the same way.
(But cannot inherit from the same object - no multi-inheritance allowed).

How would you avoid code-duplication?

Upvotes: 0

Views: 192

Answers (3)

mrabat
mrabat

Reputation: 912

I guess what you are looking for is object aggregation.

Check out TAggregatedObject. The idea is to have an object that implements the behavior and as a property it delegates the interface functions to that inner object.

Upvotes: 4

Ken Bourassa
Ken Bourassa

Reputation: 6487

DRY is a principle. As a principle, its purpose is to guide you toward what is believed to be the best practices. But, as it is "just" a principle and not some unbreakable law, one needs to know when to apply it, and when it's preferable not.

My take on the DRY principle is that, it's not because 2 functions are implemented exactly the same that they don't both deserve to exists, for the exact same reasons why you can have multiple constants with the same values (ERROR_SUCCESS = NO_ERROR = SW_HIDE = etc...). Semantics and contexts matter.

If you changed 1 implementation tomorrow, would you need to also change the other? If the answer is no, I don't believe you are really breaking the DRY principle, or at the very least I don't believe you should apply the DRY principle in this case.

But granted, all this is slightly subjective.

Upvotes: 1

HeartWare
HeartWare

Reputation: 8251

If I understand you correctly, you can't - not entirely. But you can get close this way:

TYPE
  IColored = INTERFACE('GUID')
               FUNCTION getColor : TColor;
             END;

  TFerrari = CLASS(IColored)
               FUNCTION getColor: TColor;
             END;

  TRedApple = CLASS(IColored)
               FUNCTION getColor: TColor;
             END;

FUNCTION CommonFunction : TColor;
  BEGIN
    // Lots of code that ends with Result:=clRed
  END;

FUNCTION TFerrari.getColor : TColor;
  BEGIN
    Result:=CommonFunction
  END;

FUNCTION TRedApple.getColor : TColor;
  BEGIN
    Result:=CommonFunction
  END;

ie. delegate the actual code into a function outside your object hierarchy, so that you can call it independently from your INTERFACE implementations.

That's the only way (besides serious low-level hacking) that I know off to implement what you are looking for (minimum code duplication).

Upvotes: 0

Related Questions