Cant Encapsulate Links

One of the alleged advantages of ObjectOrientedProgramming is that it allegedly can hide every detail behind an object interface. However, links between 2 or more objects are not truly encapsulated. A developer has to deal with the link(s) between them in a more or less "raw" form. Maybe one object has an interface to access or manage the partner link, but the developer is still dealing with links in a rather crude pointer-like way.

And, I feel that relational has a more organized, abstract, and consistent approach to managing links in general.

- top

Counterpoint: One is perfectly free to reify links between objects and encapsulate them. This happens often enough that it has a name: ProxyPattern. And if an object O wishes to manage links between two objects, simply reify the link as a ProxyPattern and allow a object O the capability to manipulate that link.

More complex 'link management' can also be reified and performed via systems like MultiCaster. And, in a well-factored OO system, link-management outside of systems explicitly designed for it is usually a CodeSmell.

I don't believe failure to encapsulate links is 'the problem' for OO. Rather, it's the need to do so explicitly, every damn time, and the ease with which "sweeping changes" can become necessary to interject a useful indirection. DesignPatternsAreMissingLanguageFeatures, or at least exhibit MissingFeatureSmell, and OO seems to be all about DesignPatterns.

Sorry, you'll never convince me there's a more natural way to deal with orders and items than the following

 anOrder.add(anItem);  //includes rules throws exceptions when violated;  //totals items and includes all rules/discounts/taxes etc.
 anOrder.items;  //for displaying to screen and such
 aCustomer.add(anOrder);  //same easy place to enforce rules

Both because it's an actual model of the Domain problem, and because it provides a natural place to put business rules for these entities that can't be bypassed or forgotten. Flexible SQL queries are just accessing a global database and provides no way to cleanly encapsulate rules nor model. Relational is great when little business rules are involved, but the more complex the rules become the more important actually modelling it become. I want my relations hard wired into the code, because logically they are hard wired in the Domain. I don't want someone to be able to simple select all from items and sum them without going through the order object, because there may be all kinds of rules involved in summing. I don't want a developer to be able to do flexible querying via sql, because he'll forget to include business rules that are included in the model, guaranteed. To put it simply, the model is the only access to the data I want exposed, period, ever. Once a model is in place, raw access to sql is forbidden, the model is the only data you ever need. As for any objections about other applications needing the data... too bad, each app gets its own database and the apps are integrated at the application level, not at the database level. Each app needs its own model, I don't want shared global data via a database between multiple applications, that's just asking for trouble and bugs imho. A database is just storage for my object model. Don't need flexible querying for reports, because if your app needs a bunch of reports, then your application is missing some functionality (ReportsSmell). Find out why they need those reports and just do that work for them with a screen in the app. An app should need few reports, the app itself should be able to provide you with the data without resorting to butchering the data with a sql query.

If each app has its own database, how do you ensure that the data is kept in sync between applications? A package sent to the wrong address or an order billed to the wrong credit card number is a problem. -- JonathanTang

If they have that much dependency between the data, I wouldn't make them separate apps. Seems they'd be using the same model, so they'd share the same model. Forgive me if I'm a little incoherent; I'm sick and a bit drugged up.

A bit more drugs and aches and you just might start to dig relational. :-)
How does a relational database "encapsulate links" in a way that is less "crude" or "pointer-like" than OO (or procedural) code?

Responses generally found in TablesAndObjectsAreTooDifferent.

I see nothing on that page that provides a response to my question. Why is a value in a tuple less "crude" or "pointer-like" than a key value in a map?

A table is a more powerful building block than a map. Further, inter-map "pointers" usually don't have externally-representable (printable) "keys". And, maps usually don't have referential integrity systems. It is hard to define usable referential integrity with maps because they are too primitive. BTW, I don't think I claimed that relational better "encapsulated links". I am not sure what you are quoting.

Read the page title and this statement again:


I didn't ask about the "power" of "building blocks". I didn't ask about "inter-map 'pointers'" (whatever that is). I asked how a relational database better encapsulates links.

But interesting that you brought up maps versus tables. I am writing an article that essentially claims the OO versus relational debate is all about maps versus relational tables when you strip away language syntax and hardware issues. It is essentially the long version of ObjectsAreDictionaries, and then goes on to complain that dictionaries have no known larger-scale guidance principles, except maybe perhaps the pattern movement, which is similar to trying to classify GoTo patterns IMO.

OK, but how does a relational database better encapsulate links than OO?

Again, I did not claim such to my knowledge. I still don't know what you are quoting. If I did, then the title itself would contradict it. I never claimed that "relational better encapsulates links" up there.

Then what are you claiming? The page is called "Can't Encapsulate Links" and begins by saying that links between objects are not encapsulated. Then it says that the developer has to deal with links in a "crude pointer-like way". Then it says that "relational has a more organized, abstract, and consistent approach to managing links in general." If you aren't saying that relational better encapsulates links, why mention it?

I am basically saying that OO encapsulation cannot encapsulate links between objects. If it makes you feel better, I will remove mention of relational.

Or you could explain why you mention it if you don't believe it better encapsulates links...

The top of this page is written as if all objects must be linked by pointers and nothing else. It ignores the fact that we use pointers when all we need are pointers, but have an infinite number of other ways to link objects. Perhaps if you explained what you mean by "encapsulate" it would shed some light on your position.

What is an example of linking objects without using pointers or inheritance?

So, with those answers out of the way, what do you mean by encapsulate? Did you create the title of this page? If so, why, and what does it mean? -- AdamBerger

Okay, I will try to work on rewording it. Sorry for not being clear enough. -- top
What does that have to do with anything? We still use them to link objects.

Yes, but that is not encapsulation

Why isn't it?

A map is like a micro-table. Is sticking stuff in tables "encapsulation"?

No, but sticking stuff in tables can be part of encapsulation. We use maps to link objects. We encapsulate the maps. Thus the links are encapsulated without using memory address style pointers.
How about we turn this into a question.

Can links be encapsulated?


Can all links be encapsulated?


I think this subject is very important and cuts to the core of where OO still fails at collection management.

"How does relational better encapsulate links than OO?"

In short: Because the relational model defines an *algebra*. OO does not define an algebra, it merely defines behaviour at the per-object level and then tries to generalise and constrain this behaviour via vaguely-defined heuristic approaches such as inheritance. (Vaguely-defined because there still is no unifying mathematical model to describe why we should have single vs multiple inheritance, interface vs implementation inheritance, message sending semantics such as synchronous vs asynchronous, scoping and privacy rules, etc.) An algebra - such as the definition of 'relation' - defines a set of constraints and invariants which go above and beyond the simple association of two items as a map. Because of this queries can be optimised and the definition of data is decoupled from its storage and access strategies.

OO via polymorphism and encapsulation provides a way for individual methods to be decoupled from their implementation; but does not provide a way for *relationships* to be defined declaratively.

The problem with the relational model is that it is not a Turing-complete model of computation while OO is. To extend the relational model to a full declarative computation model, we'd need to take it to something like LogicProgramming such as PrologLanguage. This is an area of research which ground to a halt at the end of the 80s and I think still needs further work on sets and logic to make it pleasant. Prolog 'sort of' works but ain't pretty and doesn't have anything like the widespread platform bindings we expect from modern languages, and there are major warts in the low-level semantics itself - negation by failure, cuts, assert/retract etc. These really need to be fixed to go forward, I think.

-- NateCull?

The root source of problems you describe is that some (by which I mean most) OO languages lack an object configuration layer. In the absence of such a layer, OO provides the primitives (objects) but not the means of composition (see PrimitivesAndMeansOfComposition). DataflowProgramming or boxes-and-ports based composition of objects works far more effectively. With a good ObjectConfigurationLayer, encapsulation of links is trivial. They're encapsulated by the configuration.

Of course, building a good ObjectConfigurationLayer is crippled by SideEffects in constructors. (ConstructorsAreEvil.) And interesting composition with external services is also hurt by 'new'. (NewConsideredHarmful).

And not being TuringComplete shouldn't ever be considered a 'problem'. Them be some backwards values. Being TuringComplete is usually a problem. Relational does benefit from LogicProgramming, though... such as DataLog or variations (see DeclarativeGui for a set of extensions on that path). Still no need for TuringComplete, at least not at that layer!


See also: OoHasLimitedAssociationModeling
