Today I have worked on my project in Java to make a refactoring of a class named TableUtil. First I decided to refactor it to Factory Method but I found out that TableUtil class depends on many small independent classes. These small classes are not so well implemented and I need of a new strategy for code refactoring. I realized that it’s very hard to refactor a core class because it depends from many small and independent classes. These independent classes could be named leaves and the core class could be named the root of the tree. So if you imagine the picture it’s very easy to start tackling with the complexity from the leaves instead of the root. Briefly we need to work on small steps from the periphery of the complicated code to the center of the problem!
8 thoughts on “Rumbling : How to refactor existing code ?”
In some similar cases, I put the troublesome code into an “interface layer” (or proxy class) to solve my immediate problem(s). This allows me some level of high level “refactor-ability” without having to rewrite it all at once if at all. I only use technique when the code base in question is considered “third party.” This technique might be called “Bury The Problem”.
When refactoring my own code, I know that the “Bury The Problem” technique will always come back to burn me later.
Thanks Mike this is an interesting idea. I haven’t thought about “Bury The Problem” technique. It’s wonderful idea to “bury the problem” and separate the tidy part from the other, when the time isn’t enough to refactor the code!
Obviously “TableUtil” is utility class and the code behind it is with “quality of utility class” – it’s common to see utility classes with poor quality of code. Usualy I made some kind of “facade” upon this kind of code – that way my code will be prevented from “code smells” that exists in the utility class or classes. When ( if ) I have enough time I refactor the “utility class”. The important thing by my opinion is to isolate bad code from your code and refactor the bad code when I ( If I ) have time.
“The Facade is not enough” … 😉
I want to extend my previous post a bit.
The idea there is pretty straight forward, but in some cases this is not enough.
Currently I deal with a low-level “utility class” that is so bad, that it raises exception from time to time – not all the time – just this class in some cases requires data that I can’t ( or I don’t want ) provide to it. In this situation making a “facade” around this class is not enough. Just because with or wothout “facade” around this class I don’t want to ( or I can’t ) provide some data to it. What I can do in this situation – not much – I have to inherit this class, override the method that I want to use ( this method is protected ) and catch the exceptions that can occur. This is a long way – I use “facade” and I use inheritance to mask the bad behaviour of this class.
So generaly speaking masking bad code in “utility class” is 2 step process:
1. create “facade” around this classes if they are more than one.
2. if there are cases that the facade is not enough, inherit the “bad” class and use the descendant in the facade.
These steps can be implemented “one-by-one” – first make “facade”, use it in your own code during debug to see if this facade masks the problems in “utility classes” well. If you find situations where the “facade” is not enough, inherit the “bad class” and use it’s descendant in the facade.
Hi Stancho :D! You are right. But don’t you think that we postpone the problem on this way ? Where is the border when we have to refactor the problem and when to bury the problem ? If I follow the Toyota Way practices I will stop and fix the problem. No matter whether it will take me a lot of time! These question make me think and make a research on the problem and write a new post. 😉
Don’t speculate !
“Time, quality, cost – choose two” paradigm drives the software development in these days. The cost and time are most important for people that pays for software development, so “cost and time” are chosen not by the developer, but the developer must deal with them and usually can not break them ! As this paradigm is wrong for software quality in most cases it is followed by other methods for achieving good software quality:
– from the manager’s point of view it is good to use “agile” software development methods and make the software system accessible ( and usable ) from the customer long before the system development is finished in it’s whole – this is little “not very honest to the customer” principle during the development process, but with good organization of this process at the end both sides will be happy.
– from the developer’s point of view – “Release It !” is very important principle. “Make it work” and after that “Make it work better” and after that “Make it work intelligent way” and after that…
If for the customer time and cost are so important the development will finish just with “Make it work” phase. After the customer has a usable working system it can decide to spend more time and money the system to became better.
Software development is engineering process, so it is a process of compromises – the good developer knows ( predicts ) which compromises should be made.
Ok, Stancho! I am agree with you but don’t you think that the choice of time make us to build a house of straw ? I can’t find the margin for my self ? Where is the margin between a house from straw and a house from bricks? What is the rule which we can use ?
Stancho is correct:
Smelly code base + Facades = “Bury the problem(s)” until there is time to fix things.
Most often, time isn’t allocated for this. A Facade then offers a cleaner interface plus more predictable behavior: fix the code that the Facade’s features expose and you should have higher reliability over top of poorly written/architected code base.
This does fall squarely in the “make it work; then make it work better” approach. This is a concept that more junior programmers don’t understand so well. Either than want it perfect the first time (thus never releasing the work) or they get it working, call it “done” and never make it work better. More senior developers understand both parts of this two part rule and use it to advantage. (But beware the premature demo…)
Until I write perfect software against perfect (written) requirements in a perfect environment, I’ll continue to use this iterative principle of software development.