Compare hotel prices and find the best deal - HotelsCombined.com

Friday, August 1, 2014

5′ on IT-Architecture: three laws of good software architecture

The issue with architectural decisions is that they effect the whole system and/or you often need to make them early in the development process. It means a lot effort if you change that decision a couple of months later. From an economic standpoint architectural decisions are often irrevocable. Good architecture is one that allows an architect to make late decisions without superior effect on efforts and costs. Let’s put that on record.
Law 1: Good architecture is one that enables architects to have a minimum of irrevocable decisions.
To minimize the set of irrevocable decisions the system needs to be responsive to change. There is a major lesson I have learned about software development projects: Nothing is permanent except change. The client changes his opinion about requirements. The stakeholders change their viewpoint of what’s important. People join and leave the project team. The fact that change alone is unchanging leads me to the second rule of good architecture, that is:

Law 2: To make decisions revocable you need to design for flexibility.
This is the most provocative statement and I am having controversial discussions here. The reason is that flexibility introduces the need for abstraction. Abstraction uses a strategy of simplification, wherein formerly concrete details are left ambiguous, vague, or undefined (from Wikipedia). This simplification process isn’t always simple to do and to follow for others in particular. “Making something easy to change makes the overall system a little more complex, and making everything easy to change makes the entire system very complex. Complexity is what makes software hard to change.” from M. Fowler) This is one core problem of building good software architecture: Developing software that is easy to change but at the same time understandable. There are several concepts that try to tackle this paradox problem: design patterns and object oriented design principles. Polymorphism, loose coupling and high cohesion are flexibility enablers to me.

Law 3: To make use of flexibility one needs to refactor mercilessly.
Flexibility is not an end in itself. You need to actively make use of flexible design. If something is changing and it makes a previous design or architectural decision obsolete you need to go into the code and change the software. Otherwise the effort of building flexible software is useless and technical debt may cause late delays and a maintenance nightmare. The fact that you take rigorous action on your code base requires continuous feedback about the qualities of your software. To be able to refactor it is therefore essential that the code base is covered by a sufficient amount of automated tests. In an ideal scenario everything is integrated into a continuous integration environment to receive permanent feedback about the health of your code base.

14 Code Refactoring smells you can easily sense and What you can do about it?

This post is specifically intended to Project Managers although developers and testers can also get reasonable inputs from this post.  Generally projects tend to accumulate a lot of technical debt over time if refactoring is not applied and if good coding practices are not followed.  It is imperative that as a Project Manager you should understand this and deal with it effectively.  This is especially true in an Agile Project, where there is constant delivery of features and you would be surprised how quickly code quality can take a beating in if proper measures are not taken.  So what are the signs you can observe that your project’s code needs refactoring and what you can do about it?

Team is taking more time than expected to deliver features

This is probably the number one smell that a Project Manager can look out for in a project.  As a Project Manager you sense that a certain feature should not take so much time, yet it takes that time.  You talk to the team and they often give you a detailed explanation of how much change the feature needs to undergo and how it affects other features.  That is one of the sure smell that indicates that the code needs refactoring

Plenty of bug fixes after delivery

On one end, the code delivery is being delayed and at another end, there will be a lot of bugs too after delivery.  If you have observed this, then it is a sure sign that your project’s code needs refactoring.

Build Quality is on a decreasing trend

This is one of the excellent smells that surely indicate the need for refactoring.  If we try to build on bad code, the code quality will get reduced and this trend continues till we attempt to put a stop to it.  If you observe this as a Project Manager, then you need to put a stop to it.

Team is increasingly frustrated to make changes in code

Team get frustrated with making changes to the existing code as they worry that it might break some other parts of it.  If you observe this, you can be rest assured that the code needs refactoring.

Team is reluctant to touch certain areas of code

Some areas of code is better left untouched, that is a classic case of legacy code.  You can surely tell that we need refactoring if the team is reluctant to touch certain areas of code.  If you observe this, you can be pretty sure that code area is brittle and team lacks confidence in it.  However if refactored, things can be improved.

Team members are very comfortable with working in their respective modules

This may not be true in all cases, but it is true in some.  Team members are very knowledgeable in their area of code, and even though their modules contain bad code they know the tweaks of the code and can effectively hack it away to make the changes.  Although this may not be The sign, it does tell you the fact that things are probably not that right and it needs some action.

Team members are reluctant to give estimates (Even tentative ones) to make changes

When you are reasonably sure of the architecture and code design, you can give more or less good estimates or at the very least dare to provide estimates.  But in case of code that needs refactoring, the team members will be reluctant to give estimates because they are not sure of the impact that it might have on the other areas.

Team members often have the opinion that starting fresh is better than working with the existing code

If any of your team members feel this, then surely you need to take a big decision or at least start refactoring.

Team members often ask for extra time to refactor code

As a project manager, you need to often look for this cue as team members know that they are trying to deliver on time, but could not due to the quality of the code.  So they ask for that extra time for refactoring the code.  If that extra time is not allocated, then it ends up messing up the things further and will cause further damage to the code quality.

Team members take long time to debug a problem

This is also another sign that the code needs refactoring.  Usually when the quality of code is not good, it takes a lot of time to find where exactly the bug occurred and takes a lot of time to fix it as well.  If you observe this, you need to definitely take a closer look and have the team analyze the root cause for this.  Invariably it will be lack of refactoring.

Fixing bugs invariably introduces other new bugs

When the code quality is not good, fixing bugs in one place tends to open up new bugs in other places/areas of code.  This is a good sign that the code needs refactoring.  If you observe this, you can be sure that the code is very brittle and needs refactoring.

If you try to read the code and find out that it is not readable

You might not be technically adept at all programming languages.  But if you read through the code and find that you find lots of
  • Unreadable code
  • Long methods
  • Long parameter lists
  • Inappropriate variable names & method names
These are some simple checks and sure signs that the code needs lot of refactoring.

If team members are making same changes in multiple places

One of the common characteristics of code that is not refactored is that there tend to be lot of duplicate code across the areas.  If that is the case, even a small change will need to be applied to all those areas resulting in duplicate effort.  So if the team members complain of making same changes in multiple places, then there is a good chance that the code needs refactoring.

If all or most of your tests are covered by functional testing

When code is not very well designed, it can’t be driven by unit tests or unit integration tests.  So you end up making all your test coverage at the functional level.  This is a sure sign that your code design needs refactoring.
So now you have sensed that something is wrong and your code needs refactoring.  So what you can do about it?
  • Discuss with the team and find out where they are stuck and why they are stuck
  • Ask them to do a root cause analysis
  • If the team is not able to figure it out in the worst case, hire an external consultant who can give valuable insights/feedback
  • Identify critical areas that needs to be refactored the most
  • Put up a plan for Refactoring
  • Start with refactoring them
From a Project Manager’s perspective, Refactoring old code is an overhead but you need to treat it like an investment for the future and a means of improving Agility of the team.  So what you can do to refactor existing code.  Here are some ideas.

Refactor Sprint

Have a sprint dedicated to Refactoring.  This might be difficult to pull off due to business reasons, but if you can pull this off this is a worthwhile investment.  You will be surprised how much code you can end up improving in a sprint duration.

Refactor Week

If not an entire sprint, try for at least a weeks time for refactoring.  It will save you some amount of effort later on.

Refactor Day

This can be introduced once in a while when you feel equally bogged down by pressures of deadline and yet you want to accomplish decent quality.

Refactor Hour

If you can’t dedicate long periods of time for refactoring, dedicate an hour every day for Refactoring.  Also ensure that this hour is used only for refactoring and not for any other activity.  Once you do this for a couple of sprints, you will quickly start to realize some benefits, depending on the size of the project.

Make it a habit

Educate the team to make refactoring a regular habit along with coding.  Team needs to understand that the extra time investment is really worth it as it will make all future changes much easier.

Agile Engineering Best Practices

Try to follow Agile Engineering best practices like Automated Unit Tests, TDD which naturally emphasizes Refactoring.
The idea is to give a start to the Refactoring activities and make small regular improvements to the code.  By making it a habit, you can easily keep check of the code quality and can utilize the time and effort gained (later on) for something more meaningful.
Do you think there any other refactoring smells that you sense?  If so, please shoot out your comments.  If you found this post useful, please share it with your circles.  You can stay updated with the latest blog post by simply submitting your email id to the right in the “Get Updates by Email” section.

What Refactoring is, and what it isn’t

Sometimes a programmer will come to me and explain that they don’t like the design of something and that “we’re gonna need to do a whole bunch of refactoring” to make it right. Oh Oh. This doesn’t sound good. And it doesn’t sound like refactoring either….
Refactoring, as originally defined by Martin Fowler and Kent Beck, is
A change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior… It is a disciplined way to clean up code that minimizes the chances of introducing bugs.
Refactoring is done to fill in short-cuts, eliminate duplication and dead code, and to make the design and logic clear. To make better and clearer use of the programming language. To take advantage of information that you have now but that the programmer didn’t have then – or that they didn’t take advantage of then. Always to simplify the code and to make it easier to understand. Always to make it easier and safer to change in the future.
Fixing any bugs that you find along the way is not refactoring. Optimization is not refactoring. Tightening up error handling and adding defensive code is not refactoring. Making the code more testable is not refactoring – although this may happen as the result of refactoring. All of these are good things to do. But they aren’t refactoring.
Programmers, especially programmers maintaining code, have always cleaned up code as part of their job. It’s natural and often necessary to get the job done. What Martin Fowler and others did was to formalize the practices of restructuring code, and to document a catalog of common and proven refactoring patterns – the goals and steps.
Refactoring is simple. Protect yourself from making mistakes by first writing tests where you can. Make structural changes to the code in small, independent and safe steps, and test the code after each of these steps to ensure that you haven’t changed the behavior – it still works the same, just looks different. Refactoring patterns and refactoring tools in modern IDEs make refactoring easy, safe and cheap.
Refactoring isn’t and end in itself
Refactoring is supposed to be a practice that supports making changes to code. You refactor code before making changes, so that you can confirm your understanding of the code and make it easier and safer to put your change in. Regression test your refactoring work. Then make your fix or changes. Test again. And afterwards maybe refactor some more of the code to make the intent of the changes clearer. And test everything again. Refactor, then change. Or change, then refactor.
You don’t decide to refactor, you refactor because you want to do something else, and refactoring helps you do that other thing.
The scope of your refactoring work should be driven by the change or fix that you need to make – what do you need to do to make the change safer and cleaner? In other words: Don’t refactor for the sake of refactoring. Don’t refactor code that you aren’t changing or preparing to change.
Scratch Refactoring to Understand
There’s also Scratch Refactoring from Michael Feather’s Working Effectively with Legacy Code book; what Martin Fowler calls “Refactoring to Understand”. This is where you take code that you don’t understand (or can’t stand) and clean it up so that you can get a better idea of what is going on before you start to actually work on changing it for real, or to help in debugging it. Rename variables and methods once you figure out what they really mean, delete code that you don’t want to look at (or don’t think works), break complex conditional statements down, break long routines into smaller ones that you can get your head around.
Don’t bother reviewing and testing all of these changes. The point is to move fast – this is a quick and dirty prototype to give you a view into the code and how it works. Learn from it and throw it away. Scratch refactoring also lets you test out different refactoring approaches and learn more about refactoring techniques. Michael Feathers recommends that you keep notes during this on anything that wasn’t obvious or that was especially useful, so that you can come back and do a proper job later – in small, disciplined steps, with tests.
What about “Large Scale” Refactoring?
You can get a big return in understandability and maintainability from making simple and obvious refactoring changes: eliminating duplication, changing variable and method names to be more meaningful, extracting methods to make code easier to understand and more reusable, simplifying conditional logic, replacing a magic number with a named constant, moving common code together.
There is a big difference between minor, inline refactoring like this, and more fundamental design restructuring – what Martin Fowler refers to as “Big Refactoring”. Big, expensive changes that carry a lot of technical risk. This isn’t cleaning up code and improving the design while you are working: this is fundamental redesign.
Some people like to call redesign or rewriting or replatforming or reengineering a system “Large Scale Refactoring” because technically you aren’t changing behavior – the business logic and inputs and outputs stay the same, it’s “only” the design and implementation that’s changing. The difference seems to be that you can rewrite code or even an entire system, and as long as you do it in steps, you can still call it “refactoring”, whether you are slowly Strangling a legacy system with new code, or making large-scale changes to the architecture of a system.
“Large Scale Refactoring” changes can be ugly. They can take weeks or months (or years) to complete, requiring changes to many different parts of the code. They need to be broken down and released in multiple steps, requiring temporary scaffolding and detours, especially if you are working in short Agile sprints. This is where practices like Branch by Abstraction come in to play, to help you manage changes inside the code over a long period of time.
In the meantime you have to keep working with the old code and new code together, making the code harder to follow and harder to change, more brittle and buggy – the opposite of what refactoring is supposed to achieve. Sometimes this can go on forever – the transition work never gets completed because most of the benefits are realized early, or because the consultant who came up with the idea left to go on to something else, or the budget got cut, and you’re stuck maintaining a Frankensystem.
This is Refactoring – That Isn’t
Mixing this kind of heavy project work up with the discipline of refactoring-as-you-go is wrong. They are fundamentally different kinds of work, with very different costs and risks. It muddies up what people think refactoring is, and how refactoring should be done.
Refactoring can and should be folded in to how you write and maintain code – a part of the everyday discipline of development, like writing tests and reviewing code. It should be done quietly, continuously and implicitly. It becomes part of the cost of doing work, folded in to estimates and risk assessments. Done properly, it doesn’t need to be explained or justified.
Refactoring that takes a few minutes or an hour or two as part of a change is just part of the job. Refactoring that can take several days or longer is not refactoring; it is rewriting or redesigning. If you have to set aside explicit blocks of time (or an entire sprint!) to refactor code, if you have to get permission or make a business case for code cleanup, then you aren’t refactoring – even if you are using refactoring techniques and tools, you’re doing something else.
Some programmers believe it is their right and responsibility to make fundamental and significant changes to code, to reimagine and rewrite it, in the name of refactoring and for the sake of the future and for their craft. Sometimes redesigning and rewriting code is the right thing to do. But be honest and clear. Don’t hide this under the name of refactoring.

Code Refactoring vs Architecture Refactoring

Introduction

Everybody knows the meaning of Refactoring; the base of Agile Programming, and the best way to continuously increase the code quality. But Refactoring is not always the same, two different categories can be defined:
  • Code refactoring
  • Architecture refactoring

Code refactoring vs Architecture Refactoring

The term Architecture Refactoring started to be used in the last years, bringing some confusion about its meaning and its difference with code refactoring. Someone could say that there is no difference, cause when refactoring the architecture is always a refactoring done at the level of the code. So let’s try to define the two types and focus on the differences:
  • Code Refactoring aims modifying the code without changing its behavior with the main scope of increase the overall software quality. One refactoring is usually a small task, but several refactorings applied to the code can considerably increase its quality. Several books have been written about code smells and refactoring patterns. Finally it exists automatic tools able to detect code smells (FindBugs, PMD, CheckStyle) and even do automatic refactoring (NetBeans IDE).
  • Architecture Refactoring aims changing the software architecture, reorganizing the existing code into new logical layers with the main scope of increase the overall software quality and surpass architecture/infrastructure limitations that critically mine systematic qualities as (for example) scalability, extensibility, evolvability, testability and robustness of the actual solution system. A major challenge of this kind of refactoring is trying to reuse as much as possible existing code, to avoid writing a new software. Use of automatic tools can be few help (maybe just to detect circular dependencies), here the most work will come from your brain and experience.
So, what is the difference? When refactoring code, we change the way the code is written, once when refactoring architecture we change the way the code is organized in logical layers and components.
To better describe the differences I would like to focus on the following aspects:
  • Project management
  • Development management
  • Documentation
  • Implementation Environment

Project Management

By the point of view of project management the difference is big. Code Refactoring is usually agreed within the boundary of the development team since the associated risk is low and the impacts can be easily controlled and validated.
Clearly it is not the same for Architecture Refactoring! An agreement from management is necessary to be able to start the task as the associated risks and cost of the task can be elevate. Follows a list of what to do and what not to do when speaking with your manager:
  • Do an high level planning before any discussion, you must have an idea of the work
  • List the attainable improvements against the actual limitation
  • Try to identify the ROI with quantifiable metrics (depending on the project but money is the most common)
  • If refactoring is too big, propose a migration planning
  • Create a small team, when revisiting the architecture is not easy to make more than 2 people working at the same time (at least at the beginning)
  • Never say that the actual version is not good!

Development Management

Code Refactoring is a task that can be done by any developer as many tools exist to assist its execution. But Architecture Refactoring needs a bit more of expertise, as developers need to speak a bit of Software Architecture to be able to understand the changes, and Software Architects need a matured experience and (in most of the cases) a lot of courage!
The Software Architect has the duty to organize all the necessary meetings with the team involved in the refactoring to share with them the philosophy and objectives of the refactoring. Differently from Code Refactoring, it is better to have a full vision of the final design before to start to work.
Finally be sure to preserve the actual source code, and in operational environment a plan B can be put in place, to grant normal deliveries of the tools in case the refactoring tasks will present unexpected difficulties that can delay the original planning. A plan B can be for example a small development team, working in parallel with the refactoring team, that will include in the actual system the most urgent new requirements targeted in the refactored architecture. This should be part of the migration planning defined with your management.

Documentation

Code Refactoring does not impact system documentation as Architecture Refactoring does. On top of all there are documents to be written as:
  • Migration planning
  • Motivation of the refactoring
  • Impact and cost estimations
And a list of existing documents will have to be modified as:
  • System design document
  • Enterprise Architecture document

Implementation Environment

Architecture Refactoring can have a huge impact on the implementation environment; for example it can be necessary to change the used IDE or build system, the continuous integration server, the test automation framework. It is better to analyze those impacts before to start the refactoring, to have a realistic idea of the cost of the task because an unexpected change in the implementation environment can arise great issues being discovered only in the final phase.

Conclusions

In my experience I had to face with several big Architecture Refactoring. Taking in consideration all the 4 described aspects helped me to finalize with success those tasks and to gain confidence with my management team. Finally, if you are a software architect I would like to mention another aspect, that is about personal feelings: Architecture Refactoring is not a proof of your mistakes or bad decisions, simply at a certain moment it becomes necessary and it can be the best way to challenge and confirm your skills.

Law of Demeter - Java examples

Summary: The Law of Demeter is discussed using Java source code examples.
Whenever you talk to a good, experienced programmer, they will tell you that "loosely coupled" classes are very important to good software design.
The Law of Demeter for functions (or methods, in Java) attempts to minimize coupling between classes in any program. In short, the intent of this "law" is to prevent you from reaching into an object to gain access to a third object's methods. The Law of Demeter is often described this way:
"Only talk to your immediate friends."
or, put another way:
"Don't talk to strangers."

A Law of Demeter Java example

Before getting into the theory, I think the Law of Demeter is best explained through a source code example, in this case, a Java example. Here then is a Java class which attempts to demonstrate what method calls are considered "okay" according to the Law of Demeter:
/**
 * A Law of Demeter example in Java.
 * Created by Alvin Alexander, http://devdaily.com" title="http://devdaily.com">http://devdaily.com
.
 * This is an adaptation of the source code example from the book
 * The Pragmatic Programmer.
 */
public class LawOfDemeterInJava
{
  private Topping cheeseTopping;
   
  /**
   * Good examples of following the Law of Demeter.
   */
  public void goodExamples(Pizza pizza)
  {
    Foo foo = new Foo();
     
    // (1) it's okay to call our own methods
    doSomething();
     
    // (2) it's okay to call methods on objects passed in to our method
    int price = pizza.getPrice();
     
    // (3) it's okay to call methods on any objects we create
    cheeseTopping = new CheeseTopping();
    float weight = cheeseTopping.getWeightUsed();
     
    // (4) any directly held component objects
    foo.doBar();
  }
   
  private void doSomething()
  {
    // do something here ...
  }
}
Now that you've seen the Law of Demeter in a Java example, here are the more formal rules for this law, as shown on the Wikipedia page:
The Law of Demeter for functions requires that a method M of an object O may only invoke the methods of the following kinds of objects:
  1. O itself
  2. M's parameters
  3. Any objects created/instantiated within M
  4. O's direct component objects
  5. A global variable, accessible by O, in the scope of M

The Law of Demeter - Bad examples
Just as it's helpful to see good examples of what you should do, it can also be helpful to see examples of what you shouldn't do in your code. Let's take a look at some "bad examples" of the Law of Demeter in Java.
In short, the Law of Demeter aims to keep you from doing things like this:
objectA.getObjectB().doSomething();
or even worse, this:
objectA.getObjectB().getObjectC().doSomething();
When you write code like this, not only are you exposing yourself to changes in the ObjectA class, you're also exposing yourself to changes that may occur in ObjectB and ObjectC as well. Here are just a few ways these calls make your class more fragile:
  • In the future, the class ObjectA may no longer need to carry a reference to ObjectB.
  • In the future, the class ObjectB may no longer need to carry a reference to ObjectC.
  • The doSomething() method in the ObjectB class may go away, or change.
  • The doSomething() method in the ObjectC class may go away, or change.
  • If the intent of your class is to be reusable, you can never reuse your class without also requiring ObjectA, ObjectB, and ObjectC to be shipped with your class. (This is referred to as "tight coupling", and you'll also hear the term "unnecessary dependencies".)

Forces

The Law of Demeter is a good practice to follow, and has the following positive benefits on the classes you create:
  • Your classes will be "loosely coupled"; your dependencies are reduced.
  • Reusing your classes will be easier.
  • Your classes are less subject to changes in other classes.
  • Your code will be easier to test.
  • Classes designed this way have been proven to have fewer errors.

Consequences

While there are many good qualities about the Law of Demeter, there are consequences to following this "law" as well:
  • If you truly need the doSomething() method of ObjectC, there are several possible solutions. The most clear solution is to require that ObjectC be passed in to your Java method.
  • A second solution is to create wrapper methods in your other classes, and this wrapper methods will simply pass your request on to a delegate. In this case, a large number of delegate methods can make your code larger and slower (albeit more portable and easier to maintain).