Reputation: 13409
Say you design an API for some library.
You want to expose some data type (say Person
) in the API (e.g. getAllPeople()
).
Consider the following goals:
Person
(extensible)Person
is likely to include internal state information that is not interesting to the client of the libraryHow would you go about it?
Person
in the library header / API package; have both the client of the library and the implementation depend on it (high coupling; very easy to extend)Person
in the API/header; define PersonModel extends Person
in your library implementation (easy to extend; still some coupling)PersonModel
in the impl.; define Person extends PersonModel
in the API (awful dependencies)PersonModel
in the impl; define Person
in the API and copy the contents when needed (hard to extend; no coupling)Upvotes: 1
Views: 100
Reputation: 15210
In fact, Person is part of the API. It is the responsibility of the library user to choose how to decouple your API in the context of his architecture. You should not impose it.
If the user does not want to use your Person object, he has to encapsulate / copy your object.
Of course you can design Person to be extensible, but in any case it is part of the API. A user of this API is coupled to it. He has to choose when and where he needs to decouple from it and the way to do it. If Person is well designed, he might just use it everywhere. If it is poorly designed or not easy to use/extend, well he will copy the interesting part and redesign it.
When you design an API, the 'Person' kind of object should be an interface e.g. the user should not have access to the implementation. If person is an input to a service of your API, any implementation should work (Liskov principle). If Person is an output parameter, the user should get a reference, with any underlying internal implementation, there will be no coupling with the client code. It is hard when dealing with object construction, but using the *factory design patterns, you can manage even that. If there is no concrete implementation visible to the client code, you have a good API :-)
Upvotes: 2