问:
Similar references to themselves in two classes
How can I make 1 class (base, generic or something else) from these two classes?

```<code>class A
{
  A Link { get; set; }
}

class B
{
  B Link { get; set; }
}
</code>```

UPD: This is what I have now:

```<code>class BSTree
{
  public BSTNode Root { get; set; }
}

class AVLTree
{
  public AVLNode Root { get; set; }
}

class BSTNode
{
  public BSTNode Parent { get; set; }
  public BSTNode Left { get; set; }
  public BSTNode Right{ get; set; }
  public int Key{ get; set; }
}

class AVLNode
{
  public AVLNode Parent { get; set; }
  public AVLNode Left { get; set; }
  public AVLNode Right{ get; set; }
  public int Key{ get; set; }
  public int Height { get; set;}
}
</code>```

And finally I want to get something like BaseNode and BaseTree.

答:
What is Link? If you have a base class Base with A : Base and B : Base, do you need to know that a.Link is of type A and b.Link is of type B?

If not, it is as easy as:

```<code>public abstract class Base
{
    public Base Link { get; set; }
}
</code>```

If, on the other hand, you need to preserve the type of Link, then what about generics?

```<code>public class Common<T>
{
    public T Link { get; set; }
}
</code>```

which can be used like this:

```<code>public static void Main()
{
    var number = new Common<int>
    {
        Link = 27,
    };

    var text = new Common<string>
    {
        Link = "Hello World",
    };

    // This is impossible, because of the mismatch between types.
    ////var wrong = new Common<float>
    ////{
    ////    Link = "I'm not a float.",
    ////};

    Console.WriteLine(number.Link);
    Console.WriteLine(text.Link);
}
</code>```

1. Refactoring: local method

Specifying both the generic type and the link is annoying, especially if you have to change the types a lot. In some cases, you may even mistakenly specify the wrong type: either a parent class or a class which supports implicit type conversion, resulting in difficult to find bugs.

To avoid this, you can create a method which initializes a new instance of the Common<T> class based on the link:

```<code>public static void Main()
{
    var number = CreateCommon(27);
    var text = CreateCommon("Hello World");

    Console.WriteLine(number.Link);
    Console.WriteLine(text.Link);
}

private static Common<T> CreateCommon<T>(T link)
{
    return new Common<T>
    {
        Link = link,
    };
}

public class Common<T>
{
    public T Link { get; set; }
}
</code>```

2. Refactoring: factory pattern

The first refactoring is enough if you use the Common class in one method. If you're using it in several classes, then you'll end up duplicating code (i.e. copy-pasting the CreateCommon method), or refactoring the previous piece of code into a one which uses a factory:

```<code>public static void Main()
{
    var number = Common.Factory.Create(27);
    var text = Common.Factory.Create("Hello World");

    Console.WriteLine(number.Link);
    Console.WriteLine(text.Link);
}

public class Common<T> : Common
{
    public Common()
    {
        // Do something here.
    }

    public Common(T link)
        : this()
    {
        this.Link = link;
    }

    public T Link { get; set; }
}

public class Common
{
    public static CommonFactory Factory
    {
        get
        {
            return new CommonFactory();
        }
    }
}

public class CommonFactory
{
    public Common<T> Create<T>(T link)
    {
        return new Common<T>(link);
    }
}
</code>```

Body:
What is Link? If you have a base class Base with A : Base and B : Base, do you need to know that a.Link is of type A and b.Link is of type B?

If not, it is as easy as:

public abstract class Base
{
    public Base Link { get; set; }
}

If, on the other hand, you need to preserve the type of Link, then what about generics?

public class Common<T>
{
    public T Link { get; set; }
}

which can be used like this:

public static void Main()
{
    var number = new Common<int>
    {
        Link = 27,
    };

    var text = new Common<string>
    {
        Link = "Hello World",
    };

    // This is impossible, because of the mismatch between types.
    ////var wrong = new Common<float>
    ////{
    ////    Link = "I'm not a float.",
    ////};

    Console.WriteLine(number.Link);
    Console.WriteLine(text.Link);
}

1. Refactoring: local method

Specifying both the generic type and the link is annoying, especially if you have to change the types a lot. In some cases, you may even mistakenly specify the wrong type: either a parent class or a class which supports implicit type conversion, resulting in difficult to find bugs.

To avoid this, you can create a method which initializes a new instance of the Common<T> class based on the link:

public static void Main()
{
    var number = CreateCommon(27);
    var text = CreateCommon("Hello World");

    Console.WriteLine(number.Link);
    Console.WriteLine(text.Link);
}

private static Common<T> CreateCommon<T>(T link)
{
    return new Common<T>
    {
        Link = link,
    };
}

public class Common<T>
{
    public T Link { get; set; }
}

2. Refactoring: factory pattern

The first refactoring is enough if you use the Common class in one method. If you're using it in several classes, then you'll end up duplicating code (i.e. copy-pasting the CreateCommon method), or refactoring the previous piece of code into a one which uses a factory:

public static void Main()
{
    var number = Common.Factory.Create(27);
    var text = Common.Factory.Create("Hello World");

    Console.WriteLine(number.Link);
    Console.WriteLine(text.Link);
}

public class Common<T> : Common
{
    public Common()
    {
        // Do something here.
    }

    public Common(T link)
        : this()
    {
        this.Link = link;
    }

    public T Link { get; set; }
}

public class Common
{
    public static CommonFactory Factory
    {
        get
        {
            return new CommonFactory();
        }
    }
}

public class CommonFactory
{
    public Common<T> Create<T>(T link)
    {
        return new Common<T>(link);
    }
}


问:
How can I reduce my problem into Max flow problem?
I am trying to reduce my problem to a max flow problem so I can run the max flow algorithm on this problem. But there are some things that I am missing while transforming my problem.

My problem is:

there are classes with a maximum capacity

there are students and their wish-list that includes 5 classes that they want

students can select at most 5 classes.

And the goal is:

to maximize number of classes that students enroll.

If I put students and classes as vertices (please see image above), then put a source node s that has an edge to each student and a sink node t that has an edge to each classes, what will be the edge costs?

edge cost between classes and sink node t or

edge cost between source node s and and students

Are the following assumptions correct?

 I think the edge between students and classes cost should be 1. Because a student can only enroll once to a class in a term.  I think edge cost between classes and the sink node t will be the maximum capacity of a class.

I don't have an idea about edge costs between source node s and students nodes.

And at the end, after arranging, do we just need to run max flow algorithm?

答: I think that a max flow from S to any student of 5, and max flow of capacity from each class to T and 1 from each student to each class would satisfy your requirements. BTW, that is not an edge cost but rather an edge flow capacity.</p>

ContentLicense: CC BY-SA 3.0


问:
Object Initializer in C# problem with readability
I wonder if object initializing have some performance gain in ASP.NET website. I have an office mate that told me that object initialization is much readable and faster than constructor. But one of my office mate disagree with that and said that it always depends.
For example I am doing this:

```<code>using (var dataAccess = new DatabaseAccess { ConnectionString = ConfigurationManager.ConnectionStrings["test"].ConnectionString, Query = query, IsStoredProc = true })
{
    //some code here
}
</code>```

Is it better if I will do this way?

```<code>using (var dataAccess = new DatabaseAccess())
{
    dataAccess.ConnectionString = ConfigurationManager.ConnectionStrings["test"].ConnectionString;
    dataAccess.Query = query;
    dataAccess.IsStoredProc = true;
}
</code>```

Thanks in advance guys!

---EDIT----

is this somehow much better:

```<code>using (
    var dataAccess = new DatabaseAccess
    {
        ConnectionString = ConfigurationManager.ConnectionStrings["test"].ConnectionString,
        Query = query,
        IsStoredProc = true
    }
)
{
    //some code here
}
</code>```

答:
Stop!

You have a bigger problem than the readability. It looks like you don't understand how object initializers work.

Let's create a disposable class which traces its execution:

```<code>public class Demo : IDisposable
{
    private string hello;

    public Demo()
    {
        Debug.WriteLine("The parameterless constructor was called.");
    }

    public Demo(string hello)
        : this()
    {
        Debug.WriteLine("The constructor with parameters was called.");
        this.Hello = hello;
    }

    public string Hello
    {
        get
        {
            Debug.WriteLine("The getter was called.");
            return this.hello;
        }

        set
        {
            Debug.WriteLine("The setter was called.");
            this.hello = value;
            throw new NotImplementedException();
        }
    }

    public void Dispose()
    {
        Debug.WriteLine("The disposer was called.");
    }
}
</code>```

Now, let's write an app which initializes this class in three different ways (sorry, it's too big; I'll explain it more in details later):

```<code>public static class Program
{
    // --- Interesting stuff ---
    private static void WithPropertiesInitialization()
    {
        using (var demo = new Demo())
        {
            demo.Hello = "Hello World!";
            // Do nothing.
        }
    }

    private static void WithObjectInitializer()
    {
        using (var demo = new Demo { Hello = "Hello World!" })
        {
            // Do nothing.
        }
    }

    private static void WithConstructor()
    {
        using (var demo = new Demo("Hello World!"))
        {
            // Do nothing.
        }
    }

    // --- Not so interesting stuff ---
    public static void Main()
    {
        Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));

        Console.WriteLine("With constructor:");

        try
        {
            WithConstructor();
        }
        catch (NotImplementedException)
        {
        }

        Console.WriteLine();
        Console.WriteLine("With object initializer:");

        try
        {
            WithObjectInitializer();
        }
        catch (NotImplementedException)
        {
        }

        Console.WriteLine();
        Console.WriteLine("With properties initialization:");

        try
        {
            WithPropertiesInitialization();
        }
        catch (NotImplementedException)
        {
        }

        Console.WriteLine();
        Console.WriteLine("Press any key to continue...");
        Console.ReadKey(true);
    }
}
</code>```

There are three types of initialization here:

Through the constructor, the value to set to the property being passed to the constructor,

With the usage of an object initializer,

With a parameterless constructor, the property being assigned later.

Before continuing to read the answer, ask yourself two questions:

Do those initialization techniques result in the same console output?

Is there a bug?

Those techniques are totally different, and there is effectively two bugs: only one of them is correct.

1. Constructor

```<code>using (var demo = new Demo("Hello World!"))
{
    // Do nothing.
}
</code>```

has nothing wrong, but it's the actual implementation of the constructor which is wrong. Constructors shouldn't throw exceptions, and one of the reasons is that it may cause inconsistent state when the object is used inside a using block: it's not fully initialized yet, so it will not be disposed, causing disaster if the unfinished initialization allocated some resources which should have been disposed.

```<code>using (var a = new A())
{
    DoWork(a);
}
</code>```

is basically the same as:

```<code>var a = new A();
try
{
    DoWork(a);
}
finally
{
    a.Dispose();
}
</code>```

As you can see, there is no try around the constructor, so an exception within it would terminate the program before reaching a.Dispose(): in all cases, we can't invoke a method of an object which is not initialized yet.

The setter of Hello throws an exception; the constructor should have been using the backing field directly, instead of the property.

2. Object initializer

```<code>    using (var demo = new Demo { Hello = "Hello World!" })
    {
        // Do nothing.
    }
</code>```

is itself incorrect, and if you have used Code Analysis even at Minimum Recommended Rules level, you would have seen the warning CA2000, telling that:

object '<>g__initLocal0' is not disposed along all exception paths.

What it that?!

That is the indicating that somewhere, an object is created and not disposed. To avoid concurrency issues, when you use an object initializer, a temporary instance of created:

```<code>this.Pet = new Gremlin
{
    Title = "Mogwai",
    Age = 14,
}
</code>```

is transformed by the compiler into:

```<code>Gremlin someCrypticName = new Gremlin();
someCrypticName.Title = "Mogwai";
someCrypticName.Age = 14;
this.Pet = someCrypticName;
</code>```

Indeed, when you use an object initializer inside a using (...):

The temporary object is created,

The properties are assigned,

The temporary object is assigned to the one which is used inside a using,

The using block runs.

Any exception thrown when assigning properties will prevent disposing the object, since the assignment happens before the try/finally.

3. Late assignment

```<code>using (var demo = new Demo())
{
    demo.Hello = "Hello World!";
    // Do nothing.
}
</code>```

is correct. Since the constructor is not expected to throw an exception (and if it will, it would be the fault of the person who implemented the constructor, not the person who is using it within the using), all exceptions will occur within the try block, resulting in the demo object being properly disposed.

Conclusion:

using should contain either:

A parameterless constructor,

A constructor which takes parameters,

given that constructors are not expected to throw exceptions.

using should not contain an object initializer: properties should be initialized within the using { ... }, in order to guarantee the proper disposal of objects.

Readability

Now that you've understood that the two pieces of code in your question are totally difference, since one is correct, and another one is buggy, let's talk readability.

Until C# 4.0, object initialization was slightly more readable than a similar constructor:

```<code>var product = new Product("PowerEdge R620 rack server", 1, "Intel® Xeon® E5-2620", 16, 1929, true);
</code>```

Here, I have no idea what is "1" or "16" or "1929". A person who is not at all familiar with hardware wouldn't know what "Intel® Xeon® E5-2620" is. No one would find what is true.

Instead:

```<code>var product = new Product
{
    Title = "PowerEdge R620 rack server",
    RackUnits = 1,
    ProcessorName = "Intel® Xeon® E5-2620",
    MemoryInGB = 16,
    PriceInDollars = 1929,
    IsAvailable = true,
}
</code>```

is much more readable.

.NET Framework introduced named arguments, and since then, a constructor can be as readable as an object initializer, while being more compact. For example, title is explicit enough, and we would consider that anyone will understand the names of processors, so we can write:

```<code>var product = new Product(
    "PowerEdge R620 rack server",
    "Intel® Xeon® E5-2620",
    rackUnits: 1,
    memoryInGB: 16,
    priceInDollars: 1929,
    isAvailable: true);
</code>```

I have an office mate that told me that object initialization is much readable and faster than constructor.

We have seen that with named arguments, a constructor can be as readable as an object initializer. What about performance?

Above, I've explained that an object initializer this.a = new A { B = b } is translated by the compiler into:

```<code>A temp = new A();
temp.B = b;
this.a = temp;
</code>```

If the only thing the constructor is doing is to assign fields or properties from arguments, then the performance would be approximately the same. Unless your office mate can give precise profiling results and benchmarks proving his point, his statement about the performance should be considered wrong.

Body:
Stop!

You have a bigger problem than the readability. It looks like you don't understand how object initializers work.

Let's create a disposable class which traces its execution:

public class Demo : IDisposable
{
    private string hello;

    public Demo()
    {
        Debug.WriteLine("The parameterless constructor was called.");
    }

    public Demo(string hello)
        : this()
    {
        Debug.WriteLine("The constructor with parameters was called.");
        this.Hello = hello;
    }

    public string Hello
    {
        get
        {
            Debug.WriteLine("The getter was called.");
            return this.hello;
        }

        set
        {
            Debug.WriteLine("The setter was called.");
            this.hello = value;
            throw new NotImplementedException();
        }
    }

    public void Dispose()
    {
        Debug.WriteLine("The disposer was called.");
    }
}

Now, let's write an app which initializes this class in three different ways (sorry, it's too big; I'll explain it more in details later):

public static class Program
{
    // --- Interesting stuff ---
    private static void WithPropertiesInitialization()
    {
        using (var demo = new Demo())
        {
            demo.Hello = "Hello World!";
            // Do nothing.
        }
    }

    private static void WithObjectInitializer()
    {
        using (var demo = new Demo { Hello = "Hello World!" })
        {
            // Do nothing.
        }
    }

    private static void WithConstructor()
    {
        using (var demo = new Demo("Hello World!"))
        {
            // Do nothing.
        }
    }

    // --- Not so interesting stuff ---
    public static void Main()
    {
        Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));

        Console.WriteLine("With constructor:");

        try
        {
            WithConstructor();
        }
        catch (NotImplementedException)
        {
        }

        Console.WriteLine();
        Console.WriteLine("With object initializer:");

        try
        {
            WithObjectInitializer();
        }
        catch (NotImplementedException)
        {
        }

        Console.WriteLine();
        Console.WriteLine("With properties initialization:");

        try
        {
            WithPropertiesInitialization();
        }
        catch (NotImplementedException)
        {
        }

        Console.WriteLine();
        Console.WriteLine("Press any key to continue...");
        Console.ReadKey(true);
    }
}

There are three types of initialization here:

Through the constructor, the value to set to the property being passed to the constructor,

With the usage of an object initializer,

With a parameterless constructor, the property being assigned later.

Before continuing to read the answer, ask yourself two questions:

Do those initialization techniques result in the same console output?

Is there a bug?

Those techniques are totally different, and there is effectively two bugs: only one of them is correct.

1. Constructor

using (var demo = new Demo("Hello World!"))
{
    // Do nothing.
}

has nothing wrong, but it's the actual implementation of the constructor which is wrong. Constructors shouldn't throw exceptions, and one of the reasons is that it may cause inconsistent state when the object is used inside a using block: it's not fully initialized yet, so it will not be disposed, causing disaster if the unfinished initialization allocated some resources which should have been disposed.

using (var a = new A())
{
    DoWork(a);
}

is basically the same as:

var a = new A();
try
{
    DoWork(a);
}
finally
{
    a.Dispose();
}

As you can see, there is no try around the constructor, so an exception within it would terminate the program before reaching a.Dispose(): in all cases, we can't invoke a method of an object which is not initialized yet.

The setter of Hello throws an exception; the constructor should have been using the backing field directly, instead of the property.

2. Object initializer

    using (var demo = new Demo { Hello = "Hello World!" })
    {
        // Do nothing.
    }

is itself incorrect, and if you have used Code Analysis even at Minimum Recommended Rules level, you would have seen the warning CA2000, telling that:

object '<>g__initLocal0' is not disposed along all exception paths.

What it that?!

That is the indicating that somewhere, an object is created and not disposed. To avoid concurrency issues, when you use an object initializer, a temporary instance of created:

this.Pet = new Gremlin
{
    Title = "Mogwai",
    Age = 14,
}

is transformed by the compiler into:

Gremlin someCrypticName = new Gremlin();
someCrypticName.Title = "Mogwai";
someCrypticName.Age = 14;
this.Pet = someCrypticName;

Indeed, when you use an object initializer inside a using (...):

The temporary object is created,

The properties are assigned,

The temporary object is assigned to the one which is used inside a using,

The using block runs.

Any exception thrown when assigning properties will prevent disposing the object, since the assignment happens before the try/finally.

3. Late assignment

using (var demo = new Demo())
{
    demo.Hello = "Hello World!";
    // Do nothing.
}

is correct. Since the constructor is not expected to throw an exception (and if it will, it would be the fault of the person who implemented the constructor, not the person who is using it within the using), all exceptions will occur within the try block, resulting in the demo object being properly disposed.

Conclusion:

using should contain either:

A parameterless constructor,

A constructor which takes parameters,

given that constructors are not expected to throw exceptions.

using should not contain an object initializer: properties should be initialized within the using { ... }, in order to guarantee the proper disposal of objects.

Readability

Now that you've understood that the two pieces of code in your question are totally difference, since one is correct, and another one is buggy, let's talk readability.

Until C# 4.0, object initialization was slightly more readable than a similar constructor:

var product = new Product("PowerEdge R620 rack server", 1, "Intel® Xeon® E5-2620", 16, 1929, true);

Here, I have no idea what is "1" or "16" or "1929". A person who is not at all familiar with hardware wouldn't know what "Intel® Xeon® E5-2620" is. No one would find what is true.

Instead:

var product = new Product
{
    Title = "PowerEdge R620 rack server",
    RackUnits = 1,
    ProcessorName = "Intel® Xeon® E5-2620",
    MemoryInGB = 16,
    PriceInDollars = 1929,
    IsAvailable = true,
}

is much more readable.

.NET Framework introduced named arguments, and since then, a constructor can be as readable as an object initializer, while being more compact. For example, title is explicit enough, and we would consider that anyone will understand the names of processors, so we can write:

var product = new Product(
    "PowerEdge R620 rack server",
    "Intel® Xeon® E5-2620",
    rackUnits: 1,
    memoryInGB: 16,
    priceInDollars: 1929,
    isAvailable: true);

I have an office mate that told me that object initialization is much readable and faster than constructor.

We have seen that with named arguments, a constructor can be as readable as an object initializer. What about performance?

Above, I've explained that an object initializer this.a = new A { B = b } is translated by the compiler into:

A temp = new A();
temp.B = b;
this.a = temp;

If the only thing the constructor is doing is to assign fields or properties from arguments, then the performance would be approximately the same. Unless your office mate can give precise profiling results and benchmarks proving his point, his statement about the performance should be considered wrong.


问:
Formatting SQL statements
In recent years I've developed a habit of formatting SQL SELECT queries like so:

```<code>SELECT
    fieldNames
FROM
    sources
    JOIN tableSource ON col1 = col2
    JOIN (
        SELECT
            fieldNames
        FROM
            otherSources
     ) AS subQuery ON subQuery.foo = col2
WHERE
    someField = somePredicate
</code>```

So you see my pattern: each keyword is on its own line and that keyword's fields are indented by 1 tab-stop and the pattern is used recursively for sub-queries.

This works well for all of my SELECT queries, as it maximizes readability though at the cost of vertical space; but it doesn't work for things like INSERT and UPDATE which have radically different syntax.

```<code>INSERT INTO tableName
       (  col1,   col2,   col3,   col4,   col5,   col6,   col7,   col8  )
VALUES ( 'col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7', 'col8' ),
VALUES ( 'col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7', 'col8' )

UPDATE tableName
SET
    col1 = 'col1',
    col2 = 'col2',
    col3 = 'col3',
    // etc
WHERE
    someField = somePredicate
</code>```

As you can see, they aren't as pretty, and when you're dealing with tables with a lot of columns they quickly become unweildly.

Is there a better way to format INSERT and UPDATE? And what about CREATE statements and other operations?

答:
I don't think the Update example you gave is really any different than the Select statement. Keeping one field per line works regardless of the number.

The insert statement is another matter. The example you gave isn't something that goes into production for most programs. This could be a way to hardcode values into some reference table. Usually it's some script for data management. For an application, the values are usually set to a parameter.

```<code>Insert into MyTable(Field1) Values(@Field1Value);
</code>```

Like most things, this is easy to manage when you have a few fields, but when you have a lot, it becomes a problem. I think the key to any solution is a way to manage the one-to-one relationship with the field list and the values. Keeping a reasonable number on each line (3-8 depending on the length of the names) as long as you are consistent. Another advantage of parameters, is their names can have a lot more meaning if they are close to the field name (I think my example achieves that.).

If the list of inserts gets too long, you would be better off pulling those values from an external file (text, spreadsheet) that has some sort of field naming structure:

```<code>Insert into MyTable (Field1)
select OtherField1 from ExternalSourceFile.
</code>```

I realize the question wants to manage this in an actual code statement, but typing the data into something like a spreadsheet is easier to view and manage and the code is much easier to read. Also, you can alter the data without having to change the sql statement.

Title: Formatting SQL statements

Body:
I don't think the Update example you gave is really any different than the Select statement. Keeping one field per line works regardless of the number.

The insert statement is another matter. The example you gave isn't something that goes into production for most programs. This could be a way to hardcode values into some reference table. Usually it's some script for data management. For an application, the values are usually set to a parameter.

Insert into MyTable(Field1) Values(@Field1Value);

Like most things, this is easy to manage when you have a few fields, but when you have a lot, it becomes a problem. I think the key to any solution is a way to manage the one-to-one relationship with the field list and the values. Keeping a reasonable number on each line (3-8 depending on the length of the names) as long as you are consistent. Another advantage of parameters, is their names can have a lot more meaning if they are close to the field name (I think my example achieves that.).

If the list of inserts gets too long, you would be better off pulling those values from an external file (text, spreadsheet) that has some sort of field naming structure:

Insert into MyTable (Field1)
select OtherField1 from ExternalSourceFile.

I realize the question wants to manage this in an actual code statement, but typing the data into something like a spreadsheet is easier to view and manage and the code is much easier to read. Also, you can alter the data without having to change the sql statement.


问:
Forcing people to read and understand code instead of using comments, function summaries and debuggers?
I am a young programmer (finished computer science university but still under a year of working in the industry) and I recently got a job working on some C code for a decent size web service. Looking at the code the only places I saw comments were when people were stashing their old code. Function and variable names are similarly informative most of the time - futex_up(&ws->g->conv_lock[conv->id%SPIN]);. Confronting a senior programmer about the situation and explaining that adding comments and meaningful names would make the code more maintainable and readable in the future, I got this reply:

In general, I hate comments. Most of them time, like the case you
  mention with the return value, people use comments to get around
  reading the code. The comments don't say anything other than what the
  guy thought the code does at the time he put in the comment (which is
  often prior to his last edit). If you put in comments, people won't
  read the code as much. Then bugs don't get caught, and people don't
  understand the quirks, bottlenecks, etc. of the system. That's
  provided the comments are actually updated with code changes, which is
  of course totally unguaranteed.

I want to force people to read the code. I hate debuggers for a
  similar reason. They are too convenient and allow you to step through
  dirty code with watches and breakpoints and find the so-called
  problem, when the real problem was that there are bugs in the code
  because the code has not been simplified enough. If we didn't have the
  debugger, we would refuse to read ugly code and say, I have to clean
  this up just so I can see what it is doing. By the time you are done
  cleaning up, half the time the bug just goes away.

While what he wrote goes against a lot I have been taught in the university, it does make some sense. However, since experience in the studies sometimes doesn't work in real life, I would like to get an opinion of people more vetted in code.

Is the approach of avoiding commenting code to make people actually read the code and understand what is going on make sense in a medium-sized coding environment (one that can be reasonably read in whole by every person working on it within a month or two), or is it a recipe for a long-term disaster? What are the advantages and disadvantages of the approach?

答:
Comments are for who, when, why, assumptions, dependancies, and possibly how.

Who wrote this? Who do I go and bug if I have questions about it?

When did they write it?

Why did they write it? What was the business reason that they spent time writing code?

Why did they pick this approach and what other approaches did they reject, and why?

What assumptions did they make? What beliefs about the organisation did they hold?

What things are required to happen for this code to execute successfully? What libraries, objects, environments or other things is it dependent on?

What are the situations in which the code might fail and how does the code deal with those failures? How do I deal with them?

As for the "how", comments should only explain how the code works if it is complicated and hard to understand (and if it is then perhaps the programmer should have put more effort into simplifying it).


答:
I used to comment a lot, now very little, making the code and variable names readable is the way to go.

I add comments for real 'gotchas' and 'why this was done that isn't (yet) obvious from the code'.

But to your REAL question.

I note that your title starts with the word:  "forcing"

I also note that the first paragraph mentions "confronting"

I used the exact same words 20 years ago myself :)

This (IMHO of course) is what programming is really about - how different people with different styles, opinions, experience, knowledge and background can work together.

There is no simple fix, no list of programmatic steps to take, no single conversation to set things right.  I would recommend that you think over the following points that I have learned from my experience of 20 years.

Listen

Listen

Listen.  Sorry to make it such a big deal but nothing will help you more in your career now than asking questions and listening even if the answer don't make sense.

Ask question and just listen to the answers even if you disagree or don't fully understand them.  There is nearly always a second chance to revisit things.

Accept that wring things get done sometimes.  If they are really bad decisions that will continue to show and one can make a case later to make them better.  But emphasis on the later.  Good enough for now is something you have to accept sometimes so you can more on for now.

Pick your battles on things that are wrong.  Learn to hold your tongue unless the item is really really important to you and even then pick your battles very carefully - and try to make then conversations and not battles!

Accept differences.  Outside of academia you will need to accept more differences and focus a (little) less on finding the 'correct and true' way to do things and more on what works for today and for the business you are workgin in.

Avoid black and white conversations.  Don't be absolutist about the 'right thing'  avoid words that are absolutist like 'must', 'only', 'impossible', etc. and use words like 'should' 'often' and 'hard'.

Use concrete examples in conversation rather than theory.  Don't avoid theory but in conversations try to have real examples for your points.  If you don't have real world examples yet this may be a indicator that you should listed more than talk.

Emphasize your youth and ignorance in conversations with more experienced programmers such as the one you mention.  You will impress them more with humbleness than boasting about your recently gained knowledge.

Title: Forcing people to read and understand code instead of using comments, function summaries and debuggers?

Body:
I am a young programmer (finished computer science university but still under a year of working in the industry) and I recently got a job working on some C code for a decent size web service. Looking at the code the only places I saw comments were when people were stashing their old code. Function and variable names are similarly informative most of the time - futex_up(&ws->g->conv_lock[conv->id%SPIN]);. Confronting a senior programmer about the situation and explaining that adding comments and meaningful names would make the code more maintainable and readable in the future, I got this reply:

In general, I hate comments. Most of them time, like the case you
  mention with the return value, people use comments to get around
  reading the code. The comments don't say anything other than what the
  guy thought the code does at the time he put in the comment (which is
  often prior to his last edit). If you put in comments, people won't
  read the code as much. Then bugs don't get caught, and people don't
  understand the quirks, bottlenecks, etc. of the system. That's
  provided the comments are actually updated with code changes, which is
  of course totally unguaranteed.

I want to force people to read the code. I hate debuggers for a
  similar reason. They are too convenient and allow you to step through
  dirty code with watches and breakpoints and find the so-called
  problem, when the real problem was that there are bugs in the code
  because the code has not been simplified enough. If we didn't have the
  debugger, we would refuse to read ugly code and say, I have to clean
  this up just so I can see what it is doing. By the time you are done
  cleaning up, half the time the bug just goes away.

While what he wrote goes against a lot I have been taught in the university, it does make some sense. However, since experience in the studies sometimes doesn't work in real life, I would like to get an opinion of people more vetted in code.

Is the approach of avoiding commenting code to make people actually read the code and understand what is going on make sense in a medium-sized coding environment (one that can be reasonably read in whole by every person working on it within a month or two), or is it a recipe for a long-term disaster? What are the advantages and disadvantages of the approach?


问:
Should I fully parenthesize expressions or rely on precedence rules?
Let's say I have a boolean condition a AND b OR c AND d and I'm using a language where AND has a higher order of operation precedence than OR. I could write this line of code:

```<code>If (a AND b) OR (c AND d) Then ...
</code>```

But really, that's equivalent to:

```<code>If a AND b OR c AND d Then ...
</code>```

Are there compelling arguments in favor or against including the extraneous parentheses?

Does practical experience suggest that including them significantly improves readability?

Or is wanting them a sign that a developer really needs to sit down and become conversant in the  basics of their language?

答:
"Should I use parentheses in logical statements even where not necessary."

Yes, because two people will find them helpful:

The next programmer, who's knowledge, competency or style may be different

The future you who returns to this code at some later date!

ContentLicense: CC BY-SA 4.0


问:
As a self-taught programmer, how do I get the academic foundation without attending school again?
I've made a pretty good living as a self-taught programmer, but when I find that I discuss some low-level fundamental topics with my peers who have a CS degree, holes appear in my knowledge. I'm a big picture (architecture) guy, so for a long time this hasn't bothered me, but lately I've wondered if there is an approach I can take that will help me learn these fundamentals without going back to school? Are there books, websites or videos that you can recommend that would give me a ground-up perspective as opposed to a learn it as you need it mentality?</p>

答:
Here is a list of the most famous online academic level learning portals (check computer science category)  :

edx

udacity

Coursera

please note that courses there are thought by top world universities like MIT,Stanford,... and you can have a certificate for passing courses after entering real mid-term, final exams and for sure submit homeworks ;)

it might keep you busy for couple of years :)

For MIT OpenCourseWare edx might be the successor as MIT has many classes there !

In General there is a trend now from universities on giving high quality academic courses online for free or very low cost. check this wikipedia entry.

ContentLicense: CC BY-SA 2.5


问:
Is it normal that I can't keep in my head more than three bugs assigned to me, nor can I understand a thousand lines of spaghetti code?
I'm working on an old codebase which is... not perfect, in an environment which isn't either. It's not the worst codebase I've seen in my life, but there are still lots of issues: zero unit tests; methods with thousand+ lines of code; misunderstanding of basic object oriented principles; etc.

It hurts to maintain the code.

Every time I have to debug a thousand lines of a badly written method with variables reused all over, I'm totally lost.

Some modifications or refactoring I've done introduced bugs in other places of the application.

Lacking any documentation, tests, or an observable architecture and combined with badly named methods, I feel that I fill up all of my available working memory. There is no room left over for all the other things I have to remember in order to understand the code I should modify.

Constant interruptions at the workplace disturb me and slow me down.

I can't remember more than two or three tasks at a time without a bug tracking system, and I forget all of them over the weekend.

My colleagues don't seem to have similar issues.

They manage to debug badly written methods much faster than me.

They introduce fewer bugs than I do when changing the codebase.

They seem to remember very well all they need to in order to change the code, even when it requires reading thousands of lines of code in twenty different files.

They don't appear to be disturbed by emails, ringing phones, people talking all around, and other people asking them questions.

They don't want to use the bug tracking system that we already have since we use TFS. They prefer to just remember every task they should do.

Why does this happen? Is it a particular skill developers acquire when working with badly written code for a long time? Does my relative lack of experience with bad code contribute to these problems / feelings? Do I have issues with my memory?

答:
CAVEAT/UPDATE: After reading the below answer, I felt it might be feel a little too harsh. Not my intention, the environment you describe is terrible and it would affect most people (probably even the better programmers suffer it, but they are "better" by comparation with others in the same environment). My answer is just a point-by-point reflection in your questions, assuming that the environment won't change (even if it should).

Totally opinable answer:

1) That depends of experience in the technology, in maintaining the application(more if it is bad designed) and even in specific parts of the application. Also depends of your concentration problems (number 4)

2) It is the same than number 1, but using a different metric. Same answer.

3) noteblock and pen. Or a word/excel document. Not that hard to solve.

4) that is a personal issue of concentration. Not sure if it is viable to improve it by yourself, though.

5) using a ticket system or not should not be decided by the programmers but by the project manager. Ask his opinion/present your points. If he is against it, noteblock and pen again.


答:
there are 3 main points that I see:

points 1, 2 and 3 stem from the fact that your colleagues are simply more experienced with the codebase which means they know its quirks. This means that they use their long-term memory for the debug process and can remember that doXYZ actually does UVW but was never renamed for historic reasons. however should they ever take a few months of from coding on it then they will start to feel your pain.

for point 4 resist interruptions, don't let non-urgent business take you out of the zone, it takes a long time to get back into it after an interruption; set the company's IM to busy, try to schedule in long blocks (full afternoons) of just coding

for point 5 second create an excel sheet with the bugs you are currently working on as your personal todo list, (or use the task management capabilities in your IDE), I'm willing to bet that some of your colleagues are doing the same

Title: Is it normal that I can't keep in my head more than three bugs assigned to me, nor can I understand a thousand lines of spaghetti code?

Body:
I'm working on an old codebase which is... not perfect, in an environment which isn't either. It's not the worst codebase I've seen in my life, but there are still lots of issues: zero unit tests; methods with thousand+ lines of code; misunderstanding of basic object oriented principles; etc.

It hurts to maintain the code.

Every time I have to debug a thousand lines of a badly written method with variables reused all over, I'm totally lost.

Some modifications or refactoring I've done introduced bugs in other places of the application.

Lacking any documentation, tests, or an observable architecture and combined with badly named methods, I feel that I fill up all of my available working memory. There is no room left over for all the other things I have to remember in order to understand the code I should modify.

Constant interruptions at the workplace disturb me and slow me down.

I can't remember more than two or three tasks at a time without a bug tracking system, and I forget all of them over the weekend.

My colleagues don't seem to have similar issues.

They manage to debug badly written methods much faster than me.

They introduce fewer bugs than I do when changing the codebase.

They seem to remember very well all they need to in order to change the code, even when it requires reading thousands of lines of code in twenty different files.

They don't appear to be disturbed by emails, ringing phones, people talking all around, and other people asking them questions.

They don't want to use the bug tracking system that we already have since we use TFS. They prefer to just remember every task they should do.

Why does this happen? Is it a particular skill developers acquire when working with badly written code for a long time? Does my relative lack of experience with bad code contribute to these problems / feelings? Do I have issues with my memory?


问:
btnBack vs backButtonField
For blackberry GUI developement.  I am using the name convention like backButtonField and some of my colleagues are using btnBack.

But sometimes I stuck with the names like loginVerticalFieldManager its a very long name.  At that time vfmLogin looks better

So for GUI components names what convention should I follow?

答: Try to imagine whether someone else will be able to figure out what the variable is for based on the name.  backButton and btnBack can probably be deduced, but vfmLogin is pretty cryptic.  I try to avoid acronyms for variable names.  Something more clear is usually just a few more keystrokes, and it will usually be much more readable.</p>

Title: btnBack vs backButtonField


答:
Yes, it is normal for structured people to be affected by unstructured code/environments. Your colleagues probably are better filtering out all the background noise. As a migraine sufferer I know my ability to filter out my environment greatly drops when a migraine is coming on. People vary.

The same is true for the code, your colleagues have probably learned to filter out the "code noise" that comes from multiple levels of abstraction in a single method and have become adept at "chunking" the code into larger areas of functionality.

It simply takes time to adapt to a code base such as the one you describe. Your colleagues probably have had much more time to grow into it and possibly have picked up on conventions, patterns and constructs that don't jump out on "code base novices". There may be more structure to the chaos than you can imagine. Talk to your colleagues, ask them to pair with you some time and pick their brains on how they approach solving one of the bugs assigned to you. When they ask you to open unit X, Y or Z, ask them why that one, what about it is telling them it may be relevant, etc.

Being lost in a thousand-lines method is normal. Attack it with a good folding editor and adding comments to chunk the various parts into functions and/or procedures without actually doing so. Printing the stuff and using an old fashioned highlighter can also help.

Refactoring without the safety net of unit tests is shooting yourself in the foot. Don't. Just don't.

Nobody is requiring you to keep everything in memory. If your colleagues don't want or need a bug system, just write the task assigned to you in your own todo list and write notes when/after talking with someone about the details of your tasks.


问:
How to ask a programmer a question without getting "Why" as the answer
We've all had this experience. You go to someone who you know has the answer to a question, ask that person the question and they answer with the typical response: "why?" You explain why you need to know, and they attempt to solve your problem.

It takes time, arm twisting and patience to steer the conversation back to the original question and just get that darn answer.

Why do programmers constantly do this, and why does the behavior get worse the more senior the programmer becomes?

How can you ask a programmer a question in a way most efficient in extracting the answer to the original question?

答:
"The question is specifically how does one engage with another programmer to ask a question, where the other has the answer and skip the debate about why the question is being asked."

You can't, at least not deterministically. The other programmer is a person, not a computer, and not your servant. If you ask them a question they get to choose what they think is the best answer. If they think they need more context they get to ask for it.

You could try prefacing your question with a statement that you are only looking for a short, bottom line answer, but they're still free to answer as they think best.


答:
Why do developers ask "why" when someone asks them how to implement a solution?

Because it requires more knowledge to evaluate whether a solution is appropriate than it does to actually implement the solution.

It's very difficult to believe someone when they say, "I don't know how to do this, but I know for sure it's what I need to do."  Programmers constantly insist on probing deeper because people constantly insist on asking the wrong questions.  Yes, sometimes it eventually comes back around to your original question, but not always.

As an analogy, imagine if someone walked up to a mechanic and asked him how to replace a car battery.  Usually if you're qualified to diagnose a defective battery, you're qualified to change one, so the mechanic will ask how you know it needs replacing.

He knows if he doesn't do this, and it turns out you don't need a battery, then you'll keep coming back asking more and more questions until eventually you figure out that you have to turn the lights off when the engine's not running.  By asking you up front, it feels like he's wasting your time, but really he knows from experience that he's potentially saving both of you a lot more time.

So, if you want to avoid the line of questioning, you need to convince him up front that you know what you're talking about.

Title: How to ask a programmer a question without getting "Why" as the answer

Body:
We've all had this experience. You go to someone who you know has the answer to a question, ask that person the question and they answer with the typical response: "why?" You explain why you need to know, and they attempt to solve your problem.

It takes time, arm twisting and patience to steer the conversation back to the original question and just get that darn answer.

Why do programmers constantly do this, and why does the behavior get worse the more senior the programmer becomes?

How can you ask a programmer a question in a way most efficient in extracting the answer to the original question?


答:
Doesn't sound like memory issues to me. It sounds like you your work habits/tendencies aren't a good fit for what you are encountering, and you're doing too much thinking about your colleagues and not yourself.

Thousand line method--everybody is going to be lost on that unless they
just worked on it.  They may be quicker at picking it up or getting it back.
You can't change that except through experience, and maybe not even then.

Refactoring introducing bugs, well, that's always a risk.  You can try to
develop unit test to cover what you're changing before doing so, but that may
not be allowed by management (probably not, or it would already be done). And
unit test aren't magic they can still miss things,  you can still introduce
bugs.  Chances are they just aren't refactoring.  This goes back to (1), they
probably try to focus on just what needs to be fixed, meaning they get to the
point faster, but miss the bigger picture, and will take longer to fix the next
thing in that thousand line mess.

Create what you need to get the job done.  If that means creating a flow
chart or some other documentation, then do so.  Whether they need it or not,
and whether they use it or not after you have created it, is irrelevant.

Interruptions slow everyone down.  Focusing on that will just slow you down
more.  Accept it and try to get back in the groove as quickly as you can.

Keeping two or three bugs in mind ain't bad, three or four would be better,
but instead of trying to improve that, give up and write it down.  Piece of
paper, whiteboard, tfs, excel, word or notepad -- just write it down.  I bet
that's what your colleagues are doing.  Either that or fixing things at random.

Programming isn't about a perfect memory, and it's not about being able to ignore distractions -- focusing on this are just distractions that you are creating.


问:
Shall we always use IoC in our designs?
I was studying Mediator Pattern and I noticed that to use this pattern you should register the Colleagues into Mediator from the Colleague concrete classes. for that we have to make an instance of Mediator inside Colleague concrete classes which violates IoC and you can not inject the Colleagues into Mediator  (as far as I know! whether it is right or wrong)

Questions:

1- Am I right about the thing I said?

2- Shall we always use IoC at all or there are some times you can forget about it?

3- If we always have to use IoC, can we say Mediator is an anti-Pattern?

答:
The mediator pattern helps in the communication between objects.

IoC is inversion of control i.e. instead of object getting a required resource one is provided to it.

These patterns are unrelated.

Title: Shall we always use IoC in our designs?


答:
No - I only see registration mentioned in the examples it is not prescribed in the pattern itself.

No - an IoC container is not prescribed in this pattern.

No - Given the two first assertions are incorrect, the third does not follow.

Title: Shall we always use IoC in our designs?

Body:
I was studying Mediator Pattern and I noticed that to use this pattern you should register the Colleagues into Mediator from the Colleague concrete classes. for that we have to make an instance of Mediator inside Colleague concrete classes which violates IoC and you can not inject the Colleagues into Mediator  (as far as I know! whether it is right or wrong)

Questions:

1- Am I right about the thing I said?

2- Shall we always use IoC at all or there are some times you can forget about it?

3- If we always have to use IoC, can we say Mediator is an anti-Pattern?


答:
Why do programmers constantly do this, and why does the behavior get worse the more senior the programmer becomes?

Unfortunately it's as far from general truth as it gets.

That behavior is restricted to the minority of really good ones. And you better should learn it too.

Just answering the damned question skipping over the whys is a good way to drive into a chasm, fast and sure.

If you really want to skip the educated part, you can prefix your question with a few sentences on limitations and your desire to skip questions -- you may get some answer or just sent off.  Presenting summary your own research is a better idea.


问:
TDD and Version Control
I am currently learning about TDD and trying to put it into practice in my personal projects. I have also used version control extensively on many of these projects. I am interested in the interplay of these two tools in a typical work flow, especially when it comes to the maxim to keep commits small. Here are some examples that come to mind:

I start a new project and write a simple test to create an as-yet-nonexistent class. Should I commit the test before writing the class even though the test doesn't even compile? Or should I stub out the minimum amount of code that is needed to get the test to compile before committing?

I find a bug and write a test to recreate it. Should I commit the failing test or implement the bug fix and then commit?

These are the two examples that come immediately to mind. Feel free to provide additional examples in your answer.

Edit:

I made an assumption in both examples that immediately after writing the test I will write code to make the test pass. Another situation might also arise: I work on a project using TDD for several hours without committing. When I finally make commits, I want to break up my work into small chunks. (Git makes this relatively easy even if you want to want to commit only some of the changes in a single file.)

This means that my question is as much about as what to commit as it is about when to commit.

答:
Should I commit the test before writing the class even though the test doesn't even compile? Or should I stub out the minimum amount of code that is needed to get the test to compile before committing?

Of course not. You should finish both the test and the class. Committing something1 that doesn't even compile makes no sense, and will certainly make people working on the same project angry if you do it regularly.

I find a bug and write a test to recreate it. Should I commit the failing test or implement the bug fix and then commit?

No, do not commit a failing test. LeBlanc's Law states :

Later equals never.

and your test might fail for a long time. It is better to fix the problem as soon as it is detected.

Also, TDD development style tells :

Test-driven development constantly repeats the steps of adding test cases that fail, passing them, and refactoring.

If you check in a failed test, that means you didn't complete the cycle.

1 When I said commit, I meant really commit to the trunk (for git users, push your changes, so other developers would get them).

Title: TDD and Version Control


答:
The question is specifically how does one engage with another
  programmer to ask a question, where the other has the answer and skip
  the debate about why the question is being asked.

You can't. Programmers, especially good ones, are wired to solve problems and to be efficient. When a customer or a fellow programmer comes looking for an answer - they will make sure to know the problem they are solving, before presenting a solution. That way they are efficient (they are not wasting your and their time by giving an answer that will not solve your problem) and they are solving real problems (by giving you solutions / answers to questions that you should be asking).

Example - when a client comes to you and says he wants an X feature implemented. Sometimes the client really needs an X feature and sometimes you really have to dig in and interrogate the customer just to find out that they don't want X but something completely different. The more older and experienced the programmers are, the more likely they were burned in the past by not getting to the heart of the problem before presenting a solution.

So to summarize - if you want your questions answered precisely you need to be sure that you're:

asking the right questions (thus you need to research the problem beforehand)

providing the context for the problem

sharing some of you're research to direct them faster to the problem

Most humans I know are just humans and not computers. If you just want answers try googling it.


答:
```<code>public abstract class Wrapper {
    private A theA;
    private B theB;
    // these are private on purpose.

    // add properties and methods for A and B stuff that you
    // want to expose. Make sure the names look like they're
    // all from one coherent class.
    // make them `protected` as needed for use by only the subclasses.

    // do not give a default constructor so you force subclasses
    // to build correctly
    public Wrapper (A a, B b) {
        // check for null!

        theA = a;
        theB = b;
    }
}
</code>```

Title: Similar references to themselves in two classes

Body:
How can I make 1 class (base, generic or something else) from these two classes?

```<code>class A
{
  A Link { get; set; }
}

class B
{
  B Link { get; set; }
}
</code>```

UPD: This is what I have now:

```<code>class BSTree
{
  public BSTNode Root { get; set; }
}

class AVLTree
{
  public AVLNode Root { get; set; }
}

class BSTNode
{
  public BSTNode Parent { get; set; }
  public BSTNode Left { get; set; }
  public BSTNode Right{ get; set; }
  public int Key{ get; set; }
}

class AVLNode
{
  public AVLNode Parent { get; set; }
  public AVLNode Left { get; set; }
  public AVLNode Right{ get; set; }
  public int Key{ get; set; }
  public int Height { get; set;}
}
</code>```

And finally I want to get something like BaseNode and BaseTree.


答:
I have used a Framework, RobotLegs, that automates dependency injection as part of how it works, and it very heavily depends on Mediator. Typically, the Mediator only knows in detail about one of the Colleagues (the View), and then it will get a generic reference to a communication channel that implements an Interface.

Both the reference to the View and the event bus are supplied through dependency injection. The default Mediator implementation declares an interest in the event bus, and so the IoC container supplies the one it has on file. Specific Mediator Classes are registered for use with specific Views, and the Mediator will be created when the View is put into use. It exposes a variable whose type matches the View and the IoC container will then provide the new View instance to the Mediator that was created.

How this works in your framework/language of choice will vary, but there is no reason that the Colleagues can't be provided through Dependency Injection. Under no circumstances should the Colleagues even be aware of, much less be responsible for creating, the Mediator.

Title: Shall we always use IoC in our designs?


问:
Design patterns: Extract instance types into different buckets
I have the following type hierarchy:

```<code>interface I:
    ----+class B implements I
    ----+class C implements I
    ----+class D implements I
</code>```

I have another class Consumer1 that supports types C and D but not B (in its various methods) and a class Consumer2 that supports type B. I have total control over Consumer1 and Consumer2 so I can choose how to implement them. Now, at runtime I expect my callers to give me a collection of Is and I will decide internally whether to route them to Consumer1 or Consumer2.

Now, a very bad non-OOP way is to do an if instanceof check all over the place and mess things up. One alternative is to register a supporting class Map<Class<?>, Class<?>> that shall contain {{B,Consumer2}, {C,Consumer1}, {D,Consumer1}}. This is as bad as the previous one because I shall have to cast objects after figuring out whether to send them to Consumer1 or Consumer2.

A second alternative is to apply a Visitor pattern which would solve this rather neatly but prevent my interface from being extended further (unless I modify the visitor). Is there a neater alternative?

答: Why is consumers not able to do their work with just I interface? Consumers should require instances of I, not rely on specifics of B,C or D.</p>


问:
How do you convince management to throw away a prototype?
I love prototyping as a fast effective way to put a UI in front of a user.

Many times though, management get their beaks in the way, and the prototype is dragged kicking and screaming into main stream development.

How do you manage management into not doing this?

答:
Don't Worry About It.

If you sit down and throw UI controls for a "prototype", there is exactly zero reason you should ever automatically throw away that design.  If it was good enough to show management, then it's a good place to start when to code the "real" program.

Moving from a prototype to a more "polished" UI should be nothing more than a series of entirely justifiable steps.  You had to add a second button.  You got feedback from users that they found the order confusing.  Your organization's standards group dictated a minor change.  You had to change the size of a text box for internationalization.

Not a single one of those reasons is "well, it was just a prototype."  In UI design or in code or in writing, ANYTHING can wind up living forever. And those that don't all should have very good reasons to kill them.

And management probably doesn't care.

Realistically, if the reason you didn't just drop in your UI to the existing code was "I had to re-write it in our correct framework", that should be enough of a reason.  And if it wasn't, you should probably have a discussion about the UI framework itself, but that's another question.


答:
In my work flow, whenever possible I do uncertain work on a personal source-control branch.  So I can try, fail, try again if necessary until it works, and only commit to the larger project when I have actual working code.

From a TDD perspective, the question of "do you check-in the test first?" is entirely dependent upon the code that you're working on.  If it's new code, you don't check in anything until you have something worth checking-in.  But if it's a bug found in already compiled or shipped code, checking in a test to reproduce the bug, BY ITSELF, is worth checking in.  Especially if it's the end of a work-day, and you will leave the office before you fix the code.

(Of course, if your shop has an automated build process that dies if any unit-tests fail, you may not want to check in a failing test until you fix the bug.  But that seems like an odd way to work, since "find and document bugs" and "fix bugs" can be done by two entirely different teams.)

Title: TDD and Version Control

Body:
I am currently learning about TDD and trying to put it into practice in my personal projects. I have also used version control extensively on many of these projects. I am interested in the interplay of these two tools in a typical work flow, especially when it comes to the maxim to keep commits small. Here are some examples that come to mind:

I start a new project and write a simple test to create an as-yet-nonexistent class. Should I commit the test before writing the class even though the test doesn't even compile? Or should I stub out the minimum amount of code that is needed to get the test to compile before committing?

I find a bug and write a test to recreate it. Should I commit the failing test or implement the bug fix and then commit?

These are the two examples that come immediately to mind. Feel free to provide additional examples in your answer.

Edit:

I made an assumption in both examples that immediately after writing the test I will write code to make the test pass. Another situation might also arise: I work on a project using TDD for several hours without committing. When I finally make commits, I want to break up my work into small chunks. (Git makes this relatively easy even if you want to want to commit only some of the changes in a single file.)

This means that my question is as much about as what to commit as it is about when to commit.


答:
Certainly you start with using a healthy source control like git.

Then you can work the way you like, and commit at each corner -- any step or substep is a fair game.

Then before pushing the stuff you squash the whole work into a single commit. Or a couple, at points where everything is green and the composition makes sense. And push those sensible commits. For the multiple case, make it a branch that you merge with --no-ff.

The source control is not a work-tracking system or a historian. The commits shall present a sensible coherent delta, while the checkout state shall be compiling at least. Intermediates may be preserved for a while for review purposes, but once everything is considered okay, a single commit per feature is fair.

Title: TDD and Version Control


答:
Hungarian was good when we didn't have IDEs and plugins for the IDEs that would let us find what we were looking for other than by cruising through a drop down list that might, if you were lucky, be alphabetized. With VS2008 or 2010 and resharper, I'm 2 or 3 keystrokes from a search dialog to let me type in "Button" and finding BackButton, OkButton, CancelButton far more quickly than hunting through a drop down.

In general, I've gotten tired of goofy naming conventions. If I wrote a manual on how to use my software I would direct my user to use the "Back button", therefore it's fairly intuitive to name the object BackButton. Your vocabulary remains the same when your talking to a Business Analyst as when you're talking to another programmer and I can't see anything wrong in that.

The other problem with any sort of abbreviation as a prefix that isn't super intuitive is that in an OO world, it quickly falls flat on it's face and everything ends up being obj or ctrl (for the UI components). I really can't find much use in that. Those drop down lists (esp the VS drop downs that only do 1 character for type ahead) become a pain in that case. When there's 3 btns on a list, hey, that's easy. When there's 20 ctrls on that list, you're back at square one.

Title: btnBack vs backButtonField

Body:
For blackberry GUI developement.  I am using the name convention like backButtonField and some of my colleagues are using btnBack.

But sometimes I stuck with the names like loginVerticalFieldManager its a very long name.  At that time vfmLogin looks better

So for GUI components names what convention should I follow?


问:
Perform operations in the entry-script, or create a class which just instantiates and calls methods?
I'm building a perl application which does the following operations:

Copy a bunch of files (class fileFetcher )

Parse each file (class fileParser)

Store some data from each file in a database (class dbHelper)

Now, should I, in my main.pl (entry point of the script), construct an instance of each of these and call the appropriate methods?
or is it better practice to have a separate "Application" class that does all the instantiations and method calls, and let the main script just have a call like Application.run(args)?

The class, would exist just to instantiate and call methods on things, and doesn't seem right.

答:
Apply the YAGNI principle - as long as you have only 3 objects, and only one entry point into your script, you most probably don't need that additional Application class, so don't create it. This  would not make your code more readable or better maintainable - so why bother (for now).

However, when your script becomes bigger in the future, and your main.pl gets additional responsibilities, it may be a good idea to refactor the instantiation code of those combined operations into a separate function. Giving that function a meaningful name describing the operation as a whole would be very good idea. Furthermore, when your program grows to a state where this operation is just one of many other operations, that would be an even better reason to refactor things out of main.

When it shows up later that this operation needs additional "global" state or environment information, then this new function may be refactored into a class to make that global state a member variable of that class. That class typically won't get the name Application, since this name is not very descriptive for what the operation does. But refactor when this happens, not beforehand.

AFAIK the notion of having a separate Application class comes from some (mostly C++) GUI frameworks where this is standard way of definining a kind of entry point and globally available object. See, for example, this SO post, about the QApplication class in the Qt framework. I don't know if there are Perl frameworks out there with a similar approach, but as long as you are not using or creating such a framework, I don't see a point to add an Applicationclass to your Perl script.


问:
Reason for return statement in recursive function call
I just had a doubt in my mind. The following subroutine(to search an element, in a list, for example) has a return statement at the end:

```<code>list *search_list(list *l, item_type x) {
  if (l == NULL) return(NULL);
  if (l->item == x)
    return(l);
  else
    return( search_list(l->next, x) );
}
</code>```

I cannot get the significance of return statement at the end
(i.e. return search_list(l->next, x) ). It would be really helpful if anyone could explain this concept, using stack model.

答:
Two things; Returning the entire list in the case that you find the "x" you're looking for doesn't necessarily warrant using recursion, but that aside, consider the following:

Suppose you are seeking a value of X = "December", and your list is the numeric value of the months of the year, a pointer to the next month, and the l->items in the list are the spelled out names of the months. (January, February, ..., December).  You need the three returns for the possible outcomes.  The first, return(NULL) is needed if the list doesn't contain the X you're looking for. The second, (return(l)) returns the list, in this case, letting you know you found your "x".  The last is where the stack model comes into play.  Successive calls to the function would have updated local variables (specifically, l->item's) like this:

```<code>1: l->item = January
   returns search_list(l->next, x)
2: l->item = February
   returns search_list(l->next, x)
3-11: March, April, May, June, July, August, September, October, November
   all return search_list(l->next, x)
12: l->item = December
  This matches the second if() and returns your list, letting you know you found your search item.
</code>```

Body:
Two things; Returning the entire list in the case that you find the "x" you're looking for doesn't necessarily warrant using recursion, but that aside, consider the following:

Suppose you are seeking a value of X = "December", and your list is the numeric value of the months of the year, a pointer to the next month, and the l->items in the list are the spelled out names of the months. (January, February, ..., December).  You need the three returns for the possible outcomes.  The first, return(NULL) is needed if the list doesn't contain the X you're looking for. The second, (return(l)) returns the list, in this case, letting you know you found your "x".  The last is where the stack model comes into play.  Successive calls to the function would have updated local variables (specifically, l->item's) like this:

1: l->item = January
   returns search_list(l->next, x)
2: l->item = February
   returns search_list(l->next, x)
3-11: March, April, May, June, July, August, September, October, November
   all return search_list(l->next, x)
12: l->item = December
  This matches the second if() and returns your list, letting you know you found your search item.


问:
Duck typing, data validation and assertive programming in Python
About duck typing:

Duck typing is aided by habitually not testing for the type of arguments in method and function bodies, relying on documentation, clear code and testing to ensure correct use.

About argument validation (EAFP: Easier to ask for forgiveness than permission). An adapted example from here:

...it is considered more pythonic to do :

```<code>def my_method(self, key):
    try:
        value = self.a_dict[member]
    except TypeError:
        # do something else
</code>```

This means that anyone else using your code doesn't have to use a real dictionary or subclass - they can use any object that implements the mapping interface.

Unfortunately in practise it's not that simple. What if member in the above example might be an integer ? Integers are immutable - so it's perfectly reasonable to use them as dictionary keys. However they are also used to index sequence type objects. If member happens to be an integer then example two could let through lists and strings as well as dictionaries.

About assertive programming:

Assertions are a systematic way to check that the internal state of a program is as the programmer expected, with the goal of catching bugs. In particular, they're good for catching false assumptions that were made while writing the code, or abuse of an interface by another programmer. In addition, they can act as in-line documentation to some extent, by making the programmer's assumptions obvious. ("Explicit is better than implicit.")

The mentioned concepts are sometimes in conflict, so i count on the following factors when choosing if i don't do any data validation at all, do strong validation or use asserts:

Strong validation. By strong validation I mean raising a custom Exception (ApiError for example). If my function/method is part of a public API, it's better to validate the argument to show a good error message about unexpected type. By checking the type I do not mean using only isinstance, but also if the object passed supports the needed interface (duck typing). While I document the API and specify the expected type and the user might want to use my function in an unexpected way, I feel safer when I check the assumptions. I usually use isinstance and if later I want to support other types or ducks, I change the validation logic.

Assertive programming. If my code is new, i use asserts a lot. What are your advices on this? Do you later remove asserts from the code?

If my function/method is not part of an API, but passes some of its arguments through to a other code not written, studied or tested by me, I do a lot of asserts according to the called interface. My logic behind this - better fail in my code, then somewhere 10 levels deeper in stacktrace with incomprehensible error which forces be to debug a lot and later add the assert to my code anyway.

Comments and advices on when to use or not to use type/value validation, asserts? Sorry for not the best formulation of the question.

For example consider the following function, where Customer is a SQLAlchemy declarative model:

```<code>def add_customer(self, customer):
    """Save new customer into the database.
    @param customer: Customer instance, whose id is None
    @return: merged into global session customer
    """
    # no validation here at all
    # let's hope SQLAlchemy session will break if `customer` is not a model instance
    customer = self.session.add(customer)
    self.session.commit()
    return customer
</code>```

So, there several ways to handle validation:

```<code>def add_customer(self, customer):
    # this is an API method, so let's validate the input
    if not isinstance(customer, Customer):
        raise ApiError('Invalid type')
    if customer.id is not None:
        raise ApiError('id should be None')

    customer = self.session.add(customer)
    self.session.commit()
    return customer
</code>```

or

```<code>def add_customer(self, customer):
    # this is an internal method, but i want to be sure
    # that it's a customer model instance
    assert isinstance(customer, Customer), 'Achtung!'
    assert customer.id is None

    customer = self.session.add(customer)
    self.session.commit()
    return customer
</code>```

When and why would you use each of these in the context of duck typing, type checking, data validation?

答:
Let me give some guiding principles.

Principle #1.  As outlined in http://docs.python.org/2/reference/simple_stmts.html the performance overhead of asserts can be removed with a command line option, while still being there for debugging.  If performance is a problem, do that.  Leave the asserts.  (But don't do anything important in the asserts!)

Principle #2.  If you're asserting something, and will have a fatal error, then use an assert.  There is absolutely no value in doing something else.  If someone later wants to change that, they can change your code or avoid that method call.

Principle #3.  Do not disallow something just because you think it is a stupid thing to do.  So what if your method allows strings through?  If it works, it works.

Principle #4.  Disallow things that are signs of likely mistakes.  For instance consider being passed a dictionary of options.  If that dictionary contains things that are not valid options, then that's a sign that someone didn't understand your API, or else had a typo.  Blowing up on that is more likely to catch a typo than it is to stop someone from doing something reasonable.

Based on the first 2 principles, your second version can be thrown away.  Which of the other two you prefer is a matter of taste.  Which do you think more likely?  That someone will pass a non-customer to add_customer and things will break (in which case version 3 is preferred), or that someone will at some point want to replace your customer with a proxy object of some kind that responds to all of the right methods (in which case version 1 is preferred).

Personally I've seen both failure modes.  I'd tend to go with version 1 out of the general principle that I'm lazy and it is less typing.  (Also that kind of failure usually tends to show up sooner or later in a fairly obvious way.  And when I want to use a proxy object, I get really annoyed at people who have tied my hands.)  But there are programmers I respect who would go the other way.


答:
A return statement passes a value back to the immediate caller of the current function's call-frame. In the case of recursion, this immediate caller can be another invocation of that same function.

In most languages, if you don't use the return value of a function you called (recursively or not), either that return value gets discarded or it is a diagnosable error. There are some languages where the return value of the last function call gets automatically re-used as the return value of the current function invocation, but they don't differentiate between normal and recursive function calls.

Assuming unused return values get silently discarded, if you had written the code like this:

```<code>list *search_list(list *l, item_type x) {
  if (l == NULL) return(NULL);
  if (l->item == x)
    return(l);
  else
    search_list(l->next, x); // no return!
}
</code>```

then search_list would only return a defined value for an empty list (NULL) or if the first item matches the value you are searching for. As soon as the function goes into the recursive call, you don't know what the result will be, because the result of the recursive call gets discarded.

Additionally, you promise to return a value from your function, but you have a path (the recursive one) where you don't specify what value to return. Depending on the language you use, this usually results either in a mandatory diagnostic or in undefined behaviour (which is shorthand for: anything can happen and that can change at any time without notice. Don't hold anyone but yourself liable if it screws up your most important presentation). There are some situations where the missing return value might appear to work, but that might change the next time you run the program (with or without recompilation).

Title: Reason for return statement in recursive function call

Body:
I just had a doubt in my mind. The following subroutine(to search an element, in a list, for example) has a return statement at the end:

```<code>list *search_list(list *l, item_type x) {
  if (l == NULL) return(NULL);
  if (l->item == x)
    return(l);
  else
    return( search_list(l->next, x) );
}
</code>```

I cannot get the significance of return statement at the end
(i.e. return search_list(l->next, x) ). It would be really helpful if anyone could explain this concept, using stack model.

Body:
A return statement passes a value back to the immediate caller of the current function's call-frame. In the case of recursion, this immediate caller can be another invocation of that same function.

In most languages, if you don't use the return value of a function you called (recursively or not), either that return value gets discarded or it is a diagnosable error. There are some languages where the return value of the last function call gets automatically re-used as the return value of the current function invocation, but they don't differentiate between normal and recursive function calls.

Assuming unused return values get silently discarded, if you had written the code like this:

list *search_list(list *l, item_type x) {
  if (l == NULL) return(NULL);
  if (l->item == x)
    return(l);
  else
    search_list(l->next, x); // no return!
}

then search_list would only return a defined value for an empty list (NULL) or if the first item matches the value you are searching for. As soon as the function goes into the recursive call, you don't know what the result will be, because the result of the recursive call gets discarded.

Additionally, you promise to return a value from your function, but you have a path (the recursive one) where you don't specify what value to return. Depending on the language you use, this usually results either in a mandatory diagnostic or in undefined behaviour (which is shorthand for: anything can happen and that can change at any time without notice. Don't hold anyone but yourself liable if it screws up your most important presentation). There are some situations where the missing return value might appear to work, but that might change the next time you run the program (with or without recompilation).


答:
Should I commit the test before writing the class even though the test doesn't even compile?

No.

Should I commit the failing test

No.

You are talking about two paradigms here:

test driven development - which says nothing about committing code. Indeed, it tells you about how to write code and when you are done. So I'd consider every 'done' as a candidate for a commit.

agile development, specifically: "commit early and often" (which does not require TDD). The idea behind it is to have an early integration with other components in the system and thus get early feedback. If you commit in a DVCS locally, and don't push, it's worthless in that meaning. Local commits only help developers to structure their work.

My recommendation is: follow the circle of TDD until your code compiles, your tests are green and you got something to contribute to the system. Therefore you should cut your features vertically, e.g. for a new UI mask don't create the whole form and commit without the business logic, but rather implement one tiny aspect but in the frontend as well as the business logic as well in the persistence layer.

For a large bugfix, commit after each improvement (e.g. refactoring), even if the bug is not fixed yet. Tests should be green, and code must compile, though.

Title: TDD and Version Control


答: It is my understanding of the world that one commits to mark a point that it may be desirable to return to.  The point a which a test fails (but compiles) is definitely one such point.  If I were to wander off in the wrong direction trying to make a test pass, I would want to be able to revert the code back to the starting point and try again; I can't do this if I haven't committed.</p>

Title: TDD and Version Control


问:
Does Jar file shrinker affect performance
I've heard ProGuard's Jar shrinker affects the performance of you application. Is this true? And if so just how much slower does the Jar go shrinked compared to unshrinked?</p>

答:
Actually, "shrinking" can only make an application load faster. Once loaded, there should be little or no difference in speed, though memory consumption can decrease.

Basically, the shrinker removes unused code, which reduces the amount of class-loading work the JVM has to do and the amount of memory taken up by that code.


问:
Break on default case in switch
I am a bit puzzled on whenever or not to include break after the last case, often default.

```<code>switch (type) {
    case 'product':

        // Do behavior

        break;
    default:

        // Do default behavior

        break; // Is it considered to be needed?
}
</code>```

breaks sole purpose is in my understanding to stop the code from running through the rest of the switch-case.

Is it then considered more logical to have a break last due to consistency or skip having it due to the break applying no functional use whatsoever? Both are logical in different ways in my opinion.

This could to a certain degree be compared with ending a .php file with ?>. I never end with ?> mostly due to the risk of outputting blank spaces, but one could argue that it would be the logical thing to end the file with.

答:
There is no break necessary after the last case. I use the word "last"  (not default )because it is not necessary default case is the last case.

```<code>switch(x)
{
case 1:
//do stuff
break;

default:
//do default work
break;

case 3:
//do stuff

}
</code>```

And we know, a break  is necessary between two consecutive cases. Sometimes, I use if(a!=0) in my code for more readability when others refer my code. I can choose to use if(a), that would be a matter of my choice

Title: Break on default case in switch

Body:
There is no break necessary after the last case. I use the word "last"  (not default )because it is not necessary default case is the last case.

switch(x)
{
case 1:
//do stuff
break;

default:
//do default work
break;

case 3:
//do stuff

}

And we know, a break  is necessary between two consecutive cases. Sometimes, I use if(a!=0) in my code for more readability when others refer my code. I can choose to use if(a), that would be a matter of my choice


问:
How to sync clocks over networking for game development?
I'm writing a game that has a lot of time based aspects. I use time to help estimate player positions when the network stalls and packets aren't going through (and the time between packet's being received and not). It's a pacman type game in the sense that a player picks a direction and can't stop moving, so that system makes sense (or at least I think it does).

So I have two questions: 1) How do I sync the clocks of the games at the start since there is delay in the network. 2) Is it okay NOT to sync them and just assume that they are the same (my code is time-zone independent). It's not a super competitive game where people would change their clocks to cheat, but still.

The game is being programmed in Java and Python (parallel development as a project)

答:
I think it is definitely not OK to synchornize the clock in the system. User does not expect you to touch the system settings and many systems won't even let you to.

All you need is to have a correlation to convert timestamp from one side's clock to the other side's clock. On the other hand you need this correlation to be rather precise, say at least to a hundredth of a second, if you want to use it for predicting player positions. System clock won't ever be this well correlated between random machines. So you should establish the correlation yourself, using some variation on the NTP theme, probably embedded in your other messages to conserve network bandwidth.

The basic idea might be that with each packet you sent out timestamp you sent it and sequence number of and timestamp when you received last packet from the other side. From this you calculate the roundtrip: For example
if packet Q says it was sent at 1000 and packet P was received at 500, than given you sent packet P at 0 and are receiving Q at 800, the round-trip is (800 - 0) - (1000 - 500) = 300. There is no way to know the assymetry, so you just assume the packet takes half (150) ticks in either direction. And that remote timestamp is ahead of local by 1000 - (800 - 150) = 350 ticks. The round-trip will vary. If you assume the clock are reasonably precise, you should use a long-term average of the correlation.

Note, that you don't want to use system clock for the clock either. They may get resynchronized midway, throwing you off track. You should use clock(CLOCK_MONOTONIC) on Unix or GetTickCount on Windows (not sure how those APIs are wrapped in Java or Python right now).

Note: The SO_TIMESTAMP socket option (see socket(7) mentioned by ott-- in comment on the question) would be useful for separating out the effect of latency of the event loop that receives the packets. Whether it's worth the effort depends on just how good precision you need.


答:
Should I commit the test before writing the class even though the test doesn't even compile?

With a branching SCM (I saw you use Git) you should commit whenever you want a backup point ("I screwed up something; I will reset the working dir to the last backup point") or when you have a stable version. When you have a stable version (all tests pass), you should also consider merging the current feature branch into your main development branch.

Or should I stub out the minimum amount of code that is needed to get the test to compile before committing?

Up to you (git gives you the flexibility to commit whenever you like without affecting other members of your team, or your ability to work on different features). Just make sure you do not have multiple incomplete (non-working) features in the same branch at the same time (then they will block each other).

I find a bug and write a test to recreate it. Should I commit the failing test or implement the bug fix and then commit?

I usually make two commits for that, unless the test code is really small / trivial to write.

These are the two examples that come immediately to mind. Feel free to provide additional examples in your answer.

Edit:

I made an assumption in both examples that I immediately after writing the test I will write code to make the test pass.

That could be a wrong assumption to make. If you work alone (personal project) nothing stops you from always doing that. In one of my most successful projects (with regard to maintaining high code quality and TDD throughout development of the project) we defined tests sometimes weeks before implementing them (i.e. we would say "the "test_FOO_with_null_first_parameter" test is now defined as an empty function and commit it like that). Then we would take a sprint (or half a sprint) sometimes a month or so later, for just increasing the test coverage for the module. Since we had the tests already declared it was easy to estimate.

Another situation might also arise: I work on a project using TDD for several hours without committing. When I finally make commits, I want to break up my work into small chunks. (Git makes this relatively easy even if you want to want to commit only some of the changes in a single file.) This means that my question is as much about as what to commit as it is about when to commit.

I would say definitely commit to create backup points. This works very well for exploratory testing ("I will just add some prints throughout the code base, run and git reset --hard to remove them when I'm done) and for prototyping.

Title: TDD and Version Control


答:
Given the ambiguity that exists around the use of switch-case in most languages, when using it I would suggest always using a break statement, except when it is explicitly and by design not wanted.

Partly this is because is makes every case call look the same, which in my opinion would improve readability. But it also means if someone (even you) chooses to insert a case after the last one at a later stage, they don't need to concern themselves with checking the prior block, which could help reduce bugs when adding new code.

Title: Break on default case in switch

Body:
I am a bit puzzled on whenever or not to include break after the last case, often default.

```<code>switch (type) {
    case 'product':

        // Do behavior

        break;
    default:

        // Do default behavior

        break; // Is it considered to be needed?
}
</code>```

breaks sole purpose is in my understanding to stop the code from running through the rest of the switch-case.

Is it then considered more logical to have a break last due to consistency or skip having it due to the break applying no functional use whatsoever? Both are logical in different ways in my opinion.

This could to a certain degree be compared with ending a .php file with ?>. I never end with ?> mostly due to the risk of outputting blank spaces, but one could argue that it would be the logical thing to end the file with.


答:
break isn't technically needed after the last alternative (which, mind you, doesn't have to be default: it is perfectly legal, and sometimes even useful to put the default branch first); whether your code falls through the end of the switch statement or breaks out at the end of its last branch has the same result.

However, I'd still end every branch, including the last one, with a return or break statement, for three reasons:

Refactorability. If all your branches end with break or return, you can reorder them without changing the meaning. This makes it less likely for such a reordering to introduce a regression.

Consistency, and Least Surprise. Consistency says your branches should end consistently, unless they are actually different in meaning. The Principle of Least Surprise dictates that similar things should look similar. Ending the last branch of a switch block exactly like the preceding ones fulfills both, which makes for easier reading and understanding. If you leave out the explicit break, the last branch will be optically different (which is especially important for quick scanning), and in order to see that it's really not different, the reader has to descend to the nitty-gritty level of reading individual statements.

Protecting yourself. If you make a habit of ending all your switch branches with a break, it will become automatic after a while, and you'll be less likely to accidentally forget it where it does matter. Training yourself to expect the break at the end of every branch also helps detecting missing break statements, which is great for debugging and troubleshooting.

Title: Break on default case in switch