Struggling with liskov substitution principle (again).

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi.

I'm developing a versioned REST-based API.

So. endpoints like ...

/v1/controller/method/id/param1/param2/param3
/v2/controller/method/id/param1/param2/param3
/v3/controller/method/id/param1/param2/param3

Simple enough.

Internally, the code is structured such that the appropriate versioned
models are injected into the controller.

There is code that is specific to the version and code that is more
general, so, internally, there are namespaces ...

api\common
api\v1
api\v2
api\v3

In many cases (probably 60%), the version specific elements are nothing
more than wrappers for the common layer.

In some cases there is code in a version specific layer that requires a
version specific model...

namespace api\v1;
class ItemController extends api\Common\ItemController {
  public function store(Item $o_Item) {
    \\ Do store for v1.
    \\...

    \\ Let the parent have its say.
    parent::store($o_Item);
  }
}

Now the signature for the parent cannot have api\Common\Item or nothing as
the type hint.

And this is SO frustrating.

Basically, the common layer wants to know that the incoming objects match
(at least) the common layer.

And at the same time the version specific layer wants the incoming objects
to match (at least) the version specific layer.

Can I swap a v1 for a v2 at the version specific layer? No, of course not.

But at the common layer, certainly. As long as the version specific element
is based upon the common element.

What am I supposed to do to write common code AND be able to extend that
common code to version specificness and enforce that the appropriate types
are supplied?

The only way I can see is to create dummy interfaces and use them.

So, my base/common item implements iBaseItem and then no matter how this
gets extended, I can pass it through the layers and still have it enforced
appropriately.


In trying to understand why my code is NOT working I read this ...

stackoverflow.com/questions/2254404/does-the-liskov-substitution-principle-apply-to-subtype-which-inherited-from-abs?rq=1


If I have a method that requires a piece of fruit. And I have a base fruit
object that has all the properties and methods I need to operate upon it at
the general level, why can't I extend that into a apples and oranges and
extend the controller (appleController, orangeController) both of which are
based upon fruitController (that layer wants fruit - be it apples, oranges
or pears or anything that extends fruit).

Frustrated and confused and annoyed at the fatal error when without the
error my code would operate perfectly cleanly with no errors AND it would
stop any developer from trying to send a cactus to the juicer.

Regards,

Richard.

-- 
Richard Quadling

[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux