Asdfasf

Thursday, October 30, 2014

CC - What is Clean Code?

Ref: Clean Code by Robert C. Martin

Bjarne Stroustrup, 

inventor of C++and author of The C++ Programming Language

 

I like my code to be elegant and efficient. The logic should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations. Clean code does one thing well.
  • Elegant, Pleasing to read. Reading it should make you smile the way a well-crafted music box or well-designed car would. Straightforward, hard for bugs to hide.
  • Efficient, this should not surprise us coming from the inventor of C++
  • Does one thing well, Clean Code is focused.

Grady Booch, 

Author of Object Oriented Analysis and Design with Applications

 

Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer’s intent but rather is full of crisp abstractions and straightforward lines of control.

  • Readable like a well-written prose
  • It should contain only what is necessary.

“Big” Dave Thomas, 

founder of OTI, godfather of the Eclipse strategy

 

Clean code can be read, and enhanced by a developer other than its original author. It has unit and acceptance tests. It has meaningful names. It provides one way rather than many ways for doing one thing. It has minimal dependencies, which are explicitly defined, and provides a clear and minimal API. Code should be literate since depending on the language, not all necessary information can be expressed clearly in code alone.

  • Readable as makes easy other people can enhance it.
  • Dave ties cleanliness to tests. He is right, Code without test is not clean.
  • Minimal, Smaller is Better. 3S Rule: Small-Simple-Safe
  • Literate, in a form as to make it readable by human 

Michael Feathers, 

author of Working Effectively with Legacy Code

 

I could list all of the qualities that I notice in clean code, but there is one overarching quality that leads to all of them. Clean code always looks like it was written by someone who cares. There is nothing obvious that you can do to make it better. All of those things were thought about by the code’s author, and if you try to imagine improvements, you’re led back to where you are, sitting in appreciation of the code someone left for you—code left by someone who cares deeply about the craft.

  • One word, CARE. Michael hit it on the head. Clean code is code that has been taken care of. Someone has taken the time to keep it simple and orderly. They have paid appropriate attention to details. They have cared.

Ron Jeffries, 

author of Extreme Programming Installed and Extreme Programming Adventures in C#

 

• Runs all the tests;
• Contains no duplication;
• Expresses all the design ideas that are in the system;
• Minimizes the number of entities such as classes, methods, functions, and the like.



Ward Cunningham, 

inventor of Wiki,

You know you are working on clean code when each routine you read turns out to be pretty much what you expected. You can call it beautiful code when the code also makes it look like the language was made for the problem.

  • when you read clean code you won’t be surprised at all. Indeed, you won’t even expend much effort. You will read it, and it will be pretty much what you expected. It will be obvious, simple, and compelling

 

 We are Authors

The @author field of a Javadoc tells us who we are. We are authors. And one thing about authors is that they have readers. Indeed, authors are responsible for communicating well with their readers. The next time you write a line of code, remember you are an author, writing for readers who will judge your effort.

The Boy Scout Rule

It’s not enough to write the code well. The code has to be kept clean over time. We’ve all seen code rot and degrade as time passes. So we must take an active role in preventing this degradation.
The Boy Scouts of America have a simple rule that we can apply to our profession.
Leave the campground cleaner than you found it.

If we all checked-in our code a little cleaner than when we checked it out, the code simply could not rot. The cleanup doesn’t have to be something big. Change one variable name for the better, break up one function that’s a little too large, eliminate one small bit of duplication, clean up one composite if statement.

CC - Clean Code Matters

Ref: Clean Code by Robert C. Martin

Uncle Bob states why clean code matters with a story, I have experienced this story as a member of tiger team in my career and much probably you have too :

If you have been a programmer for more than two or three years, you have probably been significantly slowed down by someone else’s messy code. If you have been a programmer for longer than two or three years, you have probably been slowed down by messy code. The degree of the slowdown can be significant. Over the span of a year or two, teams that were moving very fast at the beginning of a project can find themselves moving at a snail’s pace. Every change they make to the code breaks two or three other parts of the code. No change is trivial. Every addition or modification to the system requires that the tangles, twists, and knots be “understood” so that more tangles, twists, and knots can be added. Over time the mess becomes so big and so deep and so tall, they can not clean it up. There is no way at all.
 
As the mess builds, the productivity of the team continues to decrease, asymptotically approaching zero. As productivity decreases, management does the only thing they can; they add more staff to the project in hopes of increasing productivity. But that new staff is not versed in the design of the system. They don’t know the difference between a change that matches the design intent and a change that thwarts the design intent. Furthermore they, and everyone else on the team, are under horrific pressure to increase productivity. So they all make more and more messes, driving the productivity ever further toward zero.

The Grand Redesign in the Sky

Eventually the team rebels. They inform management that they cannot continue to develop in this odious code base. They demand a redesign. Management does not want to expend the resources on a whole new redesign of the project, but they cannot deny that productivity is terrible. Eventually they bend to the demands of the developers and authorize the grand redesign in the sky. 

A new tiger team is selected. Everyone wants to be on this team because it’s a greenfield project. They get to start over and create something truly beautiful. But only the best and brightest are chosen for the tiger team. Everyone else must continue to maintain the current system.
 
Now the two teams are in a race. The tiger team must build a new system that does everything that the old system does. Not only that, they have to keep up with the changes that are continuously being made to the old system. Management will not replace the old system until the new system can do everything that the old system does.
 
This race can go on for a very long time. I’ve seen it take 10 years. And by the time it’s done, the original members of the tiger team are long gone, and the current members are demanding that the new system be redesigned because it’s such a mess.
 
If you have experienced even one small part of the story I just told, then you already know that spending time keeping your code clean is not just cost effective; it’s a matter of professional survival.

You will not make the deadline by making the mess. Indeed, the mess will slow you down instantly, and will force you to miss the deadline. The only way to make the deadline—the only way to go fast—is to keep the code as clean as possible at all times.

Here is a great post stating about why refactoring is better than rewriting, tiger team in Uncle Bob's story did.

Monday, October 27, 2014

PragProg - Unit Testing

Ref: The Pragmatic Programmer

The Software IC (Integrated Circuit) is a metaphor that people like to toss around when discussing reusability and component-based development.The idea is that software components should be combined just as integrated circuit chips are combined. This works only if the components you are using are known to be reliable.

Like our hardware colleagues, we need to build testability into the software from the very beginning, and test each piece thoroughly before trying to wire them together.

Chip-level testing for hardware is roughly equivalent to unit testing in software—testing done on each module, in isolation, to verify its behavior. We can get a better feeling for how a module will react in the big wide world once we have tested it throughly under controlled (even contrived) conditions.

A software unit test is code that exercises a module. Typically, the unit test will establish some kind of artificial environment, then invoke routines in the module being tested. It then checks the results that are returned, either against known values or against the results from previous runs of the same test (regression testing).

Why do we go to all this trouble? Above all, we want to avoid creating a "time bomb"—something that sits around unnoticed and blows up at an awkward moment later in the project.

TIP 48: Design To Test

By making the test code readily accessible, you are providing developers who may use your code with two invaluable resources:
  1. Examples of how to use all the functionality of your module
  2. A means to build regression tests to validate any future changes to the code
All software you write will be tested—if not by you and your team, then by the eventual users—so you might as well plan on testing it thoroughly. A little forethought can go a long way toward minimizing maintenance costs and help-desk calls.

TIP 49: Test Your Software, or Your Users Will.

PragProg - Refactoring

Ref: The Pragmatic Programmer

Change and decay in all around I see …
H. F. Lyte, "Abide With Me"

As a program evolves, it will become necessary to rethink earlier decisions and rework portions of the code. This process is perfectly natural. Code needs to evolve; it's not a static thing.

Rather than construction, software is more like gardening—it is more organic than concrete. You constantly monitor the health of the garden, and make adjustments (to the soil, the plants, the layout) as needed.

Business people are comfortable with the metaphor of building construction: it is more scientific than gardening, it's repeatable, there's a rigid reporting hierarchy for management, and so on. But we're not building skyscrapers—we aren't as constrained by the boundaries of physics and the real world.

The gardening metaphor is much closer to the realities of software development. Perhaps a certain routine has grown too large, or is trying to accomplish too much—it needs to be split into two. Things that don't work out as planned need to be weeded or pruned. Rewriting, reworking, and re-architecting code is collectively known as refactoring.

When Should You Refactor?

When you come across a stumbling block because the code doesn't quite fit anymore, or you notice two things that should really be merged, or anything else at all strikes you as being "wrong," don't hesitate to change it. There's no time like the present. Any number of things may cause code to qualify for refactoring:
  • Duplication. You've discovered a violation of the DRY principle (The Evils of Duplication).
  • Nonorthogonal design. You've discovered some code or design that could be made more orthogonal (Orthogonality).
  • Outdated knowledge. Things change, requirements drift, and your knowledge of the problem increases. Code needs to keep up.
  • Performance. You need to move functionality from one area of  the system to another to improve performance.

Real-World Complications

So you go to your boss or client and say, "This code works, but I need another week to refactor it."
 
We can't print their reply.

Time pressure is often used as an excuse for not refactoring. But this excuse just doesn't hold up: fail to refactor now, and there'll be a far greater time investment to fix the problem down the road—when there are more dependencies to reckon with. Will there be more time available then? Not in our experience.

You might want to explain this principle to the boss by using a medical analogy: think of the code that needs refactoring as a "growth." Removing it requires invasive surgery. You can go in now, and take it out while it is still small. Or, you could wait while it grows and spreads—but removing it then will be both more expensive and more dangerous. Wait even longer, and you may lose the patient entirely.

TIP 47: Refactor Early, Refactor Often.

How Do You Refactor?

At its heart, refactoring is redesign. Anything that you or others on your team designed can be redesigned in light of new facts, deeper understandings, changing requirements, and so on. But if you proceed to rip up vast quantities of code with wild abandon, you may find yourself in a worse position than when you started.

Martin Fowler offers the following simple tips on how to refactor without doing more harm than good
  1. Don't try to refactor and add functionality at the same time.
  2. Make sure you have good tests before you begin refactoring. Run the tests as often as possible. That way you will know quickly if your changes have broken anything.
  3. Take short, deliberate steps: move a field from one class to another, fuse two similar methods into a superclass. Refactoring often involves making many localized changes that result in a larger-scale change. If you keep your steps small, and test after each step, you will avoid prolonged debugging.

Saturday, October 25, 2014

PragProg - Programming by Coincidence

Ref: The Pragmatic Programmer

 Know what you are doing while you are doing it. Know why you are doing while you are doing it.

TIP 44: Don't Program by Coincidence

How to Program Deliberately

  • Always be aware of what you are doing. Don't be frog in boiling water.
  • Don't code blindfolded. Attempting to build an application you don't fully understand, or to use a technology you aren't familiar with, is an invitation to be misled by coincidences.
  • Proceed from a plan, whether that plan is in your head, on the back of a cocktail napkin, or on a wall-sized printout from a CASE tool.
  • Rely only on reliable things. Don't depend on accidents or assumptions. If you can't tell the difference in particular circumstances, assume the worst.
  • Don't just test your code, but test your assumptions as well. Don't guess; actually try it. Write an assertion to test your assumptions.
  • Don't be a slave to history. Don't let existing code dictate future code. All code can be replaced if it is no longer appropriate.
So next time something seems to work, but you don't know why, make sure it isn't just a coincidence.

PragProg - While You Are Coding

Ref: The Pragmatic Programmer

Conventional wisdom says that once a project is in the coding phase, the work is mostly mechanical, transcribing the design into executable statements. We think that this attitude is the single biggest reason that many programs are ugly, inefficient, poorly structured, unmaintainable, and just plain wrong.

Coding is not mechanical. If it were, all the CASE tools that people pinned their hopes on in the early 1980s would have replaced programmers long ago. There are decisions to be made every minute—decisions that require careful thought and judgment if the resulting program is to enjoy a long, accurate, and productive life.
 
Developers who don't actively think about their code are programming by coincidence—the code might work, but there's no particular reason why. In Programming by Coincidence, we advocate a more positive involvement with the coding process.

Something that should be in the back of your mind whenever you're producing code is that you'll someday have to test it. Make code easy to test, and you'll increase the likelihood that it will actually get tested.

PragProg - Decoupling and the Law of Demeter

Ref: The Pragmatic Programmer

Good fences make good neighbors.
Robert Frost, "Mending Wall"

"shy" code is beneficial. But "shy" works two ways: don't reveal yourself to others, and don't interact with too many people.

Suppose you are remodeling your house, or building a house from scratch. A typical arrangement involves a "general contractor." You hire the contractor to get the work done, but the contractor may or may not do the construction personally; the work may be offered to various subcontractors. But as the client, you are not involved in dealing with the subcontractors directly—the general contractor assumes that set of headaches on your behalf.
 
We'd like to follow this same model in software. When we ask an object for a particular service, we'd like the service to be performed on our behalf. We do not want the object to give us a third-party object that we have to deal with to get the required service.

Don’t talk to strangers.



Friday, October 24, 2014

PragProg - Pragmatic Paranoia

Ref: The Pragmatic Programmer


Tip 30 : You Can't Write Perfect Software

Did that hurt? It shouldn't. Accept it as an axiom of life. Embrace it. Celebrate it. Because perfect software doesn't exist. No one in the brief history of computing has ever written a piece of perfect software. It's unlikely that you'll be the first. And unless you accept this as a fact, you'll end up wasting time and energy chasing an impossible dream.




When To Use Exceptions

it is good practice to check for every possible error—particularly the unexpected ones. However, in practice this can lead to some pretty ugly code; the normal logic of your program can end up being totally obscured by error handling. We've seen code that looks something like the following:


Fortunately, if the programming language supports exceptions, you can rewrite this code in a far neater way:


PragProg - Debugging

Ref: The Pragmatic Programmer

Unfortunately, modern computer systems are still limited to doing what you tell them to do, not necessarily what you want them to do.
 
No one writes perfect software, so it's a given that debugging will take up a major portion of your day. Let's look at some of the issues involved in debugging and some general strategies for finding elusive bugs.

Psychology of Debugging

Having found someone else's bug, you can spend time and energy laying blame on the filthy culprit who created it. In some workplaces this is part of the culture, and may be cathartic. However, in the technical arena, you want to concentrate on fixing the problem, not the blame

TIP 24: Fix the Problem, Not the Blame

It doesn't really matter whether the bug is your fault or someone else's. It is still your problem.

A Debugging Mindset

Tip 25: Don't Panic

If your first reaction on witnessing a bug or seeing a bug report is "that's impossible," you are plainly wrong. Don't waste a single neuron on the train of thought that begins "but that can't happen" because quite clearly it can, and has.

Rubber Duck Debugging

A very simple but particularly useful technique for finding the cause of a problem is simply to explain it to someone else. The other person should look over your shoulder at the screen, and nod his or her head constantly (like a rubber duck bobbing up and down in a bathtub). They do not need to say a word; the simple act of explaining, step by step, what the code is supposed to do often causes the problem to leap off the screen and announce itself.

PragProg - Basic Tools

Ref: The Pragmatic Programmer

 Every craftsman starts his or her journey with a basic set of good-quality tools. A woodworker might need rules, gauges, a couple of saws, some good planes, fine chisels, drills and braces, mallets, and clamps. These tools will be lovingly chosen, will be built to last, will perform specific jobs with little overlap with other tools, and, perhaps most importantly, will feel right in the budding woodworker's hands.

Over time, the woodworker will add new tools, such as biscuit cutters, laser-guided miter saws, dovetail jigs—all wonderful pieces of technology.

Tools amplify your talent. The better your tools, and the better you know how to use them, the more productive you can be.

Shell Utilities and Windows Systems

Although the command shells provided with Windows systems areimproving gradually, Windows command-line utilities are still inferior totheir Unix counterparts. However, all is not lost.Cygnus Solutions has a package called Cygwin. As well asproviding a Unix compatibility layer for Windows, Cygwin comes with acollection of more than 120 Unix utilities, including such favorites as 1s,grep, and find.


Power Editing

You need to be proficient. Simply typing linearly and using a mouse to cut and paste is not enough. You just can't be as effective that way as you can with a powerful editor under your fingers. Typing "backspace" ten times to move the cursor left to the beginning of a line isn't as efficient as typing a single key such as "Home".

Tip 22: Use a Single Editor Well

If this sounds like you…Then think about…
I use only basic features of many different editors.
Pick a powerful editor and learn it well.
I have a favorite editor, but I don't use all of its features.Learn them. Cut down the number of keystrokes you need to type.
I have a favorite editor and use it where possible.Try to expand and use it for more tasks than you do already.
I think you are nuts. Notepad is the best editor ever made.As long as you are happy and productive, go for it! But if you find yourself subject to "editor envy," you may need to reevaluate your position.

Monday, October 20, 2014

PragProg - Estimating

Ref: The Pragmatic Programmer
TIP 18: Estimate to Avoid Surprises

We think it’s a great idea to record your estimates so you can see how close you were. If an overall estimate involved calculating subestimates, keep track of these as well. Often you’ll find your estimates are pretty good—in fact, after a while, you’ll come to expect this.

What to Say When Asked for an Estimate

You say "I'll get back to you."

PragProg - Prototypes

Ref: The Pragmatic Programmer

We tend to think of prototypes as code-based , but they don't always have to be. Like the car makers, we can build prototypes out of different materials. Post-it notes are great for prototyping dynamic things such as workflow and application logic. A user interface can be prototyped as a drawing on a whiteboard, as a nonfunctional mock-up drawn with a paint program, or with an interface builder.

Prototypes are designed to answer just a few questions, so they are much cheaper and faster to develop than applications that go into production.

Prototyping is a learning experience. Its value lies not in the code produced, but in the lessons learned. That's really the point of prototyping.

TIP 16: Prototype to Learn

How NOT to Use Prototypes

Before you embark on any code-based prototyping, make sure that everyone understands that you are writing disposable code. Prototypes can be deceptively attractive to people who don't know that they are just prototypes. You must make it very clear that this code is disposable, incomplete, and unable to be completed.

PragProg - Tracer Bullets

Ref: The Pragmatic Programmer

Ready, fire, aim…

There are two ways to fire a machine gun in the dark [5]. You can find out exactly where your target is (range, elevation, and azimuth). You can determine the environmental conditions (temperature, humidity, air pressure, wind, and so on). You can determine the precise specifications of the cartridges and bullets you are using, and their interactions with the actual gun you are firing. You can then use tables or a firing computer to calculate the exact bearing and elevation of the barrel. If everything works exactly as specified, your tables are correct, and the environment doesn't change, your bullets should land close to their target.

Or you could use tracer bullets.

Pragmatic Programmers tend to prefer using tracer bullets.

TIP 15: Use Tracer Bullets to Find the Target

Tracer code is not disposable: you write it for keeps. It contains all the error checking, structuring, documentation, and self-checking that any piece of production code has. It simply is not fully functional. However, once you have achieved an end-to-end connection among the components of your system, you can check how close to the target you are, adjusting if necessary. Once you are on target, adding functionality is easy. It is an incremental approach.

The tracer code approach has many advantages

  • Users get to see something working early: 
  • Developers build a structure to work in: This makes everyone more productive and encourages consistency.
  • You have an integration platform: As the system is connected end-to-end, you have an environment to which you can add new pieces of code once they have been unit-tested.
  • You have something to demonstrate
  • You have a better feel for progress.


PragProg - Orthogonality


Ref: The Pragmatic Programmer

Orthogonality is a term borrowed from geometry. In computing, the term has come to signify a kind of independence or decoupling. Two or more things are orthogonal if changes in one do not affect any of the others.

TIP 13: Eliminate Effects Between Unrelated Things.

Coding

Keep your code decoupled: Write shy code-modules that don't reveal anything unnecessary to other modules and that don't rely on other modules implementations.

Avoid global data: Every time your code references global data, it ties itself into the other components that share that data.


PragProg - DRY - Dont Repeat Yourself

Ref: The Pragmatic Programmer

We feel that the only way to develop software reliably, and make our development easier to understand and maintain, is to follow what we call the DRY principle.

The DRY principle is stated as “Every piece of knowledge must have a single,unambiguous, authoritative representation within a system.


DRY - Don't Repeat Yourself


Most of the duplication we see falls into one of the following categories:

a) Imposed duplication.
Developers feel they have no choice—the environment seems to require duplication.

b) Inadvertent duplication.
Developers don't realize that they are duplicating information.

c) Impatient duplication.
Developers get lazy and duplicate because it seems easier.

d) Interdeveloper duplication.
Multiple people on a team (or on different teams) duplicate a piece of information.