The Pragmatic Craftsman
:: Simplicity from complexity ::
What was the last book you read?
Has it been long?
The bottom line, to become a better coder, better [anything], you have to do the things you are used to do… better. Reading books is one of the best ways to acquire knowledge, to deepen your knowledge, to improve yourself: to become better.
How much do you have to read?
The Pragmatic Programmers (very good book, btw), recommend reading a book every quarter. Steve McConnell in Code Complete (excellent book), recommends reading around 35 pages a week.
Is that a lot?
My guess it is that you’re most likely reading that much already, so keep doing it. Shifting to a book a month might make it more challenging,
The software development world is constantly changing. If you’re not following it, by reading and practicing, you’re falling behind.
Nowadays, though, it seems to me that people are reading everything but books. People read blogs, articles, etc. I don’t think that’s bad, I just think that a good book is more valuable. You should still have books as your primary source of knowledge. A book gives you a more complete knowledge. A book requires a lot more knowledge to create than a blog entry or an article.
Where to start? What to read?
We don’t have the time to read all of the books (I wish). So read the best. Read the classics. Just start reading and applying the knowledge you gain. A great book to start is Code Complete. It will help you guide your career.
One effective way to stay on top is to read and then apply the knowledge you learned. Repeat continuously.
RelatedContinuous Learning by Reading, my previous entry
Adding new responsibilities to a class is a fairly common thing in coding. We do that when we get a request from a business person. We do that also when we refactor parts of a project. It’s an everyday activity you can say.
But here’s a question? How do you determine where to put the responsibility? What is the best place?
By the Information Expert pattern, you should add it to the class that has the information. It’s almost like in real life, you ask people that have the necessary tools and knowledge to do a job.
What is the Information Expert pattern? It is discussed in Applying UML and Patterns book. It is part of the GRASP patterns, which describe fundamental principles of object design and responsibility assignment. We hear a lot about GoF patterns but, in my opinion, not enough about GRASP patterns.
This pattern is simple and results in objects that do things related to the information they have.
However, if you applied this pattern everywhere, you would end up with a class that knows how to load its information, persist to db, etc. That’s not good. You are violating a lot of patterns by doing that (high coupling, low cohesion, too many responsibilities, and many more). Or, as author says, you are violating “basic architectural principle: design for a seperation of major system concerns. Keep application logic in one place (such as the domain software objects), keep database logic in another place (such as a seperate persistence services sybsystem), and so forth.”
What major benefits does the Information Expert give you?
“Information encapsulation is maintained, since objects use their own information to fulfill tasks. This usually supports low coupling, which leads to more robust and maintanable systems.”
“Behavior is distributed across the classes that have the required information, thus encouraging more cohesive ‘lighweight’ class definitions that are easier to understand and maintain. High cohesion is usually supported.”
So next time you are asking somebody to do something for you, see if he has the required information. If not, find somebody else that does. You want the job done well, right? Use an Information Expert for such a job.
ReferenceApplying UML and Patterns by Craig Larman, p221
It’s one of my favorite and most-referred to books. It’s one of 10 Books Every Java Software Engineer Must Own.
I hesitated posting this… The last thing I want is more red tape. However, after reading about code reviews in several sources, I am convinced that the reward is worth the price. The bottom line, code reviews improve code quality. While no silver bullet, they force us to write better code — knowing that somebody else will evaluate it makes us do it.
I have never been part of a company where code reviews worked effectively, but at the same time, if implemented properly into the development process, they have the potential to improve the quality code in a significant way.
What’s more, they enable cross-training programmers, mentoring, and enforcement of code conventions. Code reviews allow us to make sure that new people are “adopting” to “our” way of doing things, if there are any. They’re the extra guard to protect the most-valued property: code.
A lot of the prominent IT gurus, like Grady Booch, Jerry Weinberg, Cedric Otaku (those are sitting on top of my mind now), are big proponents of code reivews. I believe Weigers even wrote a book on the subject.
What prompted me to write this is an excellent blog entry by Cedric Beaust, Why Code Reviews Are Good For You, http://beust.com/weblog/archives/000393.html. He explains why it’s good and the different types of reviews. The following sums it up nicely:
“I strongly believe that projects that work without any peer review will end up with code of significantly worse quality, regardless of how talented or experienced the developers are. It doesn’t matter how good you are, you can’t produce top quality code all the time. We all get sloppy at time, and code reviews are here to address these times.”
I think we should consider implementing non-blocking code reviews. Let’s be honest, we all check in code that is sometimes sloppy, we could all use a little incentive to do better, and a lot of times we write code that only we can understand. Code reviews would be an improvement in this area.
How do we implement it? Good question. I believe that there should be some communication system in place. But the bottom line, each line of code should be looked at by somebody else and suggestions how to make it better should be requested of each reviewer (no heart feelings).
At my current job we have JIRA and SVN integrated, doing code reviews would be simple. Every SVN check in has to have a ticket ID. Before a ticket can be closed and the project released, every change has to be reviewed by somebody else and commented on. Before it can be closed, the reviewer would have to approve that the changes have actually been implemented.
We all strive to write good quality code whether we do code reviews or not, but it does not always happen. Knowing that our code would be reviewed would force us to do it every time.
ReferenceWhy Code Reviews Are Good For You, Cedric Otaku
RelatedCode Reviews, very good java.net article
A fairly common occurence I’ve come across in software development is that a class I’m working onchanges for various non-related reasons. For one type of change, I modify a portion of it, and for another, another portion. That’s not a good situation.
Martin Fowler calls this “divergent change” under the Code Smells category. He says thefollowing,
“Programs should be structured in such a way that we can make changes easily. When we make a change we want to be able to jump to a single clear point in the system and makethe change.Divergent change occurs when one class is commonly changed in different ways for different reasons. Ifyou look at the class and say, “Well, I will have to change these three methods every time I get a new database; I have to change these four methods every time there is a new financial instrument,” you likely have a situation in which two objects are better than one. That way each object is changed only as a result of one kind of change.”
Robert Martin calls this principle The Single-Responsibility Principle: A class should have only one reason to change.
In this context, he defines responsibility as “a reason for change.” If you can think of more than one motive for changing a class, then that class has more than one responsibility. “It’s not easy to see that because we usually think of responsibilites in groups.”
What’s an example of a responsibility coupling? Martin gives a common violation of the SRP: Employee class containing business rules and persistence control. Business rules tend to change frequently, and persistence usually changes for completely different reasons. A clear violation.
Interestingly, Martin calls this principle one of the simplest, and at the same time, one of the hardest to get right. “Conjoining responsibilities is something that we do naturally. Finding and seperating those responsibilites from one another is much of what software design is really about.“
Thus, when adding new functionality to a class, I think it’s important to keep in mind that they don’t violate the Single-Responsibilty Principle. This has a side effect of keeping your classes cohesive. And you knowthat is a good thing.
Once again, if over time you make changes to a class that touch completely different parts of the class, you have a violation of the principle. Split the class in two. Put the parts that change together into their own class. You’ll be glad that you did.
ReferenceMore Info on SRPSingle-Responsibility principle is a fundamental principle in software design. It is a good idea to”embed” it into your software development knowledge. http://www.objectmentor.com/resources/articles/srp
Refactoring, Martin Fowler’s influential and still relative book on refactoring (Code Smells section is invaluable).
Agile Software Development, Robert Martin’s book on patterns, a great book. He talks about fundamental patterns in OO development. A must read.
In an object-oriented world, special exceptions are evil. To me, they ruin a well-structured framework/project. Yet in the business world, they are fairly common. What do you do?
I think the worse thing you can do is to actually add a special exception to a special-case free project. Once you do that, your project will take a downhill drive towards unmaintainability.
Let’s say that you have a nice inheritance and polymorphism in place: a well-structured OO system. To be more specific, let’s say you have a base class Shape and a Circle and a Square as subclasses. Everything works nicely: you only care about the Shape class and everything else takes its polymorphic runtime form.
Then, a business person comes in, with the usual time pressure, and asks you to implement something that resembles a Shape but it works a little differently. What do you do? You don’t want to spend some extra time to refactor the original structure. And you don’t want to implement a new structure as well — too time consuming.
So what do you do? You add a special exception: you create a special-cased Shape. From now on, whenever you use the Shape object, you add the special exception to make sure something different is performed. Just a few lines of code. Everything works. You’re happy. You’re done. Quick.
But you did something else. You just ruined a well structured OO project. From now on, anytime you use the Shape object, you have to duplicate the special exception. It’s only a matter of time when somebody forgets to do that. Ooops. A bug is let into the system. You created the opening with the special exception.
What else did you do? A level of frustration to the maintainer. The system is much more difficult to maintain after that.
Never do that! Take the time to do it right. Never put a special condition to a perfectly working OO system (with inheritance and polymporphism). Unless, of course, you don’t care… and you consider yourself a crappy programmer.
I like the following saying: If you don’t have the time to do it right, will you have the time to do it over?
You save some time at the time of implementation, but you will pay for it several times later.
So, anytime you need to add a special condition, and it’s inevitable, refactor the code to support that, but don’t add a special condition. It never works.
A better coder is a happy coder, don’t spoil that.
Writing good OO code is not easy. Here’s a set of rules of thumb when creating classes. These are taken from the Object-Oriented Design Heuristics book by Riel — good stuff.
2.2 Users of a class must be dependent on its public interface, but a class should not be dependent on its users.
2.3 Minimize the number of messages in the protocol of a class.
2.4 Implement a minimal public interface that all classes understand [e.g., operations such as copy (deep versus shallow), equality testing, pretty printing, parsing from an ASCII description, etc.].
2.5 Do not put implementation details such as common-code private functions into the public interface of a class.
2.6 Do not clutter the public interface of a class with things that users of that class are not able to use or are not interested in using.
2.7 Classes should only exhibit nil or export coupling with other classes, that is, a class should only use operations in the public interface of another class or have nothing to do with that class.
2.8 A class should capture one and only one key abstraction.
2.9 Keep related data and behavior in one place.
2.10 Spin off nonrelated information into another class (i.e., noncommunicating behavior).
2.11 Be sure the abstractions that you model are classes and not simply the roles objects play.
ReferenceObject-Oriented Design Heuristics, Riel
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.