Pages

Friday, May 27, 2005

Who's responsible for what?

It seemed like forever since my last post although I think it was just 4 days since I last bragged here :) Anyway, last week was a veeery busy week for me. I had to finish this java-based text game and then do thos other use case diagram for my other class. Alas! The benefits of being jobless proved itself beneficial to me once again!! I just hope that I got high marks for those.

My Naruto downloads are progressing err... somewhat slow.. so far, I've just downloaded the first 11 eposides and the last 5 episodes (using the school's internet :D) the site that hosts episodes 1 - 50 won't allow me to download 65 megs in an hour so I cannot use the school's bandwitdth to download those early episodes (which are sooo large by the way). Having to donwload an episode for 14 hour and then reaping the benefits by watching that 22-minute cartoon and then having to wait for 14 hours more is just crazy!! It's like whenever you finished downloading a single episode and then you watch it and then you get this tendency to become emotionally attached and then all of a sudden, the episode ends and then you launch your download manager and it tells you that you still have to wait for 13.40 hours before the download for the next episode.. damn!! all the excitement and all the emotion build-up just have to wait for 13 more hours!! A DSL surely would come in handy in this situation :D But hey, a 14 hour download is worth the wait if it lets me watch an episode of Naruto :D

So, where were we?! Oh yes.. I want to skip the math mumbo jumbos today that I've been bragging about over my last few posts and just talk about a very important thing that I've learned in programming - especially when you are dealing with objects. But I'll try my best not to include objects in this post. Today, I want to talk about coupling and cohesion. These two concepts are very important and yet are so much pain the ass that it takes them a lot of time to master but once you do, it will give you the skill to make your programs the ability to become incredibly extensible and maintainable in an almost effortless manner. It's like this phrase that my professor always says: "Once you know, you know."

As far as I can remember, maintaining a program is really and I mean REALLY is one of the most difficult part of the programmer's life. I remembered way back during my thesis days when I had this Super Trump program that we initially did during our software engineering class. It was constructed in a procedural approach using an object oriented programming language which as we all know would leave a lot of trace of inefficencies like numerous amount of code redundancies, very high dependencies between modules, and a method that knows how to do all!! It seemed like almost imposible for me to maintain that crap and to tell you frankly, if it weren't for that thesis, I could have pressed SHIFT + DELETE and it would have sent it directly to the recycle bin!! Just imagine the things that we had to go through just to add additional features to the game that our thesis advisor made us do. Just imagine this scenario: You have these five thousand lines of code in your program. You want to add a feature that lets you shuffle the decks of the players. So, you study the codes (.. no big deal..) and you try to implement the changes that you think are necessary.. and that's it.. but wait, there's more. You tried running the program.. what's this?! a runtime error?? what the.. Oh yes.. the perils of debugging a code. Now you have to spend some time looking at each of the modules and try to think what went wrong. You know have to think what were the components that were impacted during the change, the code snippets that you have to update in order to make the changes work, and probably search for those redundant codes and apply the updates to those as well and make sure that you did not forget anything, and oh, I need to remind you that you are working on a program that has 5000 lines of code and that you are running out of time because you have a scheduled program demo tomorrow!! God dammit!! I wanna die!! Harharharhar!!

"So, what is this coupling and cohesion that you are talking about?" you asked. Well, coupling is a concept that talks about the degree of dependence between each part of your program. Cohesion, on the other hand talks about the number of tasks that a unit of your program can perform. As a programmer and a designer, we aim to develop a program that is high in cohesion and low in coupling. This simply means that individual units of a program should have very low dependence with each other and that each units of the program should have a single and well-defined task that it should do. To put things in proper perspective, low coupling allows the programmers to make changes to one part of the program without having much effect on the other parts of the program. It means that whenever we want to add or remove something on a certain part of a program, we shouldn't have no worry (at least) about any possible side effects that it may cause to other parts of the program. High cohesion on the other hand just means limiting what a module or a class can do in such a way that it all its methods contributes to the overall identity the class or the module itself. It means that if you have a module that computes for taxes on a certain income bracket, then it should only compute for taxes, nothing more. Seems easy eh?! Well there's a lot more than meets the eye you know.

So how do we achieve a low-coupled and highly-cohesive program anyway? Well, to be able to achieve a low-coupled program, I now introduce the terms implementation and interface. An implementation, in simple terms, describes how a program works from the inside while an interface describes how the program works on the outside. Let me explain on this more using an analogy. Lets say you have a calculator. As a student, you know how to use the calculator by pressing the buttons and looking at the screen for the result. But whenever you press a button, something happens from the inside. All of those circuit boards and logical gates reacts to the button that was pressed and performs the expected operation. But then again, the student doesn't care how 5 + 4 is processed inside the calculator. All the student knows is that whenever the buttons 5, +, 4, and = are pressed, it will yeild 9 as the result and display it on the LCD. Hence, we can say that the student "trusts" the calculator to do its job and it doesn't care how it does it - as long as the what the student is expecting is projected by the calculator to the LCD. Going outside the analogy, we can say that the interface in the calculator are the buttons and display and the implementation are those series of gates and circuit boards which are all underneath the plastic cover. Now that we understand what these concepts mean, lets go back to coupling. To be able to achieve a low-coupled program, each units of the program (class, methods, modules, etc) should communicate not with its implementation but with its interface. This implicitly says that a certain unit of the program should not know how the other unit that it needs to interact with works internally. It only needs to know what are the interfaces that the unit offers (remember the calculator buttons!) and have the unit to interact with it - and that's it! Certainly, on the calculator analogy, we do not want the student to have it learned digital circuits just to use the calculator eh?! So how does it reduce the time to maintain a program then? Well basically, if you depend on a module or a class' interface, once the implementation of that unit of the program changes, you don't need to worry at all on whether the other methods or class that uses it will still work - because it will (that is of course if the interfaces are still intact!!). Certainly, on our calculator analogy, if later (for some reason), Casio decided to store numbers in octal form instead of binary inside the calculator, then we can implement that change inside the circuitry without having to change the buttons because after all, what we are changing is how it works - from the inside. Having all of these said, I hope that it is now clear that low-coupled programs reduces dependencies between programs and as a result, reduces the impacts that may require changes to other affected parts of the program. Phew! That takes care of coupling.

Now on to cohesion. If you have a module or a method in your class that seems to do almost everything, then this is an indication that your program is lowly cohesive (sounds like mighty bond!) This means that your neighbor shouldn't be living in your house and instead it should live in its own house! Every class or module that are defined in the program should do a single and well-defined task. This would allow for a proper division of responsibilities between modules / classes and other modules / classes. By having a highly-cohesive program, we ensure that a certain module or a class takes care of its own methods - otherwise, we will end up having other classes or modules of different animals taking care of methods which they are not supposed to be doing. And this adds more coupling to our program - and we all know what that means now don't we???!

Now all of these stuffs doesn't happen magically you know. There is no silver bullet towards a highly maintainable program. To be able to come up with a program that has these characteristics, you should not just jump right ahead to coding and just have these sporadic thoughts run while you program. Certainly, all of these are attained through good design and proper recognition of the problem. Take some time to learn how the program is supposed to run, what are the entities involved in the program, and how do they interact with each other. These very simple steps are often underestimated even by veteran programmers. As a rule of the thumb, the more you design, the less hours you spend on hours and hours of frustration on trying to do things right. "But hey, do I even need to design a program even if its just as simple as my stupid assignment in COMPR4?" you say? Well, find that out yourself. After all, the best way of learning is experiencing the learning in the first place ;)

Alright, I guess that's it with this long post! I still have to solve this stupid exercise number 37 in my math book (I have been stucked with this number for 6 days now you know!!). I'll try to post it here once I find the solution for it. Ciao!!

No comments:

Post a Comment