The Bridge Design pattern is one of the design patterns I've had most difficulty wrapping my head around. 🤯 Note: This article assumes some basic k...
For further actions, you may consider blocking this person and/or reporting abuse
I feel that all abstraction, as shown in this example are just contracts of what is to be contained by concrete implementations. Whether or not that abstraction includes other interfaces is up to the designer; however, a more overarching principal is that "favoring composition over inheritance" simply means, add anything you need as a property or field/function (typed or non-typed), in this case, it's a Color property type defined by a Color contract/interface.
In the context of Composition, we don't call this a pattern, as it is simply containment of what is needed e.g. Color and Shape (and the rules to follow). Note that the exact same thing can be achieved merely defining classes, no need for interface or abstract classes. In fact, ultimately there is no need for types either.
Most JavaScript folks will not see the value in this example. They don't see value in interfaces and do not use abstract declarations. Shoot they haven't traditionally even used the class construct. For them it's just close-to-the-metal scripting/get-it-done, simple key value pair programming all contained in a JSON Object. In some ways they are right, it's much easier to think that way than in "abstract" OOP terms.
Alas the style we choose for the right job is always paramount, need types? Implement them! Don't need types? Leave them out. Need abstractions? Put them in etc. etc.
Thanks for the post.
Thank you for the constructive feedback!
I feel like I found this pattern difficult to wrap my head around was because it is very close to the Strategy Pattern, and it really is just down to fulfilling contracts that the developer defines themselves.
I studied patterns for years. In the end I abandoned them. Reason was that all OOP when refactored as far as possible turns into single responsibility functions anyway. The javascript folks love functional programming, so this aligns there too.
Instead of patterns I now create lots and lots of small SRP functions that are compose-able. Also, I no longer use classical inheritance. I find doing this aligns nicely with web based programming. I still use Typescript because I love type safety and I use Classes for the same reason. Why find run-time errors when you can find them via intellisense before the compile?
Maybe I'm missing something, but it seems that the distinction between an abstraction and implementation only becomes relevant when the language has a distinction between the two?
In some senses, Javascript developers work only in abstractions; if I have two different API services in Javascript, and they both implement a
.get
, how would we distinguish, in Javascript, between writing a function which relies on an implementation of a thing-which-needs-a-get-function, and an abstraction of a thing-which-needs-a-get-function? With an example:I can call
callGet
using eitherapiA
orapiB
. Unless I'm missing something here, I don't really see, in fact, how non-OO languages have any way at all of caring about the distinction between abstraction/implementation; I'd be very glad to be pointed in the correct direction though!In traditional Javascript there is no guarantee that the service you show, can know ahead of time if both objects (shown above) have implemented the getter pattern. It would only become known at runtime.
This is my #1 reason for advocating class design with types, and why I prefer Typescript over Javascript.
If we use typed classes, then the question is answered before compile time via intellisense. If either of the objects passed in did not implement getters the red squiggly line would show via intellisense while coding.
Therfore questions like 'how do we know' are answered by Intellisense. It's perhaps the greatest tool for programmers ever; and it works best on Typed objects.
Indeed, and I'm also a big fan of Typescript; I think the question of catching at runtime vs compile time is a separate question, though.
My main point was that it isn't really possible to assert that Javascript developers don't use abstract declarations. That's all they use.
Sir thank you so much for this great article : -
Here is how I use services using Composition over Inheritance like so
a. under crud.js I have -
b. Here is my API file like so : -
What I find after reading your post, your approach is more Object Oriented based suited for TypeScript(which is great) and Type-Safe. I will use your approach next time.
Please share some thoughts, Thanks
From ES6 onwards you have access to the
class
keyword, if you don't want to switch to Typescript just yet :)