czwartek, 23 kwietnia 2015

Demystifying decoupling and cohesion in Software Architecture


Decoupling and cohesion are phrases that are thrown around in software very often. You kind of know what they mean, but do you really? 

Decoupling

Coupling in software architecture usually applies to modules in OOP. It measures how dependent are modules from each other - how strong is the connection between them. Why should that bother us? The main problem is that if modules are highly coupled, that usually means that when you change something somewhere, you create a ripple effect and you have to change other modules as well.

 How do we measure it? There's no one rule, but there are some guidelines.
  • If a change in class A forces you to change other modules, it's a sign that these modules may be highly coupled
  • If you use some custom classes, instead of primitives to pass data around modules, you increase the strength of the relationship
  • If module B has a pointer to object A, and vice versa
In order to decouple modules:
  • Think of your modules as independent, as if the rest of the program didn't exist
  • Prefer abstractions - they tend to help you think of your modules as independent
  • Design patterns of course
  • Cohesive code is often decoupled
  • Prefer composition, over inheritance.
  • Use layers of architecture

                                                                                                                 source

Interfaces != Decoupling



One very common misconception is that Dependency Injection magically decouples your code. If you do this right, by abstracting your modules, it will help you to layout your code in  modules to be independent, hence decoupled. If you just create an interface for every dependency and inject it, it doesn't decouple the code, it just gives you an illusion of doing so, because interfaces aren't abstractions.

You can have decoupled code, without using one interface.

Cohesion

Cohesion is strongly connected to decoupling but there is a subtle difference. 

"In computer programming, cohesion refers to the degree to which the elements of a module belong together."

If you have low cohesive code, it's almost definitely strongly coupled. SOLID's Single Responsiblity Rule commands to created modules, with single responsibility, hence cohesive.

Your module is cohesive, if:
  • The functionalites of the class have a lot in common and the class' responsibility can be described in a simple sentence without "and", "or".
  • Doesn't use unrelated dependencies (network module using database module)

                                                                                                                           source

sobota, 18 kwietnia 2015

Solving the NSNumber mystery


Ignorance is bliss. I used NSNumber and didn't really care how it really works. One day when I had to find out what's inside NSNumber (bool, float or integer) that bubble burst.

It turned out that you can't really find out what NSNumber is holding with simply calling a method on the object, which is kind of illogical, given that you explicitly say what you put inside NSNumber and Obj-C is a dynamic language, right? I don't give up that easily, though. I digged more. What I discovered surprised me greatly.

NSNumber is a class cluster which is a special design pattern used to box private classes in one public class.

That means that we don't have to deal with a dozen of classes, as they are hidden behind the public class.






That also means that NSNumber points to a different Core Foundation class in reality, depending on what you decide it to be.

We can use that knowledge to find out what NSNumber instance is really holding:




So, NSNumber can point to either CFBoolean, or CFNumber. CFNumber can hold any type of number primitive. We cast to (void*) or (CFNumberRef) to keep the compiler happy.

Unfortunately, even though Foundation lets us forget about Core Foundation, sometimes we have to go back and use the lower layer.

Every Objective-C programmer should have some knowledge about underlying Core Foundation framework, as it gives you more control, it can allow you to create some neat hacks (like the one above), and some libraries are Core Foundation exclusive (Keychain access for example).