Creating methods is probably the single most often performed activity during programming. Thus, it is crucial that it is performed well. When creating a method, I think the most important thing is that it should perform one task and do it well: it should have high cohesion.
High cohesion is the fundamental principle in object oriented programming (probably the most important). If there was a way to require high cohesive methods, then it should be a requirement. I’m all for it.
If you have cohesive methods then it is a good sign that you are a good Object Oriented developer. It shows that you program for a human to read, not the computer. Having high cohesion is hard, you have to have one-task methods with good method names. It is a constant struggle to keep it cohesive with the additions/modifications. But if you accomplish that, then you’re good. :- )
So do you have to care about the method size?
Actually, you should not. But somehow, you find a lot of methods that are very long. A lot of them are over 100 lines, some are over 150 lines. I’ve seen even longer than that.
I think a good rule of thumb to adopt is to have methods that do not exceed your screen’s size. It’s a good rule. It allows you to see the whole method without scrolling. Which means your method should not be longer than 70-100 lines, roughly.
Alternatively, if you have a generic method name and your method is long, it should (be required to) be refactored and the related things put into its own method.
In the Signs You’re a Crappy Programmer (and don’t know it) article, the author states [that you are a crappy programmer] if:
You are adamantly opposed to function/methods over 20 lines of code. (or 30 or 10 or whatever number of lines) Sorry, sometimes a really long function is just what’s needed for the problem at hand. Usually shorter functions are easier to understand, but sometimes things are most simply expressed in one long function. Code should not be made more complex to meet some arbitrary standard.
I think the key word is “sometimes.” It’s OK to have a long method here and there, the problem is when you have it in a lot of places — in too many places. If your method does one function — one responsibility — and it takes over X lines, it’s fine, no reason to break it up. But a lot of times, those long methods “accrue” extra responsibilties, making them harder to maintain. I think everyone can agree that a long method is harder to understand and modify than a shorter one.
Actually, I think you are a crappy programmer if you have a lot of those long methods with non-specific names.
The bottom line is to have functions that do one task and do it well. If you do that, you don’t have to worry about the length, your methods will be short and easy to modify.
Everybody would benefit if you adhered to the rule of thumb, especially the maintainers of the code.
ReferenceSigns You’re a Crappy Programmer (and don’t know it), Damien Katz
RelatedWrite English the Way You Write Code – very good post
I don’t know if anybody actually reads the comments that we sometimes write as Javadoc. Do you? I don’t, most of the time.
That’s why I think it’s important to write code that speaks for itself and that does not need a comment. I’d go this far: if you need a comment, your code should be refactored and made easier to understand. (What does it mean easy? Easy for somebody else to understand — important to keep this in mind as well.)
So how do you write self-documented code?
Use good names. For class names. For variable names. And for method names. Don’t name your class WriteData or ConnectionInfo. They should have better names. They should be more specific. You should be able to tell what a class or a method does by its name.
Be short and specific. I hate it when I have to modify a 1000+ line class. I hate it when I have to modify a method over 100+ lines (you should have rules for these :- )). Have classes that have a specific set of tasks to accomplish. Have methods that do one thing and do it well. In this regard, it helps to have good and specific names so you know exactly what your class or method is doing, and whether you need to assign the new responsibility to a new class (assigning responsibility is crucial in OO development, as I said before).
Abstract it when you can. When you have some complicated logic, encapsulate it in a class, hide the complexity. By doing so, you’re putting it in one place and you don’t have to delve into details of how it works, as long as it works — you assign it a responsibility and you hold it accountable. If you keep adding complicated logic to a class or a method, you’re messing up the class, making it harder to undertand and modify. If it was seperate and nicely abstracted, you can modify it with more confidence. Maybe it’s better to add a new class, a new method? Ask yourself that before adding any complex logic.
When writing a comment, focus on “why” not “how.” Make every comment be of substance. Comment surprises.
In some cases you have to have complex logic. Add a comment then. Make it easier for you and for others. Prepare the reader for complex logic with a comment, explain why it is being done that way.
I think writing a self-commented code, code that is easy to read, is a crucial part in our day-to-day programming. It’s one of the things that has huge effect — in both positive and negative direction.
To be a good coder, to become a better coder, make sure your code is easy to read.
RelatedCode Complete, Steve McConnell’s excellent book (my previous recommendation), required if you want to become a better coder
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.
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.
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).
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.
I have around 6 years of development experience. I have worked for several companies now. I can tell you one thing: a lot of developers don’t know how to write object oriented code. They write Java and they assume they write objects. But those are not objects; they’re more like data structures. Objects are not data structures, objects have to have a clear responsibility, a clear purpose. Object should do one thing and do it well.
Anyway, I am going to put my thoughts on object oriented systems here in this category. My thoughts, learning experiences, etc. Hey, I learn as I gain experience. I’m not perfect and I don’t want to be. But there are some principles that I have already learned that work for me. One thing I’m sure: writing objects is hard, very hard. It takes real effort and dedication. It takes years of experience to do it well. But modifying a nicely structured object-oriented system is a joy. It’s fun. I like to program, but it has to be fun. “Hacking” might be fun, but it is fun in only one direction: it’s not fun when you have to modify it and undo your “hack.”
I believe that good programmers are egoless and humble. There is no room in software development for attitude. Of course, you can be that way, and a lot of people are, but what they fail to recognize is that the path takes them downwards. That path will not make you better, that’s for sure. So be humble, admit mistakes, learn from others, and you’ll do well.
Lamont Adams has a list of 10 Commandments of Egoless Programming. It’s good stuff, read it.
1. Understand and accept that you will make mistakes.2. You are not your code.3. No matter how much “karate” you know, someone else will always know more.4. Don’t rewrite code without consultation.5. Treat people who know less than you with respect, deference, and patience.6. The only constant in the world is change. Be open to it and accept it with a smile.7. The only true authority stems from knowledge, not from position.8. Fight for what you believe, but gracefully accept defeat.9. Don’t be “the guy in the room.”10. Critique code instead of people傭e kind to the coder, not to the code.
For a more detailed version, go to the article, below.
ReferenceTen Commandments of Egoless Programming, Lamont Adams
RelatedEvery Craftsman Is Dump and Lazy, my post