Tuesday, March 31, 2009

System.Diagnostics.Process and xcopy… why it doesn’t work?

We spent 30 minutes on a spiny issue. We execute some commands directly from a C# program but we want to make sure that everything executed. We did unit test on some code and everything seemed to work.

Today, we tried it live with some real case scenario where we execute some XCOPY. And then…. nothing.

We didn’t receive any ExitCode that was 0. We didn’t catch any exception. And we didn’t catch anything in the error stream.

Here is the code that we used:

private void ExecuteProcess()
{
    // setup the process info
    var startInfo = new ProcessStartInfo(@"cmd.exe", @" /c xcopy c:\file*.txt c:\file*.bck")
                        {
                            UseShellExecute = false,
                            CreateNoWindow = true,
                            WorkingDirectory = @"C:\",
                            RedirectStandardError = true,
                            RedirectStandardOutput = true
                        };

    
    using(Process proc = Process.Start(startInfo))
    {
        proc.OutputDataReceived += ((sender, e) => MessageBox.Show("Data: " + e.Data ?? String.Empty));
        proc.ErrorDataReceived +=
            (sender, e) => MessageBox.Show(string.Format("Error: {0}", e.Data ?? string.Empty));
        proc.BeginErrorReadLine();
        proc.BeginOutputReadLine();

        proc.WaitForExit();
    }

}

Wow. Nice piece of code isn’t it? It will work for everything you have to execute. But if you execute XCOPY it won’t work. We found out that it’s missing something that should not be needed in our case but that cause XCOPY to just execute with no output and no results.

You want XCOPY to work? Just add this line before starting the process:

startInfo.RedirectStandardInput = true;

That’s it! This error will only happen if you have “UseShellExecute” set to false.

Hope it help some clueless programmer that is wondering why the XCOPY won’t execute.

Submit this story to DotNetKicks

Sunday, March 29, 2009

Anti-Pattern: The Gas Factory or Unnecessary complexity

Just as in any system, when you start coding some structure, you always try to make it as generic as possible to make it easy to later reuse those parts.Just like petrolum complex, things starts getting complex There is normal complexity when you build your code and as you go, complexity adds up. However, one of the main problem of this anti-pattern is when it’s done consciously.

Let’s give a quick example here. You start building collections and one of your collection need a special feature. The problem is when you extract this functionality and try to make it as generic as possible so that anyone could reuse your class. That is the problem of the unnecessary complexity. You see, as you are making stuff generic for a single class, you are adding structures inside your code. Some of those structure might be proof tested for this specific class but might fail on other classes. There is also the problem that maybe no other class will ever require this functionality.

How do I solve this anti-pattern?

By following YAGNI and Lean Software Development, you delay code and unnecessary complexity until you actually require the complexity. If  you have 2 classes that require the same functionality, it is now time to extract this functionality inside a different class and make those 2 classes inherit from it (or any other patterns that are required).

And here, I’m not just talking about inheritance. I’m also talking about unnecessary design patterns. If you built a pipeline component to calculate discount but you only have one discount at the moment, it might be actually relevant to implement it anyway since you are sure you might require it later. However, the client is the one that is supposed to drive the requirements and if you don’t require the pipeline immediately… well… don’t built it!

It doesn’t mean to leave your code in a fixed state. It just means to keep your code clean to ease the implementation of the pipeline.

The best line of codes are those we don’t need to write.

Submit this story to DotNetKicks

Thursday, March 26, 2009

Software development is not an art. It’s a craft.

When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong.
R. Buckminster Fuller - US architect & engineer

Forget about the “creation” part of the job. As you are developing your first application, you are not creating something. You are building something. Mind you, it’s not like building a bridge as in engineering or a plane.

The main difference between the art and the craft is the people inside the profession. Art is completely subjective. Anyone can be improvised artist and some may succeed. The difference between artist and programmers is artist that don’t sell get another job. Self-improvised programmers that fails simply find another company to hire him.

I’m not complaining about self thought programmers. What I’m worried about is the quality of the code we find in today’s software. Who saw some serious bad code here? Raise your hand! You’re not alone. Those code were probably made by people who don’t care about software or by people who never had the chance to have proper training. That’s where it’s important to realize that our profession is way more of a craft than an art.

Art is based on inspiration. Craft is based upon sets of rules and experience that will bring you quality every time you follow them. Artistic software development doesn’t care about the rules. Let’s pick a simple metaphor. Japanese sword maker. There is a reason why there work is recognized and of such quality. Their craft had hundreds of year to accumulate rules on how to properly melt the metal, forge the blade, etc.. The master know a good sword on sight and knows that there is very few way to reach quality. Young apprentice will train for years under their master to gain the knowledge they acquired and be able to reproduce success.

It will be harsh but there is only 2 ways to change the behaviour of those that don’t care about the code.

  1. Train them (mentorship, classes, etc.)
  2. Get rid of them

If you want to train a programmer, he have to attend conferences, user group and spend some time off work to learn about good practices, design pattern and software principles. Company like Object Mentor do offer training to raise the quality of existing programmer.

Our industry might not be as old as Japanese sword maker but we must start to get rules/principles as much as possible and encourage “artistic sword maker” to follow rules and principles. Otherwise, the only thing you will get is a cheap rip-off that will break on the first hit. We’ve all seen software that breaks on the first hit and we need to improve the average level of our profession.

UPDATE: Added a quotation that I think represent a part of what we are doing. Solving problems and then making it nice. But foremost, solving problems.

Submit this story to DotNetKicks

Sunday, March 8, 2009

Software Developer and Software Engineer are not opposite, they are the same

Of course, Software engineering is defined as:

Software engineering is the application of a systematic, disciplined, quantifiable approach to the development, operation, and maintenance of software, and the study of these approaches.

This term was created in 1968 in the hope of bringing a more “civilized” way of coding. What is interesting however, is that most of the time, people and companies won’t make a difference between the developer and the engineer.

A Software Developer is defined as :

A software developer is a person or organization concerned with facets of the software development process wider than design and coding, a somewhat broader scope of computer programming or a specialty of project managing including some aspects of software product management. […]

Other names which are often used in the same close context are software analyst and software engineer.

If we stick to the definition, we can say that a software engineer developer, operate and maintain software and that he will study what he did to make sure it’s the best in the industry. As for the “systematic, disciplined, quantifiable”, it’s perfectly understandable that a software engineer should always do his best and follow standards.

What about the software developer? If we stick to the definition, a software developer design, code, manage, test and participate in the release of his software. Honestly, it’s basically what I do everyday. I’m not given a class diagram and said “code this”. I receive a requirement and I have to ensure that it will go in the application. I have to answer those following question:

  • Can it be done?
  • When will it be done?
  • Will it impact something else that you have to do?

No body ask me “How will you implement it?”. I have the responsibility to design, organize, implement and test my code. Of course I can go cowboy and go straight for the implementation.

But it’s not because I’m a software developer. Software developers is just a title. It’s not because some cowboy coders put all the Data Access Logic inside the view that all software developers are a useless bunch of monkey coder.

I’ve signed the software craftsmanship manifesto because I value the work that I do. I’ve signed it because quality is important, maybe not at the moment but it will eventually. I’ve signed it because I believe in good software.

What do you think? Is there such a gap between software developers and software engineers?

Submit this story to DotNetKicks

Thursday, March 5, 2009

Implementing a Chain-of-responsibility or “Pipeline” in C#

Anti-Patterns are interesting in showing you what you are doing wrong. However, patterns are also interesting in showing you how to do it well.

This time, I want to show how to implement a simple Chain-of-responsibility pattern. Our example is going to be based on a simple e-Commerce data model.

The Domain Model

Product which will have some basic attributes like a price, a name and a collection of applied discounts.

Discount which is going to be an actual discount implementation. More class are going to be derived from this base class.

That is all we are going to need for this pattern. However, it would be smart to have a class that would assign discounts to product based on certain rules.

Let’s start by writing our Product class and our Discount interface:

public class Product
{
    private readonly List<IDiscount> _appliedDiscount = new List<IDiscount>();
    
    public string ProductName { get; private set; }
    public decimal OriginalPrice { get; private set; }
    
    public decimal DiscountedPrice
    {
        get
        {
            decimal discountedPrice = OriginalPrice;
            return discountedPrice;
        }
        
    }

    public Product(string productName, decimal productPrice)
    {
        ProductName = productName;
        OriginalPrice = productPrice;
    }

    public List<IDiscount> AppliedDiscount
    {
        get
        {
            return _appliedDiscount;
        } 
    }
}

public interface IDiscount
{
    decimal ApplyDiscount(decimal productPrice);
}

Right now, the "DiscountedPrice” is simply returning our “OriginalPrice”. Let’s implement the proper discount commands:

public decimal DiscountedPrice
{
    get
    {
        decimal discountedPrice = OriginalPrice;
        
        foreach (IDiscount discount in _appliedDiscount)
            discountedPrice = discount.ApplyDiscount(discountedPrice);

        return discountedPrice;
    }
}

Now that we have an algorithm that will apply all discounts, let’s create a few Discount class:

public class PercentageDiscount : IDiscount
{
    public decimal PercentDiscount { get; set; }

    public PercentageDiscount(decimal percentDiscount)
    {
        PercentDiscount = percentDiscount;
    }

    public decimal ApplyDiscount(decimal productPrice)
    {
        return productPrice - (productPrice*PercentDiscount);
    }
}

public class FixPriceDiscount : IDiscount
{
    public decimal PriceDiscount { get; set; }

    public FixPriceDiscount(decimal priceDiscount)
    {
        PriceDiscount = priceDiscount;
    }

    public decimal ApplyDiscount(decimal productPrice)
    {
        return productPrice - PriceDiscount;
    }
}

So now we have a class that implement a percentage discount and another one that impose a fixed rate discount. Of course, our current implementation should NEVER be used in a real system as it is now. Validations must be done for a positive price and maybe some extra verification that we are not underselling the item.

Let’s use this current implementation:

// Creating a product worth 50$
Product currentProduct = new Product("Simple product", 50.0M);

Console.WriteLine(string.Format("Original Price: {0}", currentProduct.OriginalPrice));

// Give a 10% rebate on the product
currentProduct.AppliedDiscount.Add(new PercentageDiscount(0.1M));
Console.WriteLine(string.Format("Discounted Price: {0}", currentProduct.DiscountedPrice));

//Give an extra 10$ off on the product
currentProduct.AppliedDiscount.Add(new FixPriceDiscount(10.0M));
Console.WriteLine(string.Format("Discounted Price: {0}", currentProduct.DiscountedPrice));

This will output in order 45.00$ and 35.00$.  It’s important to be aware that the discount interfaces are not aware that they are being applied to a product. They could be reused in any other model that accepts an IDiscount.

Conclusion

By chaining Strategy Pattern (the discount algorithms), we can increase the amount of flexibility inside our model and increase the reuse of common algorithms. It would also be easy with a simple rule engine to apply discounts to product that match certain rules.

Other uses of a chain-of-responsibility could be when dealing with objects that could have multiple rules applied to them based on different conditions. The conditions would then be moved from the object itself to a “Command” and then reused exactly the same way we did here.

Submit this story to DotNetKicks

Wednesday, March 4, 2009

Waterfall development just work as great

Waterfall development is still a valid way to develop software. Setting up the requirements, making proper analysis, coding and then testing works just as fine. However… not for ever changing software like a website.

If I were to build an e-Commerce website, I would never choose to go Waterfall. I would love to go SCRUM or XP. Agile development have the advantage of including the client inside the development process. It allows the client to change his mind on some things that seemed good at first but that were finally a bad idea. There is some ideas that can only be rated as “bad” when you are working to develop them. Of course, if some features take longer, it’s easier to find out quickly that the project is going to be late and that some features are going to be left out.

Agile development as worked well so far in custom application development, websites, e-Commerce, product development, etc. However, as good as Agile might be… there is one strong point where I think the waterfall approach is still relevant.

Some software need to be bug free and have detailed specifications about the features. What are those software? One example is what a group of people inside Lockheed Martin is developing for the Space Shuttle which FastCompany talks about. This software need to be bug free. Of course, it needs to be thoroughly tested and must pass the strongest inspections. Every changes to the specifications must be approved by multiple persons and any change inside the code base without a valid reason is not allowed. They do not do agile. They do waterfall. What about the bugs?

This software never crashes. It never needs to be re-booted. This software is bug-free. It is perfect, as perfect as human beings have achieved. Consider these stats : the last three versions of the program -- each 420,000 lines long-had just one error each. The last 11 versions of this software had a total of 17 errors. Commercial programs of equivalent complexity would have 5,000 errors.

So how come Waterfall works in this case? Of course, because the software is based on pieces of hardware that rarely need to change, it reduce the amount of compatibility problem. The software doesn’t need to work on 100 types of space shuttle. It has only one physical requirement. It also works because once specifications are written, they are to be followed at all cost. Changes are expansive and must be approved every time. The software is also never updated while in use. Of course you’ll never see this in an e-Commerce website!

So let’s resume:

  • Hardware that rarely change
  • Precise specifications
  • Expansive change
  • Once deployed, can’t be changed

Does that bring other examples? The simple things I could think would be any piece of hardware that have software inside. Let’s go with the Microwave. Your microwave have a software inside. Let’s see how many points it meet shall we? First, the microwave hardware will NEVER change. Nobody is pimping out his microwave so we can assume that the hardware stays the same for all it’s usable life. The specification for a microwave software rarely change (timer, defrost settings, power levels, etc.). If there is a change that must be made, it’s probably because of a hardware change which is expansive. And finally, no microwave is Wi-Fi enabled or have a USB connection to update it’s firmware.

We can safely assume that the Waterfall model must have been among the first software development process to be used. People first programmed chips, board, “simple” OS or OS with limited distribution. Of course, back then the formula worked great because of exactly the same four points I mentioned. The model started to break when building software for computers that varied largely in configuration (RAM, CPU, etc.). The model tried to be used but suddenly, development time sky-rocketed through the roof. A new model was seen as necessary.

So please, unless you are reprogramming your microwave for some evil plans, don’t use Waterfall. The main weakness of waterfall was the lack of user inputs. Even the Sashimi model is not enough. We need rapid feedback and constant testing. We are not developing perfect software that must never fails. But make sure it does before hitting the client.

Submit this story to DotNetKicks