Saturday, 27 October 2012
Saturday, 20 October 2012
What's so cool about OO?
When people start reading or talking about object oriented (OO) design, there is always a bunch of quite fundamental questions appearing, at some point.
Ad.1. What does OO design really mean?
Short answer:
It is all about dependency management.
Long answer:
It means breaking source code dependency and diverting it, so that we would get an independent deployability.
Ad.2. Does writing in object oriented language mean I am creating OO design?
Short answer:
No.
Long answer:
OO language is providing you a mechanism, to grow an OO code. The trick is that OO language creates an opportunity of using that mechanism, but nobody is pushing you to do so. That is why you have to be aware of what you are doing and consciously use available language features.
Ad. 3. Why some developers despite using OO language, they do not create OO code?
Short answer:
They do not know what OO design is.
Long answer:
Some developers assume that writing in Java, an OO language, means they are so cool that everything they touch is OO. It is not true. Even worse thing is they do not know how wrong they are. This is sad, but often it is true.
Ad.4. How is OO language different from functional one?
Short answer:
These two approaches are very different.
Long answer:
These are two, entirely different concepts. Each of them has its own strengths and limitations. We have to know both sides to choose wisely what we need. Same time, we have to be aware of the consequences of our choice.
Object oriented languages have a very good dependency management mechanism. On the other hand, functional approach is much better in terms of:
Ad.5. What is the first class citizen in OO and functional approaches?
Short answer:
Object oriented languages: objects.
Functional languages: functions.
Long answer:
Functional languages: functions.
Object oriented languages: objects, but to be fairly honest the interface is the one, who is a major player.
As I said previously, it is all about dependency management. To be more precise, it is all about how to invert source code dependency (aka compile time dependency) against flow of control (aka runtime dependency). To satisfy that idea, we have a set of techniques enabling us dealing with dependencies:
Okay, so what is the beef ?
Again, it is all about dependency management. Let's crack down some simple, but not easy example.
Imagine a car using an engine. The Car object is having a dependency to the SportEngine.
We may crystalize that dependency by saying that Car has a start method, which uses SportEngine's run method. That is how our initial dependency may look like:
As you can see, we have a source code dependency pointing exactly to the same direction as runtime dependency. Source code dependency is an import statement in Car class, which associates Car with SportEngine, in a direct way. Runtime dependency tells you that Car uses SportEngine, so that it can start properly.
The whole idea of solving above problem and many other, similar issues is:
TO BREAK A SOURCE CODE DEPENDENCY AND DIVERT IT.
That is an extremely crucial thing to understand. However, there is one gotcha here. People may think that whole trick is about diverting the compile time dependency arrow from SportEngine to point directly to the Car. This is wrong! It needs to point towards Car, but not directly.
How can we do it ?
Let's introduce a middle man called an Engine, which in fact is a polymorphic interface between Car and SportEngine. The Car class will be using Engine interface, which would have a run method. On the other hand, SportEngine class will be implementing Engine interface.
From now on, we have the source code dependency diverted and pointing towards Car class, at least from SportEngine's perspective. That point of view is one of the most important assumptions, which we need to understand. Only embracing SportEngine's perspective and its source code dependencies allows us to see the bigger picture.
From high level perspective, the whole idea looks easy, however it is only a superficial feeling. In fact, we have to see the problem from three, totally different perspectives (Car, Engine and SportEngine).
Summing up, SportEngine knows about Engine and so as Car class. The runtime dependency's direction remains the same and points through Engine's interface to SportEngine class.
That is what we got:
Real life example.
The almost obvious extension would be to apply above principle on different levels like: classes, modules, components, entire applications or DBs.
- What does OO design really mean?
- Does writing in object oriented language mean I am creating OO design?
- Why some developers despite using OO language, they do not create OO code?
- How is OO language different from functional one?
- What is the first class citizen in OO and functional approaches?
Ad.1. What does OO design really mean?
Short answer:
It is all about dependency management.
Long answer:
It means breaking source code dependency and diverting it, so that we would get an independent deployability.
Ad.2. Does writing in object oriented language mean I am creating OO design?
Short answer:
No.
Long answer:
OO language is providing you a mechanism, to grow an OO code. The trick is that OO language creates an opportunity of using that mechanism, but nobody is pushing you to do so. That is why you have to be aware of what you are doing and consciously use available language features.
Ad. 3. Why some developers despite using OO language, they do not create OO code?
Short answer:
They do not know what OO design is.
Long answer:
Some developers assume that writing in Java, an OO language, means they are so cool that everything they touch is OO. It is not true. Even worse thing is they do not know how wrong they are. This is sad, but often it is true.
Ad.4. How is OO language different from functional one?
Short answer:
These two approaches are very different.
Long answer:
These are two, entirely different concepts. Each of them has its own strengths and limitations. We have to know both sides to choose wisely what we need. Same time, we have to be aware of the consequences of our choice.
Object oriented languages have a very good dependency management mechanism. On the other hand, functional approach is much better in terms of:
- multithreading (immutability out of the box)
- lack of states, which means lack of side effects
- flow oriented applications.
Ad.5. What is the first class citizen in OO and functional approaches?
Short answer:
Object oriented languages: objects.
Functional languages: functions.
Long answer:
Functional languages: functions.
Object oriented languages: objects, but to be fairly honest the interface is the one, who is a major player.
As I said previously, it is all about dependency management. To be more precise, it is all about how to invert source code dependency (aka compile time dependency) against flow of control (aka runtime dependency). To satisfy that idea, we have a set of techniques enabling us dealing with dependencies:
- SOLID principles - helps to manage dependencies in OO design
- Component cohesion principle - describes forces that cause classes to be grouped in the independently deployable components
- Component Coupling principle - describes forces that govern dependencies between components
Okay, so what is the beef ?
Again, it is all about dependency management. Let's crack down some simple, but not easy example.
Imagine a car using an engine. The Car object is having a dependency to the SportEngine.
We may crystalize that dependency by saying that Car has a start method, which uses SportEngine's run method. That is how our initial dependency may look like:
package com.korczak.oskar.blog; import com.korczak.oskar.blog.engine.SportEngine; public class Car { private SportEngine sportEngine; public Car(SportEngine aSportEngine) { this.sportEngine = aSportEngine; } public void start() { sportEngine.run(); } }
package com.korczak.oskar.blog.engine; public class SportEngine { public void run() { // here goes some engine implementation } }
The whole idea of solving above problem and many other, similar issues is:
TO BREAK A SOURCE CODE DEPENDENCY AND DIVERT IT.
That is an extremely crucial thing to understand. However, there is one gotcha here. People may think that whole trick is about diverting the compile time dependency arrow from SportEngine to point directly to the Car. This is wrong! It needs to point towards Car, but not directly.
How can we do it ?
Let's introduce a middle man called an Engine, which in fact is a polymorphic interface between Car and SportEngine. The Car class will be using Engine interface, which would have a run method. On the other hand, SportEngine class will be implementing Engine interface.
From now on, we have the source code dependency diverted and pointing towards Car class, at least from SportEngine's perspective. That point of view is one of the most important assumptions, which we need to understand. Only embracing SportEngine's perspective and its source code dependencies allows us to see the bigger picture.
From high level perspective, the whole idea looks easy, however it is only a superficial feeling. In fact, we have to see the problem from three, totally different perspectives (Car, Engine and SportEngine).
Summing up, SportEngine knows about Engine and so as Car class. The runtime dependency's direction remains the same and points through Engine's interface to SportEngine class.
package com.korczak.oskar.blog; import com.korczak.oskar.blog.engine.Engine; public class Car { private Engine engine; public Car(Engine anEngine) { this.engine = anEngine; } public void start() { engine.run(); } }
package com.korczak.oskar.blog.engine; public interface Engine { public void run(); }
package com.korczak.oskar.blog.engine; public class SportEngine implements Engine { public void run() { // here goes some engine implementation } }
That is what we got:
- Car and SportEngine are separate classes
- Independent deployability
- We can have many different Engines deployed
- Module SportEngine plugs in to Car
Real life example.
The almost obvious extension would be to apply above principle on different levels like: classes, modules, components, entire applications or DBs.
Few days back, I found that principle very useful on a DB level. We got a very tight dependency between us and other project, who had a read only access to our DB. I know that letting even a read only access to other projects is something similar to ripping the application's skin and exposing our guts to the public, but let's not discuss the root cause of that situation. The issue was pretty substantial and causing a lot of annoyance, hurt feelings and other stuff. Every single alter operation on a table like changing the type of field, its length or adding a column was a massive pain for both sides. I will only mention that adding a new table or dropping it was even worse. On a top of that we found that we have different release cycles. Basically, we were required to slow down our process, so that we would conform to the slower project. Incidentally, it was very similar to situation almost all of us had at school. Teacher had always to work as fast as the slowest person in the group, causing others to be pissed off. On the other hand, the slowest guy was also annoyed as everybody was waiting for him. Typical loose-loose situation.
We badly needed a clutch and we found one. The solution was to expose only those business data, the other project needed, via DB views. All the rest say technical data was hidden behind views. We built these views having a well defined interface between us and them. Interface was not changing almost at all and we were independent from the other project. We still could do releases in our pace, without any other external dependency. Other guys were also happy about still DB interface and maintaining their release cycle. Typical win-win situation.
If we examine above case, we easily find that project exposing some data was an allegory of SportEngine and guys reading our DB were a reification of Car. We simply created an interface, which diverted a source code dependency.
Sunday, 14 October 2012
Show Me the Value
Do you recall a well-known phrase uttered by characters in the 1996 film 'Jerry Maguire'?
If one would like to sum up Agile practices in a neatly tailored way:
'Show Me the Value' is one of the best approaches I have ever heard about.
If one would like to sum up Agile practices in a neatly tailored way:
'Show Me the Value' is one of the best approaches I have ever heard about.
Sunday, 7 October 2012
The Bigger Picture of Lagre Projects
Have you ever thought how big your project is and what it implies? Many people boast of their projects and how lagre they are. However, there is one consequence, people seem not to be aware of: the bigger project is, the harder is to finish it on time or at all. According to Jim Johnson of the Standish Group:
"Projects greater than $6M are considered large and have a 1% success rate."
Subscribe to:
Posts (Atom)