Coupling in Standalone Modules – Good or Bad?

frameworksinheritanceprogramming practices

Encapsulation is a mechanism of wrapping the data (variables) and code acting on the data (methods) together as a single unit. Client code is expected to inherit from system-supplied classes and then substituted for the system's classes in its algorithms.

Inheritance is when an object or class is based on another object or class, using the same implementation or specifying a new implementation to maintain the same behavior.

I like inheritance. For numerous reasons. That's the way of not writing everything again. I like that. Encapsulation… well, that's the thing that I don't like so much because of logic around it. To encapsulate something I need to know much bigger scheme of it all. But, eventually it's the same "scheme" as if I'm looking for inheritance.

But what do you do to avoid coupling when there's a bunch of inheritance? Is coupling a good thing or bad thing when I'm developing standalone modules on framework? Is it better to go with inheritance or is it better to go with encapsulation?

Best Answer

Is coupling a good thing or bad thing when I'm developing standalone modules on framework?

Coupling is an unavoidable thing if you want things to work together. What you work towards is loose or low coupling so that you can make changes in one place without being forced to make them in other places as well to keep things working.

Is it better to go with inheritance or is it better to go with encapsulation?

This is a false choice. Choosing between inheritance and encapsulation is like choosing between cats and democrats. Sure there is an important choice here but it's not between these two things.

The alternative to inheritance is composition with delegation. Both are ways of doing polymorphism.

The alternative to encapsulation is public state. Both let you hold information.

Encapsulation is a mechanism of wrapping the data (variables) and code acting on the data (methods) together as a single unit. Client code is expected to inherit from system-supplied classes and then substituted for the system's classes in its algorithms.

No.

A mechanism of wrapping the data (variables) and code acting on the data (methods) together as a single unit is called an object.

Encapsulation is information hiding, even if I only do it by naming variables with underscores to signal that you should keep your grubby mitts off of them. It's me separating what parts of my object are for public consumption and what aren't.

By the way, encapsulation has nothing to do with remembering to use getters and setters. That's a lie that's been told many times but it still isn't true. Getters and setters started as debugging code, a manual way to do Aspect-Oriented Programming before we knew what that was. Me getting a chance to fiddle with my private stuff before you read my private stuff isn't encapsulating it. It just gives me a chance to know what's causing bugs with it because I can set a breakpoint and look at the call stack.

Inheritance is when an object or class is based on another object or class, using the same implementation or specifying a new implementation to maintain the same behavior.

No.

More correctly, Inheritance is when an object or class is based on another object or class, using the same implementation or specifying a new implementation to maintain the same interface or type.

Inheritance is a way of implementing polymorphism. It's not the only way. Composition and delegation can do this as well and more flexibly. It just requires that you type out more code.

I like inheritance. For numerous reasons. That's the way of not writing everything again.

I hate inheritance. For numerous reasons. Mostly over use of the template method pattern and the sickening yo yo problem. This emerges because lazy SOB's create a system with a few generic classes that barely do things you need them to do and design the system to only accept them. Rather than design a proper API for people to use they say, "Oh just inherit from the Foo class". Doing that, especially when you're not the only one or the only layer, without getting hideously coupled to Foo, is a nightmare.

I greatly prefer composition and delegation. Sure it's more typing of code but it means I control what I care about.

...the way of not writing everything again.

Don't repeat yourself is an excelent principle. Inheritance has no monopoly on following it. The strategy pattern discorages solving this with hierarchys in favor of optional implementations. And it isn't the only way to delegate. I can go as far as doing composition and delegation with Single Method Interfaces so I'm never repeating code. Here's an example.

To encapsulate something I need to know much bigger scheme of it all.

Encapsulation doesn't mean you need to know the bigger scheme. Encapsulation means never you mind what my private stuff is doing. The best encapsulated objects don't offer any getters at all. They ask you to follow Tell, Don't Ask. They are not designed to give up their secrets when asked. They sit around waiting for you to tell them to do something, then they go do it. What they do may depend on that private stuff but you don't need to worry about that, that's their job.

When you work this way you can tell an animal to speak without testing if it's a duck. You say speak and it quacks. Unless it's a dog. But since you just need it to speak you don't care. You don't even know it's a duck. You don't want to know. Whatever you are, just go speak already.

Build your classes and API's with that kind of thinking and avoiding coupling is much easier. You can't be coupled to what you don't know about. Be very careful of what you let your classes know about.

But what do you do to avoid coupling when there's a bunch of inheritance?

If you must use inheritance at least design a child class that puts a stop to it. The real cause of the yo-yo problem is when you inherit, add what you need, and let the next poor guy inherit from you. If you can't get rid of the inheritance at least design the child class so that anyone coming after can pass in (inject) what they need without being weighed down by everything that went before. Doing that injection in a loosely coupled way is what dependency injection is all about.

Frameworks have come a long way. They are very powerful and useful. But all too often they want to take over your language space to the point that you're not a Javascript programmer anymore your a Javascript/Angular.js programmer. If you have to mention a framework when you advertise for a programming job, don't tell me you're not coupled to it.

You can fight this by treating your framework like a library, telling it to do what you need in controlled ways, not letting it visibly spread into all of your code. But doing that is fighting against the will of the framework author. They want you coupled. It's in their business plan. Don't expect doing that to be easy.

One of the best presentations I've seen to demonstrate that you can use a framework without it taking over you're life is this. It's about ruby and rails but hopefully you can get some use out of it.

Related Topic