Showing posts with label OOP. Show all posts
Showing posts with label OOP. Show all posts

Thursday, April 30, 2009

Sharing information within organizations

Naresh Jain tweeted code reuse being still an unsolved problem within organizations some days ago. This made me think that this is a symptom of a more general problem within organizations, who do not account for information and knowledge transfer costs.

I’ve seen a few attempt to promote reuse within organizations, and they all failed because they assumed a non realistic communication model within the organization. In some cases the approach was completely naive: just because some code had been written to address a specific problem, everybody was supposed to know about this code. There's only one organization capable to achieve such level of coordination: it's called "
The Borg". They have a collective intelligent and are continuously in sync, one and another.
This type of information sharing simply does not happen in nature.


A more sophisticated approach involved use of repositories and/or knowledge management system to promote information sharing in a common tool. I've seen most of these approach fail as well. Having a common repository to share the information is generally a good idea, but expectations on those systems were really high, and probably unreasonable.

The starting point to promote code reuse within an organization is to know that there is some code that already solves your problem. From a communication perspective we have Developer A, a potential
writer of an information at time T0 who knows something about what he's currently doing. Some times later, or maybe simply somewhere else, we'll have Developer B with a similar problem, at time T1. To have a successful communication:
  • A should have written something meaningful about the problem he solved
  • B should have searched the repository for an existing solution
  • B should have found what A wrote
  • B should have recognized that what A said was relevant to his problem
I think most of these steps are inherently non-trivial, basically because there is a huge amount of arbitrary decisions in every step (including whether to do the step or not). Words used by A might be different from words used by B to search. Or the information might be filed under an arbitrary label. Basically, this is a decoupled asynchronous communication. There's no feedback possible, and every arbitrary decision is an obstacle between A and B.

I personally find structured systems for storing information particularly bad: they
force users to choose where to file their data, and the way people label their knowledge varies a lot form person to person and from time to time. Non-structured information repositories, such as Wikis with a Google-like search tool are definitely better, but they don't solve the core of the problem.

Sometimes we can connect our specific problem to a more general case, for example a "shortest path problem" or a "traveling salesman". This is probably how we'd call the problem after we've found the solution. The way we describe the problem before might be a lot different. Knowing how to call the problem is already a step towards the solution. This means also that who describes the problem and who describes the solution might use different terms. making our asynchronous-remote-decoupled communication at high risk of being completely ineffective.

Effective communication about partially unknown problems needs a higher amount of feedback. That's what we do when reading the menu in an ethnic restaurant: or (closer to our example) when we get into a shop to buy things we've seen but we don't know the name. A clerk might have a gotcha and tell us "Ah! you meant this!" showing us what we wanted and telling us how it's called. The most effective way to communicate about unknown things is the one with more feedback: face to face conversation.

Unsurprisingly, organizations trying to push communication through structured systems are often the ones that put a lot of efforts in preventing effective face to face communications to happen. Well ... in fact
preventing good things to happen is one thing organizations are good at. And effective communication is one of these fragile things which might happen in a good environment, but there's no way to force them to happen.

Friday, June 22, 2007

IDE refactoring capabilities

I had to spend some time recatoring some classes, working with Eclipse, a couple of days ago. I selected some code inside a long method, and went for an "extract method" refactoring. Good surprise! The IDE (I was using Eclipse, but I bet that IntelliJ IDEA has the leading edge here) also checked out the entire file looking for occurrences of the code portion that was cutted and pasted all over the place, and replaced all of the occurrences with the new method (whic was the part I was planning to do afterwards...) the net result was that a 20 minutes operation became a 10 seconds operation.

On al larger scale this has some interesting consequences: if you know what to do (if you have read and understood the first 70 pages of Martin Fowler's Refactoring), refactoring a large amount of crappy code is a lot easier that you might think, so its worth doing it in many more situations. To be effective you must anyway be confident on your team OOP capabilities, and on their IDE power user skills, being the former much more important - and harder to achieve - than the latter.

Friday, May 11, 2007

Things they wouldn't teach you of in college

I had an interesting conversation with one of my colleagues, a couple of days ago, about the best way to coach the newly hired developers who just graduated in university. He was doubtful about what to teach, since some of the technologies used in the project were new for him too.

Well, it's not about the technology, at all. A young, smart developer, can learn a new technology faster than I can do. He's probably already learned a couple of fashionable technologies for the thesis, still he desperately needs to learn all of the things that university doesn't teach (sometimes, doesn't even mention) but that are vital for becoming a good developer, or a good IT consultant.

So I started thinking about some posts, hoping that they could be meaningful or useful for the case...

The test of time
A student can write code. Can also solve difficult coding puzzles. But writing good code is another stuff. The main reason for this, is that coding for an exam is a pretty simplified job compared to coding for production (which is the typical developer's stuff).
Think about the context:
  • you are given a task (sometimes you can even choose it)
  • you are given some constraints
  • you can work alone, sometimes in a team
But the most important question is: "What happens after I deliver the code?" and the answer is ... nothing. Well, nothing, unless you fail the exam. But the point is that in the university there is no such thing as the maintenance phase. Your code lasts the time of an exam (it's like a butterfly, in a way...) and then it's gone. Will you ever need that code again? I bet not.

So you're missing a big part of what the code is for, which is users and colleagues. The former will ask you to change how the code works, the latter the way the code is written. More about this in the next posts.

Tuesday, May 02, 2006

Default Constructor: a possible solution


I finished my last post grunting like an angry old man. Time to stop whining and start proposing something. Ok, here’s what I do. As a rule in my projects, I mark parameterless constructors in domain classes as @deprecated. This way I can monitor bad coding habits without affecting frameworks that need to access the default constructor. This normally raises questions so I have a chance to explain to developers why I consider it an anti-pattern and to find a solution (normally a robust constructor or a factory).

Another possible solution is to make it a check in source code quality checkers such as checkstyle, this approach eases the burden of manually adding the deprecation comment in all the classes, but requires the team to be familiar with the tool, while deprecation should already be in every developer’s scope.

Tags: , ,

Tuesday, April 25, 2006

Why I hate the default constructor


Hmm, I think I should provide a more detailed (boring) explanation on the reasons why the default constructor is in the list of my most hated anti-patterns.

Back to basics
OO theory provided us with the gift of encapsulation: the ability to hide details of the internal structure of an object by providing access control to attribute and methods thus allowing to split the exposed behaviour of an object (its interface) from the internal structure (the implementation).

The rule of thumb says that you should define all of your attributes private, and then provide public methods for the interactions with other classes. It’s a common practice (a short way to say that I quite disagree with that, but this will drive me out of scope) to provide also public methods to access the properties of the object, in a JavaBeans like fashion.

JavaBeans specification
JavaBeans specification defined that a special category of java objects, the Beans, was identified by the following properties
  • presence of a public parameterless constructor

  • presence of public methods to access properties of the object, such as getters and setters in the form of getPropertyName() and setPropertyName(…)
Plenty of discussions arose on the subject “is JavaBeans specification breaking encapsulation?” arguing that making attributes public would have had the same effect.

Unfortunately, what most of the developers forgot was that java beans specification were meant to be used by tools like IDEs (one of the first implementation of the spec was used to add user defined graphics object in a graphical environment, so that you could create your components and add them to the JBuilder palette) or frameworks like Castor or Hibernate. Java Server Pages also use Java Beans as the underlying object for the pages. Java Beans specification allowed tools to dynamically access properties of given (and unknown) objects by relying on introspection, driven by the coding conventions mentioned above.

Having a commonly accepted syntax for accessor methods, was a good result indeed, but was largely abused. But this gave new popularity to the empty constructor anti-pattern.

Why is the empty constructor evil?
Ok, I need a basic example to start from. Suppose we have a simple class like this:
public class Person {

private String name;
private String surname;

public Person() {}

public String getName() { return this.name; }
public String getSurname() {return this.surname; }

public void setName(String name) { this.name = name; }
public void setSurname(String surname) { this.surname = surname; }
}

By creating an empty object, and
then setting its property in a
Person p = new Person();
p.setName(“John”);
p.setSurname(“Smith);
fashion, we make a series of mistakes. At the end of the execution the result is just like
Person p = new Person(“John”,”Smith”);
assuming that we defined in Person.java a constructor like
Public Person (String name, String surname) {
this.name = name;
this.surname = surname;
}
But unfortunately the result it’s not the same during the execution. In other words object initialization is not atomic in the former case, while it is atomic in the latter. Moreover, the second constructor encapsulates creation logic, knowing that you need both name and surname to have a fully functional Person object. Using the default constructor, anybody trying to initialize the class should be aware of the internal details of the Person class to initialize the class.

Suppose then that you need instances of your class in different areas of your software. Every time, you should create your objects in the correct fashion. To do so, you normally would use the best replacement for OOP: cut & paste (which is a form of reuse after all…). Suppose then that you need to add an extra attribute to the Person class, namely birthDate, and that this attribute is required. Guess what? Changing the robust constructor to
public Person (String name, String surname, Date birthDate) {
this.name = name;
this.surname = surname;
this.birthDate = birthDate;
}
raises compilation problem on every invocation of the constructor. Is this a bad thing? Not at all! It allows you to correct every single invocation. It can be a simple job, or a tricky one (if the newly needed parameter is not so easy to get), but it ensures that the object is in the correct state. The other way round raises no compilation error, you know that you have to correct the code anyway, so you have the following options:
  • search every instance of new Person() throughout the code base and check that all the three setters are called (do you think that it’s fastest than fixing the compile errors?)

  • search some known instance of new Person(), add the new setter, and have a coffee

  • add the setter where we need it and let somebody else deal with the nullPointerException they are 99% likely to get.
Conclusion (where I explain my bitter mood)
What really puzzles me is that, every in the simplest situation, invoking the default constructor is almost always wrong! If your class has attributes, then you should favour a robust constructor instead, and makes you write less code. If it doesn’t have one, then maybe you don’t need a constructor at all but you could access static methods or use a factory to create your object. The only reason why we abuse so much this anti-pattern is just because we are damn lazy.

Tags: , ,

Monday, April 24, 2006

I hate the empty constructor


I was looking for inspiration for a short post about the abuse of the parameterless constructor. Then I found this and thought that there’s not so much else to say. If there is still somebody still convinced that

Person p = new Person();
p.setName(“John”);
p.setSurname(“Smith”);

is still as good as

Person p = new Person(“John”,”Smith”);

…please leave a comment.

Ok, then I thought this was a little bit too short, and wrote down some more explanation in the following post.

Tags: ,

Thursday, February 16, 2006

Type Checking and Code Smells


I’ve been caught for a while in the endless debate between strongly typed languages, such as Java, and loosely typed languages, such as Python. The main question could roughly be reduced to “is strong type checking worth the price?”, for python supporters the answer is clearly “No!”, cause the java syntax burden is not bringing so much of a value. I usually am a strong supporter of a strong type checking (even if I never used smalltalk, for me everything is an object) but in most java projects I’ve seen, strong type checking was never enforced, so developers were just dealing with a heavier syntax without enjoying its benefits.

Testing can introduce some safety degrees at deployment and release time, ensuring some more confidence on the produced code, but in this way you’re supposed to introduce a full-featured test suite, to really confident on software stability in the long term. But type checking was really meant with another goal: bullet proof (or fool proof) design. The best design example I remember, was the 3,5” floppy: even if it approximately looked like a square, it was not; and there was only one way it could be inserted in the slot (unless you were really creative, of course…). I used this metaphor a lot of times when teaching Java and OOP, but I am starting to wonder if it’s any more valid.

I usually get extremely suspicious (and worried, if it’s a project I am working on) when I see two things in code: empty constructors (and a lot of setters) and a huge list of String attributes. These two smells often came along, so the resulting aroma is a perfect blend. Ok, one thing changed from some years ago: a good IDE now shows more and more information about attributes and parameters, so – sometimes – the pessimistic control offered by strong type checking, can be surrogated by an optimistic naming convention (after all developers are supposed not to be that stupid). Still this is not an argument that can save empty constructors (and the resulting partially instantiated objects) from being intrinsically evil, and I can’t believe that none of those String attributes is a potential class.

But to really get some benefit from a more OO refactoring of the code you need behaviour, and if you’re pushed between a presentation framework, which doesn’t enforce OO data, such as Struts, and a lazy coded DAO layer, there’s not so much behaviour left to add to your classes, so – like an old man that feels out of fashion – I would look at all those String attributes in the code, and feel intimately disgusted, but then instead of invoking a refactoring session I’d rather have a glass of wine, thinking that the old times were better…

An article on the Python vs Java debate by Bruce Eckel
Martin Fowler's code smell "Data Clump"

and ConstructorInitialization


Tags: ,

Tuesday, January 24, 2006

MDA Skeptic - part 4: Raising the level of reuse


Functions were probably the first widely adopted element of software reuse. Developers loved them because functions made them save their own time, but in a way reuse scope was limited by the application boundaries. OOP promised to increase reuse across the boundaries of a single application, and made it easier to share reusable units between the development team. Still we saw many attempts to build company assets of reusable objects, that simply didn’t succeed. Apparently this was due to the underestimation of two factors:
  • the communication costs of sharing the knowledge

  • the need of a company support, to make developers choose learning somebody else’s code, instead of writing their own.
There’s a bit of game theory in it: every developer could agree that OOP is a good thing, still 99% of the times
  1. coding looks faster than learning

  2. it’s certainly more interesting (developers simply love starting from scratch)

  3. Damn! I can write better code than this!...

Ok. Let’s get back to MDA, here the reuse is aimed to a higher level: platform independence, portability of the model between applications and technologies. To me, it just looks like that the required time to enjoy the positive effects are longer than in other evolutionary steps, and that advantages are expected mainly at company level, while singles and teams are carrying the heavy burden of the adoption threshold (learning curve and so on) without an immediate and/or personal reward. My personal experience (and maybe there is some typical Italian mood here) is that changing people’s attitude is a lot harder when benefits are targeted at a higher level than singles, or small groups.


Tags: , ,

Sunday, January 15, 2006

MDA Skeptic - part 3: impact on code


A lot of emphasis has been put on the fact that MDA tools could be used to generate pattern code, straight from the model. The one thing that is puzzling me is that in a full MDA scenario this is useless. Patterns are a great way to clean your design, and to define the proper responsibilities to the components. But they do so having 2 good weapons.
  • Readability: the code looks cleaner and clearer,

  • Ease of (re)use: further evolutions are easier because the pattern structure defines the place where to work, when you need to add or change something.
They both are valueless in a MDA approach: the code is not written, but is generated so it won’t make a big difference if it’s cleaner or not, the edit point is in the Model, or in the Mapping, not in the generated code. Of course, generating the correct patterns would be fine in a one-shot MDA approach (which I tend to dislike, ‘cause will deviate from the model anyway), but the good point of MDA is exactly the one of keeping the model in sync with the code, the full MDA roundtrip.

We can probably expect specific MDA patterns to arise in this context, as long as MDA adoption gets wide enough, but design patterns (and architectural patterns as well) look too rooted in the traditional development process. If we move the focus on the definition of the model, then readability, and maintenance cost are no longer key factors, as – for example – performance might be. Possible candidates for being popular patterns in this new context are likely to be the Analysis Patterns collected by Fowler some years ago.

Tags: , , ,