Object Oriented programming is hard. It’s easy to program in a language like Java, but hard to get it right. Why?
Because Object-Oriented programming is more than just writing classes and methods. OO programming is way more than that.
I think the hardest thing in OO programming is the ability to create objects with cohesive functionality. The ability to assign responsibility well is the key to object oriented programming. And that is hard.
To see where you are, ask yourself this question: what is an object? Is it an instance of a class? Or is it a data structure? If any of those two, you don’t think in objects.
I think to truly program in an object-oriented way, you have to treat your objects as a set of responsibilities. Object oriented programming then is creating and assigning responsibilites to different objects. OO programming is creating a set of objects that are able to collaborate to achieve a task.
Also, it’s important to spread the functionalities (more or less) equally to several objects. It’s important to have objects that do several (Grady Booch recommends 3 to 5) of related tasks and do it well: specialized (cohesive) objects. That’s why your classes should not be too large. It is a sign that your class does too much — it has too many responsibilities — if it is large. It’s usually good then to break up that class into more specialized classes.
The biggest benefit of OO, I think, is the ability to think more abstractly. It’s the ability to concentrate on a higher level. It’s like programming in Java vs C++. In Java, you don’t have to worry about pointers and references. You are working on a higher level. I think you can accomplish more that way (and save your brain for other tasks ).
To be a good programmer, better coder, you have to be a good OO programmer. It’s not an easy thing.
I have not done any SOA development yet. I’ve just been reading and hearing a lot about it. I’m reading the Enterprise SOA e-book at ACM.org now (my first on SOA; so far it is a very good book) and I just want to share some of my SOA views.
I think the Service Oriented Architecture (SOA) holds great promise. The key word is “holds” because, as of now, I think we mostly have a lot of hype surrounding it. There is too much hype and not too much actual implementation, because SOA has some issues that need to be adressed/resolved. There are certainly bits and pieces actually being developed, but that’s not really service oriented architecture.
The potential of SOA is there. It enables reuse in dimensions never seen before. It enables the usage of different technologies. It gives you the ability to bring old technologies/projects back to life.
What I see happening is that you have a project that provides some functionality that you would like to reuse. Instead of putting this functionality inside your project (as a dependend project) you make it a service. This does not couple you with the project as before. And the project that you are dependent upon has its own life. It can change the DB, it can change the language it is implemented in, and a lot more. One thing that does not change is its public face, the API, the service contract. This really is exciting.
I think there are two very big problems, though. First, the complexity. It is still very complex to actually develop the self standing services. We have so many different techniques, and they do not really like to talk to each other easily. I am still lost in the midst of all the available technologies. I think that’s changing and I hope a clear, easy to develop/understand standard will appear.
The second problem is speed. Calling a service is a network call. In the traditional way, where you have a dependent project, it is a regular function call. The difference in speed in the two is huge, I don’t know the details but I’d guess a service call is at least 100 times slower. To mitigate this issue, good caching is needed. In this case, the service calls would be cached on the client. This way, only the first call for each service parameter values would incur the call expense. Not too bad. Certainly possible. But this just adds more complexity.
SOA promise is certainly there. It will happen. Probably in the next couple of years, in the next decade. There are still major issues with it, as I see it. But the major obstacles in my mind are complexity and speed.
Lessons from the Google Web Toolkit…
I’ve been looking at the sample projects from the Google Web Toolkit. Mostly looking at code and playing around with the apps. Based on this, I think I can learn couple things from the toolkit and the source they provide.
First of all, if you have not looked at the code, it might be a good time to do now (by downloading the tookit, you will have everything under the samples directory).
I love the samples’ code style. I love its simplicity.
If I was an architect for a code style document, I would adopt the following things:
Simple, small classes. It’s a joy to look at them; they’re easy to understand and thus, I think, easy to modify.
Small methods. Show me a method that’s over 100 lines. I’d like to see it. The way they built the framework, the abstractions they have, allows them to have small methods. This is a key to having maintainable code.
Using intefaces a lot. Using inheritance. It allows them to keep their classes small, highly specialized.
Self-commented code. They don’t use too many comments. They use self-commented code. The source speaks for itself. That’s beauty.
A one sentence summary of what the class does. If you can’t fit it in one sentence, it means that you don’t have a good class. It should probably be renamed, broken up, refactored. But this one sentence should always be there.
Comments to explain more complex code. Writing self-commenting code is crucial, but not always possible. Adding a comment where it helps is important.
Not going over 80-character margin. I’ve been trying to do that (in Eclipse you can set a visible margin at 80 – search for “margin” in preferences). It makes the code more readable.
Having 2-character tabs. I like that. The code looks better. Plus, you can fit more into 80 characters.
Effort put into making code readable. I can’t stress this enough. Put your name on the code, make it look good, make it elegant. Your code is your public face to other programmers, believe it or not.
I think it’s important to have a mindset that a quality code is a requirement (and an asset).
P.S. One thing I did not like is the package structure. They just put everyting into one big package. Not the optimal way, I think, but maybe they did not want to expose too much.
How many times have you been thinking “let me just copy this here. It’s not going to change. And if it changes, I’m going to modify it in both places.”
I think that’s a critical sin.
You might remember, but the next maintainer might not.
I have commited it many times, no doubt about it. But it was never a good thing. I have also experienced the benefit of having a single place to make changes. And it feels great.
In my opinion, duplicating code is the single biggest sin that you can commit. Always try to refactor the code to avoid duplication.
What invites duplication is code complexity, I think. If I find a code that is hard to understand, I am afraid to modify it. I’d rather copy it and modify it than refactor it. But I’m still commiting the sin. So you should try to make our code as simple as possible (it is a lot harder to do than writing complex code, believe me). Whenever I see code that is simple, easy to understand, I have high regard for the developer that wrote it (imagine what I feel when I’m frustrated ).
Avoiding duplication is tough sometimes. Sometimes it cannot be avoided. But you should have a mindset of never duplicating, be it the last resort. And if you do, you should feel that you did something wrong (write a comment to indicate that you’re duplicating; admit the sin ).
Whenever I see a lot of duplication in a project, I know it’s not a quality project (no matter what it does). Youl want to write high-quality projects, right? Youl want to become a better developer, right? Avoiding duplication is a required route to take in that direction.
Good developers always strive to avoid duplication.
Programming on Purpose
by P.J. Plauger
ISBN 0137213743
Date Read 5/2006
My Rating
This book is dated, no question about it. However, it contains several excellent essays that are as relevant today as they were decades ago.
A lot of the techniques discussed in the book are no longer used. This was a book written in the days of structured programming. Those days are over. Thus, I found several of the essays boring. I could not put my full attention into them. They seemed dry.
Several essays in this collection were priceless, though. Worth buying the book just for those. Which Tool Is Next (Ch.7) is an excellent intro to software engineering. It contains several excellent analogies and definitions of software engineering. I think the best essays in the book are the last 5: the author talks about OO Principles and Software Engineering in general. The chapter on Encapsulation (Chp 21) is the best I’ve read. The chapters Heresies of Software Design (Ch 23) and Remedial Software Engineering (Ch 24) are just so “capturing.” They explain what works and do not work in software engineering. They define the whole software engineering industry.
Like I said, this book is dated. But because of the several excellent essays, this book is a keeper. Those essays are worth re-reading. The author is a great teacher, good writer. Most of all, the author speaks from his own experience (years of it).
I must admit. I am still having hard time seeing a real difference. I am still having hard time defining them both.One thing I am sure: both are fundamental principles of object oriented programming. I am going to try to learn them here and explain the differences. Just so I know for future.
“Abstraction and encapsulation are not synomous,” says P.J. Plauger in Programming on Purpose.
Encapsulation is information hiding. I think that’s the best way to define it and remember it. “Information hiding allows for implementation of a feature to change without affecting other parts that are depending on it.”
P.J. Plauger has a great analogy and definition of information hiding.”Information hiding is not the same as secrecy. The idea is not to prevent outsiders from knowing what you are doing inside a module. Rather, it is to encourage them not to depend on that knowledge. That leads to a kind of secondary coupling which is more pernicious than obvios dependency because it is less visible. You should encapsulate information to keep it private, not secret. (What you do in the bathroom is no secret, but it is private.)”
“Stuff all of the code that is likely to change in a module [class] and hide its innards.” That not only defines information hiding, but it is also a fundamental principle developing: when to create a new class, when to refactor.
Abstraction. Look at it as “what” the method or a module does not “how” it does it. I just found a great definition of abstraction: “The notion abstraction is to distill a complicated system down to its most fundamental parts and describe these parts in a simple, precise language.”
Let’s compare Java and C++. We have a good example of abstraction. In C++, you have to deal with pointers and references a lot. You have to deal a lot of garbage collection. In essence, you have to work on a low level. (C and C++ in turn abstracted a lot of even lower level machine code.) In Java, those things are abstracted away. You just assume they exist. In essence, abstraction means that you are working on a higher level. You don’t care how pointers work in Java, you just assume that they work. You don’t have to concentrate on the lower level stuff, you work on higher level.
I think abstraction is extremely important. By working more abstractly we can solve more and more difficult problems because we don’t have to concentrate on the lower level details. As Steve McConnel puts it, we are working closer to the business domain.
So to summarize, I think I got it now. Encapsulation is information hiding. Abstraction means working on a higher level, not worrying about the internal details. They go hand in hand. The bottom line, even if you still don’t know the differences, utilize information hiding; make your programs more abstract by creating classes with responsibility and then talk about the feature by the name of the class, but what it does, not by how it is doing it (that’s abstraction, I think).
Simplicity always wins, in my opinion. The following two quotes from Programming Pearls (book I’m reading now) need no further comment: they nail it.
|
A designer knows he has arrived at perfection not when there is no longer anything to add, but wen there is no longer anything to take away.
–Antoine de Saint-Exupery
the French writer and aircraft designer (quoted in Programming Pearls) |
|
More programmers should judge their work by this criterion. Simple programs are usally more reliable, secure, robust and efficient than their complex cousins, and easier to build and maintain.
–Jon Bentley
in Programming Pearls |
That’s an exact title from Johanna Rothman’s blog post. I totally agree: architects must code. If you an architect you need feedback. You need feedback because you want to make a better architecture in the future, to make improvements, and to see what doesn’t work. How do you get that feedback? You need to write code. There is no other way. There might be, of course, but most of the time it does not work.
I want to move into architecture in the next couple of years, I like to code: perfect marriage. But architecture is hard, it requires a lot of knowledge in a lot of areas. Most of all, it requires a lot of experience so you know what works and does not work. That’s why I’m learning a lot, keeping an eye on how to improve.
This point from Johanna says it best:
I’ve been a part of projects for 30 years. I’ve been assessing projects for 10 years. And every time I’ve seen an architect who doesn’t participate in the code-writing part of the project, I’ve seen an architecture that doesn’t do what it’s supposed to do, never mind extend to inevitable changes in requirements that occur during the project.Architects need feedback about their architecture. The only way to get feedback is to write the code, integrate it, and see what happens.
RelatedCharacteristics of a Software Architect, my previous post
ReferenceArchitects Must Write Code, Johanna Rothman
What’s the single most important thing when writing code? And practical? To me, it’s the DRY, OAOO principle.
Don’t know what those acronyms mean? Don’t Repeat Yourself, and Once And Only Once principle. Not repeating the same code in different places is the single most important thing you can do to make your project easy to maintain and to modify in the future. There are no exceptions to this rule. If you have repeated code in different places, it is a matter of time when you will see the project disintegrate. Do yourself a favor: don’t copy and paste. Modify the method, break it up into two. But don’t make it wet.
I broke this rule numerous times. And numerous times I was sorry that I did. I did it, and I got burned. It’s tempting to do so: easy and fast. But always consider the consequences.
I like my code to be clean: I like “girly” code. Duplication makes it dirty.
I can say with certainty: If your project has any duplication of logic, it is not a quality project. And after the first copy and paste, you take an express ride to a restaurant for a pasta meal. I mean “spaghetti.” I mean spagheti code. Do you want that?
I understand that you cannot always avoid duplication. For instance, if I have to modify an existing project, I might have to work with a lot of duplication (I hate it when I do), but for any new code that I write I have the following principle:
DUPLICATION PRINCIPLEDuplication is my enemy. I want no enemies; therefore, I will not create any duplication and I will try to kill it whenever I see it.
ReferencesThe Pragmatic Programmers: The DRY PrincipleCode like a girl, Creating Passionate Users blogOnce And Only Once, WikiWiki
I’m working on a legacy project and I’m frustrated. It’s a mess. It seems that it was built to never be modified. It is just a pain to make even a small change to it.
I hate when I’m working on an Object-Oriented project and it contains special exceptions. C’mon, use polymorphism, use template methods, whatever, no special exceptions. I think what happens is that people design it nicely at first but then when a change is requested they just create a special exception because it is faster. Don’t fall into that trap. In essence, with that one exception they broke the system. The next change is “just another” exception. On and on… the system becomes a nightmare to modify for a new person on the project.
In any case, a system like that is slow to modify. You make changes to the system and you are scared that the roof will fall — problems appear in different places. That’s not object oriented programming, that’s hacking and destroying the system. So, next time you want to add a special exception to a fully working system, think twice, because, in essence, you are breaking the system. Put the time in and refactor it. Keep it object oriented and you will be glad that you did.
So how do you make your system better, more object-oriented? Keep it that way! Don’t break it by putting special exceptions. No exceptions. Really.
One of the rules that I have when working on any type of a change is to make the system better. Better for me, and better for someone after me. I always do that. Whether it is breaking it into a smaller method, creating a new class, renaming a method. Whatever works, whatever makes it better.