答:
Note: I put an accent on the database usage, while you asked about the usage of the code itself. The answer still applies to both cases in every point I mentioned.

You already answered in part your own question in the last paragraph: see what is accessed while the application is running.

You may want to profile the database and to ask the profiler to record all the queries for a day. It will give you an overview of the most used database objects, but will not tell which ones are never used. Also, you must still be careful with the results: for example a table may be used exclusively through stored procedures, but when you'll look at the queries from the profiler, it would appear as if the table is not used at all.

Reviewing the source code, searching for queries is more helpful, and after collecting all queries, you can have a good understanding of database usage, not in terms of frequency (this is where a profiler is handy), but in terms of used/not used tables. Sadly, for a badly written/not maintained for years codebase, it may be extremely hard and error prone, especially if queries are constructed dynamically (imagine a method which, in a select, uses a parameter as the name of the table; how can you possibly know what are the possible values of the parameter by just looking at the source code?).

Static analysis and some compilers may also reveal dead code, but still doesn't give you the answer you want.

Analysis of data itself or the database metadata can reveal some interesting info. For example, it would be easy to assert that the table LogonAudit(uniqueidentifier LogonAuditId, datetime LogonEvent, ...) is not used any longer if it contains 10 000 records per day for the years 2006 to 2009, and no records from September, 18th, 2009. The same is not true for a table which contain the data indented to be mostly read-only.

Those four points together will give you the list of used tables. Remaining ones are either used or not. You may make assertions, and test them, but without good unit tests coverage, it wouldn't be easy. Any "easy" way would fail too. For example, if you have a products_delme_not_used table, you may assert that the table is not used at all, and check for "products_delme_not_used" in your code. This is optimistic: it's not unusual to find the DailyWTF candidate like this in an old codebase:

```<code>// Warning: WTF code below. Read with caution, never reuse it, and don't trust
// the comments.

private IEnumerable<Product> GetProducts()
{
    // Get all the products.
    return this.GetEntities<Product>("PRODUCT");
}

private IEnumerable<T> GetEntities<T>(string tableName)
{
    // Everyone knows that SQL is case sensitive.
    tableName = tableName.ToLower();

    if (tableName == "user" || tableName == "product")
    {
        // Those tables were renamed recently in the database. Don't have time
        // to refactor the code to change the names everywhere.
        // TODO: refactor the code and remove this `if` block.
        tableName += "s";
    }

    if (this.IsDelme(tableName))
    {
        // We have some tables which are marked for deletion but are still
        // used, so we adjust their name.
        tableName = this.Delme(tableName);
    }

    return this.DoSelectQuery<T>("select top 200 * from " + tableName);
}

private bool IsDelme(string name)
{
    // Find if the table is among candidates for removal.
    List<string> names = this.Query<string>("select Names from DelmeTables");
    return names.Contains(name);
}

private string Delme(string name)
{
    // Return the new name for a table renamed for deletion.
    return string.Join("_", new [] { name, "delme", "not", "used" });
}
</code>```

Can you figure out that this code actually uses products_delme_not_used table?

If I were you, I would:

Keep all the database objects in place,

Refactor the whole application (if it's worth it),

Document (while refactoring) the application and specifically the database usage.

When you finish the last two steps, you'll probably have a better understanding of the database usage, which will help figuring the names of the tables which are not used any longer, and may more or less safely remove them.

Title: In a legacy codebase, how do I quickly find out what is being used and what isn't?

Body:
I've been asked to evaluate what appears to be a substantial legacy codebase, as a precursor to taking a contract maintaining that codebase.

This isn't the first time I've been in this situation. In the present instance, the code is for a reasonably high-profile and fairly high-load multiplayer gaming site, supporting at least several thousand players online at once. As many such sites are, this one is a mix of front- and back-end technologies.

The site structure as seen from the inside out, is a mess. There are folders suffixed "_OLD" and "_DELETE" lying all over the place. Many of the folders appear to serve no purpose, or have very cryptic names. There could be any number of old, unused scripts lying around even in legitimate-looking folders. Not only that, but there are undoubtedly many defunct code sections even in otherwise-operational scripts (a far less pressing concern).

This is a handover from the incumbent maintainers, back to the original developers/maintainers of the site. As is understandably typical in these sorts of scenarios, the incumbent wants nothing to do with the handover other than what is contractually and legally required of them to push it off to the newly-elected maintainer. So extracting information on the existing site structure out of the incumbent is simply out of the question.

The only approach that comes to mind to get into the codebase is to start at the site root and slowly but surely navigate through linked scripts... and there are likely hundreds in use, and hundreds more that are not. Given that a substantial portion of the site is in Flash, this is even less straightforward since, particularly in older Flash applications, links to other scripts may be embedded in binaries (.FLAs) rather than in text files (.AS/ActionScript).

So I am wondering if anyone has better suggestions as to how to approach evaluating the codebase as a whole for maintainability. It would be wonderful if there were some way to look at a graph of access frequency to files on the webserver's OS (to which I have access), as this might offer some insight into which files are most critical, even though it wouldn't be able to eliminate those files that are never used (since some files could be used just once a year).

Body:
Note: I put an accent on the database usage, while you asked about the usage of the code itself. The answer still applies to both cases in every point I mentioned.

You already answered in part your own question in the last paragraph: see what is accessed while the application is running.

You may want to profile the database and to ask the profiler to record all the queries for a day. It will give you an overview of the most used database objects, but will not tell which ones are never used. Also, you must still be careful with the results: for example a table may be used exclusively through stored procedures, but when you'll look at the queries from the profiler, it would appear as if the table is not used at all.

Reviewing the source code, searching for queries is more helpful, and after collecting all queries, you can have a good understanding of database usage, not in terms of frequency (this is where a profiler is handy), but in terms of used/not used tables. Sadly, for a badly written/not maintained for years codebase, it may be extremely hard and error prone, especially if queries are constructed dynamically (imagine a method which, in a select, uses a parameter as the name of the table; how can you possibly know what are the possible values of the parameter by just looking at the source code?).

Static analysis and some compilers may also reveal dead code, but still doesn't give you the answer you want.

Analysis of data itself or the database metadata can reveal some interesting info. For example, it would be easy to assert that the table LogonAudit(uniqueidentifier LogonAuditId, datetime LogonEvent, ...) is not used any longer if it contains 10 000 records per day for the years 2006 to 2009, and no records from September, 18th, 2009. The same is not true for a table which contain the data indented to be mostly read-only.

Those four points together will give you the list of used tables. Remaining ones are either used or not. You may make assertions, and test them, but without good unit tests coverage, it wouldn't be easy. Any "easy" way would fail too. For example, if you have a products_delme_not_used table, you may assert that the table is not used at all, and check for "products_delme_not_used" in your code. This is optimistic: it's not unusual to find the DailyWTF candidate like this in an old codebase:

// Warning: WTF code below. Read with caution, never reuse it, and don't trust
// the comments.

private IEnumerable<Product> GetProducts()
{
    // Get all the products.
    return this.GetEntities<Product>("PRODUCT");
}

private IEnumerable<T> GetEntities<T>(string tableName)
{
    // Everyone knows that SQL is case sensitive.
    tableName = tableName.ToLower();

    if (tableName == "user" || tableName == "product")
    {
        // Those tables were renamed recently in the database. Don't have time
        // to refactor the code to change the names everywhere.
        // TODO: refactor the code and remove this `if` block.
        tableName += "s";
    }

    if (this.IsDelme(tableName))
    {
        // We have some tables which are marked for deletion but are still
        // used, so we adjust their name.
        tableName = this.Delme(tableName);
    }

    return this.DoSelectQuery<T>("select top 200 * from " + tableName);
}

private bool IsDelme(string name)
{
    // Find if the table is among candidates for removal.
    List<string> names = this.Query<string>("select Names from DelmeTables");
    return names.Contains(name);
}

private string Delme(string name)
{
    // Return the new name for a table renamed for deletion.
    return string.Join("_", new [] { name, "delme", "not", "used" });
}

Can you figure out that this code actually uses products_delme_not_used table?

If I were you, I would:

Keep all the database objects in place,

Refactor the whole application (if it's worth it),

Document (while refactoring) the application and specifically the database usage.

When you finish the last two steps, you'll probably have a better understanding of the database usage, which will help figuring the names of the tables which are not used any longer, and may more or less safely remove them.


问:
In a legacy codebase, how do I quickly find out what is being used and what isn't?
I've been asked to evaluate what appears to be a substantial legacy codebase, as a precursor to taking a contract maintaining that codebase.

This isn't the first time I've been in this situation. In the present instance, the code is for a reasonably high-profile and fairly high-load multiplayer gaming site, supporting at least several thousand players online at once. As many such sites are, this one is a mix of front- and back-end technologies.

The site structure as seen from the inside out, is a mess. There are folders suffixed "_OLD" and "_DELETE" lying all over the place. Many of the folders appear to serve no purpose, or have very cryptic names. There could be any number of old, unused scripts lying around even in legitimate-looking folders. Not only that, but there are undoubtedly many defunct code sections even in otherwise-operational scripts (a far less pressing concern).

This is a handover from the incumbent maintainers, back to the original developers/maintainers of the site. As is understandably typical in these sorts of scenarios, the incumbent wants nothing to do with the handover other than what is contractually and legally required of them to push it off to the newly-elected maintainer. So extracting information on the existing site structure out of the incumbent is simply out of the question.

The only approach that comes to mind to get into the codebase is to start at the site root and slowly but surely navigate through linked scripts... and there are likely hundreds in use, and hundreds more that are not. Given that a substantial portion of the site is in Flash, this is even less straightforward since, particularly in older Flash applications, links to other scripts may be embedded in binaries (.FLAs) rather than in text files (.AS/ActionScript).

So I am wondering if anyone has better suggestions as to how to approach evaluating the codebase as a whole for maintainability. It would be wonderful if there were some way to look at a graph of access frequency to files on the webserver's OS (to which I have access), as this might offer some insight into which files are most critical, even though it wouldn't be able to eliminate those files that are never used (since some files could be used just once a year).

答:
In a typical Java code base, I'll consider using tools such as PMD, FindBugs, or Sonar and then I'll try to understand tools reporting (dead code, undocumented code, duplicated code, etc.)

Based on the reports I'll try to find the different layers of the application/site (business layer, DB, SQL, etc.)

If layers are coupled (html within servlet, sql within java code) I'll start first by decoupling each of these steps should be considered to be isolated and you may commit at the end of each one (by starting a branch then make merge).

ContentLicense: CC BY-SA 3.0


问:
string.format with variables vs inline variables
What are the pros/cons (if any) to using

```<code>string output;
int i = 10;
output = string.Format("the int is {0}", i);
</code>```

versus

```<code>string output;
int i = 10;
output = "the int is " + i;
</code>```

I have always used the latter example, but it seems as though a good majority of online tutorials use the string.format example. I don't think that there are any real differences in terms of efficiency, my initial thought is so a coder doesn't have to keep breaking the string to insert variables.

答:
I prefer the first way because it allows me to accurately see what the string is going to look like when output. It's very easy to forget to add a space, or to add extra spacing when just appending strings.

I'm sure that there's also a performance benefit to the first way due to not having to create the extra strings; but that's not my primary concern.


答: By using the first option you can store a commonly used format string and reduce typing needed and make it easier to update the string everywhere its used. Basically the first option allows for DRY to be implemented easily. It is also a much nicer syntax if multiple variables need to be used in a string, like you mentioned.</p>

Title: string.format with variables vs inline variables

Body:
What are the pros/cons (if any) to using

```<code>string output;
int i = 10;
output = string.Format("the int is {0}", i);
</code>```

versus

```<code>string output;
int i = 10;
output = "the int is " + i;
</code>```

I have always used the latter example, but it seems as though a good majority of online tutorials use the string.format example. I don't think that there are any real differences in terms of efficiency, my initial thought is so a coder doesn't have to keep breaking the string to insert variables.


答:
I strongly recommend refactoring the existing source code (as opposed to a rewrite) using the patterns found in the book "Working Effectively With Legacy Code".

The book details several mechanisms for efficiently covering legacy code in unit tests, so that you can then begin to safely refactor the code.  The book is broken in parts, one describing the philosophy behind the approach, and then several chapters that solve particular problems, such as "It takes forever to make a change", "I don't have much time and need to change it", and "I can't get this class in to a test harness". Each of these chapters has detailed, proven techniques that help you learn how to apply best practices in testing to real world problems.

Reading the book left me with a very real sense that "we are not alone" ... many of us, or perhaps all of us, are working with complex code bases that have become difficult to manage. The techniques listed in the book have given me much hope, and I've personally been able to apply them almost immediately.

Joel Spolsky's blog post does a great job of explaining why its best to keep an existing, working code base as opposed to starting from scratch.  I've chosen a quote from the article that sums it up, but its a fantastic read.

"There's a subtle reason that programmers always want to throw away
  the code and start over. The reason is that they think the old code is
  a mess. And here is the interesting observation: they are probably
  wrong. The reason that they think the old code is a mess is because of
  a cardinal, fundamental law of programming:

It’s harder to read code than to write it.".
   - http://www.joelonsoftware.com/articles/fog0000000069.html


答:
Check out the first answer for https://stackoverflow.com/questions/4671610/why-use-string-format. It covers everything in my opinion as to why it is better.

Also, each .NET assembly has an intern pool, containing a collection of unique strings. When your code is compiled, all the string literals you reference in your code are added to this pool. If you have a code that looks like this:

```<code>"the int is " + i + " and the double is " + d
</code>```

That makes it 2 strings in the pool.

If you have:

"the int is {0} and the double is {1}"

You have only one String in the pool.

It is a bit more complicated to know when Strings are interned, and when they are not because the compiler has some intelligence when detecting Strings that may not need to be interned sometimes...Check out for example this article which gives more insight into this matter.

Edit: after digging up a bit, I've encountered an interesting answer to the question When is it better to use String.Format vs string concatenation?. In short, the author of the answer with +30 votes makes a compelling argument in favor of String concatenation when localization is not involved.

Body:
Check out the first answer for https://stackoverflow.com/questions/4671610/why-use-string-format. It covers everything in my opinion as to why it is better.

Also, each .NET assembly has an intern pool, containing a collection of unique strings. When your code is compiled, all the string literals you reference in your code are added to this pool. If you have a code that looks like this:

"the int is " + i + " and the double is " + d

That makes it 2 strings in the pool.

If you have:

"the int is {0} and the double is {1}"

You have only one String in the pool.

It is a bit more complicated to know when Strings are interned, and when they are not because the compiler has some intelligence when detecting Strings that may not need to be interned sometimes...Check out for example this article which gives more insight into this matter.

Edit: after digging up a bit, I've encountered an interesting answer to the question When is it better to use String.Format vs string concatenation?. In short, the author of the answer with +30 votes makes a compelling argument in favor of String concatenation when localization is not involved.


答:
I think with string.Format() it's easier to see what exactly is the result going to be (so you don't have problems with forgotten spaces or something like that), and it's also easier to type and modify.

If you want to do very simple formatting, using the + plus operator might be easier, but I tend to use it only when concatenating two strings, not more.

To show how string.Format() is easier to modify, consider that you wanted to add a full stop at the end of the sentence in your example: going from string.Format("The int is {0}", i) to string.Format("The int is {0}.", i) is just one character. But going from "the int is " + i to "the int is " + i + '.' is much more.

Another advantage of string.Format() is that it allows you to easily specify the format to use, like string.Format("The int is 0x{0:X}.", i). This is even more important when formatting date.

As for efficiency, string.Format() is most likely slower that simple string concatenations. But code like this is most likely not on a hot path, so it doesn't matter. And if it does, you are probably better off with using StringBuilder.


答:
Since what you're being asked to do is provide input for your client to write an appropriate proposal to the other client (owner-of-the-nightmare-code) for any work on that code, I'm going to go out on a limb and say that you're not going to be doing any thorough testing or refactoring or anything along those lines at this point. You probably have a very short time to get a rough estimate. My answer is based on my experience in the same situation, and so if my interpretation is incorrect, just disregard everything that follows.

Use a spidering tool to get a sense of what pages are there, and
what is inbound.  Even a basic linkchecker tool -- not a specific
"spider for auditing purposes" tool -- will be useful in this regard.

Make a basic audit/inventory spreadsheet. This could be as simple as
a list of files and their last-modified time, organized by directory.
This will help you get a sense of scope, and when you get to
directories like _OLD and _DELETE you can make a big note that a)
your evaluation is based on stuff not in those directories b) the
presence of those directories and the potential for cruft/hidden
nightmares attests to deeper issues that should be accounted for in
your client's bid, in some way. You don't have to spend a gazillion
years enumerating the possible issues in _OLD or _DELETE; the info
will feed into the eventual bid.

Given you are reviewing what sounds like an entirely web-based app,
even standard log analyzer tools are going to be your friend.  You
will be able to add to the spreadsheet some sense of "this is in the
top 10 of accessed scripts" or some such.  Even if the scripts are
embedded in Flash files and therefore not spiderable, there's a high
probability they are accessed via POST or GET, and will show up in
the server logs.  If you know you have 10 highly accessed scripts,
not 100 (or vice versa), this will give you a good idea of how
maintenance work will likely go.

Even in a complicated site, what I outlined above is something you could do in a day or day and a half.  Since the answer you're going to give to your client is something like "this is going to be a tremendous pain in the butt, and here are some reasons why you'll just be putting lipstick on a pig, so you should bid accordingly" or "any reasonable person would bid not to maintain but to start over, so you should bid accordingly" or even "this isn't that bad, but it will be a consistent stream of work over any given timeframe, so bid accordingly", the point is that they're going to be making the bid and thus you do not need to be as precise as you would be if you were being hired directly to do a full content and architecture audit.


问:
What is the easiest and cheapest way to distribute apple iOS enterprise app?
I work as a developer in a company, The company I work with has to deploy the app I made to their client. Number of clients are 3 and each client has around 100 iPads. Now my question is,

What different ways we can use in order to deploy and distribute app seamlessly?

How good is AppCentral to distribute applications?

答:
There are three options:

If it's more than 100 devices, get the client to sign up to an Apple Enterprise account then they can deploy the app via an ad-hoc build to all their employee's devices without needing to individually add each device UDID to the provisioning profile. (If it's less than 100 devices they can just get a regular developer account, but it's still a lot of hassle provisioning and maintaining that number of devices individually).

You could get the company to bulk-buy the app from you using the B2B bulk purchase program (US only - http://www.apple.com/business/vpp/).

You could deploy the app to the app store as normal and require a login to use it. Give the login to all employees at the company, but don't make it available to the general public.

OwnerDisplayName: Nick Lockwood


答:
It sounds to me you need to get enough information for creating a quote so I'll concentrate on that effort.

I would try to determine how many use cases there are involved in this site. This typically gives you an idea of how big and complicated the site is and how much time it will take to re-create or maintain the site/application.

Yes, it's true that sometimes code isn't used any longer and it will make the application look a little bit bigger than it really is, but I don't think this is going to affect the numbers by more than 20% at the most, so I wouldn't worry about that part.

Looking at the source code, web pages and database tables should help you discover this.

You may also want to consider limiting the number of hours per month that you'll spend on this project for the pre-determined fee to protect yourself.

As far as discovering what is being used and not used, there really is no easy way. Code analysis tools may help, but since you're dealing with such a mixed bad I don't think any single tool exists that can help. For each specific area you can probably find a code analysis tool that may help.


问:
Where is a good place to start to learn about custom caching in .Net
I'm looking to make some performance enhancements to our site, but I'm not sure exactly where to begin. We have some custom object caching, but I think that we can do better.

Our Business

We aggregate news stories on a news type of web site. We get approximately 500-1000 new stories per week. We have index pages that show various lists of the items and details pages that show the individual stories.

Our Current Use case: Getting an Individual Story

User makes a request

The Data Access Layer(DAL) checks to see if the item is in cache and if item is fresh (15 minutes).

If the item is not in cache or is not fresh, retrieve the item from SQL Server, save to cache and return to user.

Problems with this approach

The pull nature of caching means that users have to pay the waiting cost every time that the cache is refreshed. Once a story is published, it changes infrequently and I think that we should replace the pull model with something better.

My initial thoughts

My initial thought is that stories should ALL be stored locally in some type of dictionary. (Cache or is there another, better way?). If the story is not found, then make a trip to the database, update the local dictionary and send the item back.

Since there may be occasional updates to stories, this should be an entirely process from the user.

I watched a video by Brent Ozar, How StackOverflow Scales SQL Server, in which Brent states "the fastest database query is the one that you don't make".

Where do I start?

At this point, I don't know exactly what the solution is. Is it caching? Is there a better way of using local storage? Do I use a Dictionary, OrderedDictionary, List ? It seems daunting and I'm just looking for some good starting points to learn more about how to do this type of optimization.

答:
If you were to choose a caching system:

Did you check the following article available at MSDN: http://msdn.microsoft.com/en-us/library/ee817645.aspx ?

It is outdated ("retired" as they say) but still a good read, particularly the second chapter for you since you did not yet made up your mind on the technique/technology you want to use. The following techniques are mentioned:

Using the ASP.NET Cache

Using Remoting Singleton Caching

Using Memory-Mapped Files

Using Microsoft SQL Server 2000 or MSDE for Caching

Using Static Variables for Caching

Using ASP.NET Session State

Using ASP.NET Client Side Caching and State

Using Internet Explorer Caching

Also, I've never used it, but I heard a lot of good stuff about Memcached, there is an interesting answer to the Memcached with Windows and .NET question that explains how it might work along a .NET environment.

However, I don't know how long is a story, how many bits it would take, but 520000 in ten years does not seem that much. Maybe Memcached is overkill in that case, I'm not sure...


答: A web crawler might help you determine which URLs are accessible. Especially if it's smart enough to extract links from Flash or JavaScript. Once you have a list of web pages, go through them and list the files they refer to. Anything that's left over after this process should be considered dead code.</p>


问:
Drawing Ellipse from a bounding box?
Does anyone know a good algorithm for drawing an ellipse from a bounding box?

```<code>draw_ellipse(int s1, int s2, int s3, int s4, color c);
</code>```

I don't need something optimized to incomprehendable , unreadable efficiency. Just something good enough to use for a simple drawing api. You can provide the algorithm in your answer in all programming languages or even pseudocode, but I would prefer it if you use C++ or a C++-like syntax.

答:
A very basic and completely untested pseudo-code for drawing an ellipse using a parametric polar equation is below:

```<code>Function draw_ellipse(int X1, int Y1, int X2, int Y2)
     RX = (X2 - X1) / 2
     RY = (Y2 - Y1) / 2
     CX = (X2 + X1) / 2
     CY = (Y2 + Y1) / 2

     for Angle = 0 to 360
          X = CX + cos(Angle) * RX
          Y = CY + sin(Angle) * RY

          if (Angle > 0) DrawLine(LastX, LastY, X, Y)

          LastX = X
          LastY = Y
     Next Angle
End Function
</code>```

Notes/Comments:

Assumes an unrotated ellipse.

Change to radians (0 to 2 pi) if your language cos/sin takes angles in radians (like C/C+ does).

You can use symmetry to reduce the loop size to 0 - 90 degrees.

Change the drawing precision as needed by changing the loop step amount (is 1 degree as shown).

Title: Drawing Ellipse from a bounding box?

Body:
A very basic and completely untested pseudo-code for drawing an ellipse using a parametric polar equation is below:

Function draw_ellipse(int X1, int Y1, int X2, int Y2)
     RX = (X2 - X1) / 2
     RY = (Y2 - Y1) / 2
     CX = (X2 + X1) / 2
     CY = (Y2 + Y1) / 2

     for Angle = 0 to 360
          X = CX + cos(Angle) * RX
          Y = CY + sin(Angle) * RY

          if (Angle > 0) DrawLine(LastX, LastY, X, Y)

          LastX = X
          LastY = Y
     Next Angle
End Function

Notes/Comments:

Assumes an unrotated ellipse.

Change to radians (0 to 2 pi) if your language cos/sin takes angles in radians (like C/C+ does).

You can use symmetry to reduce the loop size to 0 - 90 degrees.

Change the drawing precision as needed by changing the loop step amount (is 1 degree as shown).


答:
If you consider translation to be important in your project, the first syntax will really help with it.

For instance you may have:

```<code>static final string output_en = "{0} is {1} years old.";
static final string output_fr = "{0} a {1} ans.";

int age = 10;
string name = "Henri";
System.out.println(string.Format(output_en, name, age));
System.out.println(string.Format(output_fr, name, age));
</code>```

Also note that your variables may not always be in the same place in the sentence with that syntax:

```<code>static final string output_yoda = "{1} years {0} has.";
</code>```

Body:
If you consider translation to be important in your project, the first syntax will really help with it.

For instance you may have:

static final string output_en = "{0} is {1} years old.";
static final string output_fr = "{0} a {1} ans.";

int age = 10;
string name = "Henri";
System.out.println(string.Format(output_en, name, age));
System.out.println(string.Format(output_fr, name, age));

Also note that your variables may not always be in the same place in the sentence with that syntax:

static final string output_yoda = "{1} years {0} has.";


问:
Does TDD really work for complex projects?
I’m asking this question regarding problems I have experienced during TDD projects.
I have noticed the following challenges when creating unit tests.

Generating and maintaining mock data

It’s hard and unrealistic to maintain large mock data. It’s is even harder when database structure undergoes changes.

Testing GUI

Even with MVVM and ability to test GUI, it takes a lot of code to reproduce the GUI scenario.

Testing the business

I have experience that TDD works well if you limit it to simple business logic. However complex business logic is hard to test since the number of combinations of tests (test space) is very large.

Contradiction in requirements

In reality it’s hard to capture all requirements under analysis and design.  Many times one note requirements lead to contradiction because the project is complex. The contradiction is found late under implementation phase. TDD requires that requirements are 100% correct. In such cases one could expect that conflicting requirements would be captured during creating of tests. But the problem is that this isn’t the case in complex scenarios.

I have read this question: Why does TDD work?

Does TDD really work for complex enterprise projects, or is it practically limit to project type?

答:
I think so, see Test Driven Development really works

In 2008, Nachiappan Nagappan, E. Michael Maximilien, Thirumalesh Bhat, and Laurie Williams wrote a paper called “Realizing quality improvement through test driven development: results and experiences of four industrial teams“ (PDF link). The abstract:

Test-driven development (TDD) is a software development practice that has been used sporadically for decades. With this practice, a software engineer cycles minute-by-minute between writing failing unit tests and writing implementation code to pass those tests. Test-driven development has recently re-emerged as a critical enabling practice of agile software development methodologies. However, little empirical evidence supports or refutes the utility of this practice in an industrial context. Case studies were conducted with three development teams at Microsoft and one at IBM that have adopted TDD. The results of the case studies indicate that the pre-release defect density of the four products decreased between 40% and 90% relative to similar projects that did not use the TDD practice. Subjectively, the teams experienced a 15–35% increase in initial development time after adopting TDD.

In 2012, Ruby on Rails development practices assume TDD. I personally rely on tools like rspec for writing tests and mocks, factory_girl for creating objects, capybara for browser automation, simplecov for code coverage and guard for automating these tests.

As a result of using this methodology and these tools, I tend to agree subjectively with Nagappan et al...

ContentLicense: CC BY-SA 2.5


问:
Is IoC feasible in winforms?
I'm coming back into the winform world after being in the web world for a while.  Is it common or otherwise feasible for developers to use IoC in winform?

My concern is mainly with performance.  I envision that I will need to "bootstrap" or initialize all my inverted items that are required by a given form instance on form initialization.  If this initialization becomes expensive, I can push the task off to a thread, but that requires that I get the created objects back to the main thread where they will be used at some point.

答:
It's very common and I can't find many complaints regarding the speed of Unity/Ninject type resolution.

Your classes doing the heaviest lifting that have the most external dependencies you want to inject into should be nowhere near the Windows Forms framework code you're writing and so the fact that you're using Windows Forms shouldn't bare heavily on your decision (look into the MVP pattern for more on decoupling application logic from the types the designer uses).

Chances are those external dependencies you're trying to remove, by using IoC, will be very slow themselves and will be your real bottleneck.  In comparison to writing a 100k file or making a web request, it's not even worth thinking about.

Title: Is IoC feasible in winforms?


问:
Is it possible to integrate UDP file transfer into a .NET web application?

Background

I have recently been tasked with designing a rebuild of an existing .NET web application that currently uses a third-party company to handle large file transfers (as big as 50Gb).

Currently, the .NET app depends on a .JAR (Java Applet) provided by this third-party which is called up inside of an iFrame and exposes the appropriate file-system interaction for selecting entire directories for upload and so forth.

I realize that so far all of this is possible using some combination of .NET networking classes (ftp) and Flash or Silverlight for client access.

I have been told that the reason that the third-party plugin is so special is that it uses UDP protocol so that if an upload or download is interrupted, it can be resumed later right where it left off. I have also been told that the third-party tool suite allows the IT folks to throttle bandwith (I don't even know what that means) and do a couple of other cool things.

Question

Assuming that we will use the latest version of C# and and the .NET framework (4.0), is it reasonably possible to replicate this UDP-based behavior? By reasonable, I mean could it be accomplished in less than, say, 240 dev hours.

Please note that the rebuilt app will ideally use all Microsoft technologies (including Silverlight for client access) and will run on Azure.

答:
Yes, .Net fully supports UDP. You can create a UDP Socket and then wrap it in a NetworkStream.

I have been told that the reason that the third-party plugin is so special is that it uses UDP protocol so that if an upload or download is interrupted, it can be resumed later right where it left off.

That doesn't make any sense. For example HTTP, supports this too. And since it seems they are using some custom protocol over UDP, a custom protocol over, say, TCP could achieve the same effect too. There is nothing special about UDP in this regard.

I have also been told that the third-party tool suite allows the IT folks to […] do a couple of other cool things.

This really sounds like it's some custom protocol. We can't tell you how hard that will be, because we don't know anything about it – i.e. how complex it is, how well documented it is, etc.


问:
Is it possible to work with distrusting clients
One of our junior developers has been assigned a new client (we don't have the client yet, we're still working with him to see if we can meet his needs) and the junior developer said the client will hire us if we can do the work on his project without getting access to his server.

I've had a direct conversation with the client who turned out to have had his code stolen before by some offshore company that he outsourced. This made me more sympathetic but I still have mixed feelings about this.

On one hand I want to prove to the client that we're not all bad apples. Also if we do a good job with him, we get a loyal client who'll hire us for all his projects. I haven't heard of this happen before but I guess it happens more often than we'd all like to admit.

On the other hand I'm hesitant to accept working with him because deployment time is going to be a nightmare and no where in my career or education has anyone taught me how to work with clients like him. I (or the junior developer) would have to write a detailed description of exactly what to do with the source to deploy it and that is an annoying burden when I could deploy and test the whole thing in an hour myself.

As I said, I've never had to deal with this before (we're signing a non-disclosure but apparently so did the offshore company before us). We're not fully fully booked so it's not like I have an immediate replacement, but we're not begging for work either and I wonder if working under such restricted environment is worth the trouble.

Another side is that the experience itself could be rewarding for us, but is it experience worth having, as in what's even the likelihood of getting a similar client anytime soon. Are we even expected to comply with such clients?

So since I don't have any first hand experience with this and it definitely wasn't covered in school, how would those with longer experience working with clients deal with a distrusting client like this? Would you even accept the job?

答:
Work with the client, and add hours of extra (billable) time to your quotation for every task, to cover the hassles of deployment without server access.

It's depressing to be limited like that due to (unfounded) trust issues, but really, it shouldn't be that burdensome. I've worked with a number of clients where we had to work this way, not due to them not trusting us, but simply because they were huge companies with blanket IT policies. It just means you need to be more disciplined about your deployments so you're not deploying, fixing a tiny bug and deploying again, realizing you forgot a file and deploying again, etc. etc.


问:
What is the value in hiding the details through abstractions? Isn't there value in transparency?

Background

I am not a big fan of abstraction. I will admit that one can benefit from adaptability, portability and re-usability of interfaces etc. There is real benefit there, and I don't wish to question that, so let's ignore it.

There is the other major "benefit" of abstraction, which is to hide implementation logic and details from users of this abstraction. The argument is that you don't need to know the details, and that one should concentrate on their own logic at this point. Makes sense in theory.

However, whenever I've been maintaining large enterprise applications, I always need to know more details. It becomes a huge hassle digging deeper and deeper into the abstraction at every turn just to find out exactly what something does; i.e. having to do "open declaration" about 12 times before finding the stored procedure used.

This 'hide the details' mentality seems to just get in the way. I'm always wishing for more transparent interfaces and less abstraction. I can read high level source code and know what it does, but I'll never know how it does it, when how it does it, is what I really need to know.

What's going on here? Has every system I've ever worked on just been badly designed (from this perspective at least)?

My philosophy

When I develop software, I feel like I try to follow a philosophy I feel is closely related to the ArchLinux philosophy:

Arch Linux retains the inherent complexities of a GNU/Linux system, while keeping them well organized and transparent. Arch Linux developers and users believe that trying to hide the complexities of a system actually results in an even more complex system, and is therefore to be avoided.

And therefore, I never try to hide complexity of my software behind abstraction layers. I try to abuse abstraction, not become a slave to it.

Question at heart

Is there real value in hiding the details?

Aren't we sacrificing transparency?

Isn't this transparency valuable?

答:
I think you should understand how it works if needed. Once you've determined it does what you thought it would do, then you have peace of mind. I never thought the goal was to hide it for ever and ever.

Once you set an alarm on a clock that you are confident will work, you can get some sleep knowing it will go off at the corret time. Waking up an hour early just so you can watch the seconds tick away is a waste.


答:
I would say that hiding the details is great when the stuff that's hidden works.

For instance, say we develop an interface which defines behaviors (i.e. GetListItems, SendListItem), which are two features that are initiated by the user via some button click or something.. NOW, each user can have their own "ListItemStore".. say one's on facebook, ones on myspace.. (for instance)..  and say it's saved as a user property / setting somewhere in the app via user prefrences.. and say it's possible for the App developers to add additional ListItemStore's over the course of time (mybook, facespace, etc..)

now there's a lot of details in connecting to facebook and getting them items.. and there's equally as much details when connecting to to myspace.. and so on...

now, after the initial "store access" code is written, it may not need to be modified (well in facebooks case we probably need a fulltime developer to keep up with the changes, zing..) ,

so when you use the code it's something like:

```<code>    new ItemManager(user) //passes in user, allowing class to get all user properties
    ItemManager.GetListItems()
</code>```

and now you've got the User's data from wherever they've stored it, and since all i'm worried about is getting the list of items and doing something with it, and since it only took 2 lines which will work no matter how many more stores are added i can get back to answering / posting questions on stack... lol..

So, all the plumbing to make that happen is "hidden" and who really cares how it does it as long as i get the correct list of items.. if you have unit tests, then you can even rest easier because the results should've been quantified already..

Title: What is the value in hiding the details through abstractions? Isn't there value in transparency?

Body:
Background

I am not a big fan of abstraction. I will admit that one can benefit from adaptability, portability and re-usability of interfaces etc. There is real benefit there, and I don't wish to question that, so let's ignore it.

There is the other major "benefit" of abstraction, which is to hide implementation logic and details from users of this abstraction. The argument is that you don't need to know the details, and that one should concentrate on their own logic at this point. Makes sense in theory.

However, whenever I've been maintaining large enterprise applications, I always need to know more details. It becomes a huge hassle digging deeper and deeper into the abstraction at every turn just to find out exactly what something does; i.e. having to do "open declaration" about 12 times before finding the stored procedure used.

This 'hide the details' mentality seems to just get in the way. I'm always wishing for more transparent interfaces and less abstraction. I can read high level source code and know what it does, but I'll never know how it does it, when how it does it, is what I really need to know.

What's going on here? Has every system I've ever worked on just been badly designed (from this perspective at least)?

My philosophy

When I develop software, I feel like I try to follow a philosophy I feel is closely related to the ArchLinux philosophy:

Arch Linux retains the inherent complexities of a GNU/Linux system, while keeping them well organized and transparent. Arch Linux developers and users believe that trying to hide the complexities of a system actually results in an even more complex system, and is therefore to be avoided.

And therefore, I never try to hide complexity of my software behind abstraction layers. I try to abuse abstraction, not become a slave to it.

Question at heart

Is there real value in hiding the details?

Aren't we sacrificing transparency?

Isn't this transparency valuable?

Body:
I would say that hiding the details is great when the stuff that's hidden works.

For instance, say we develop an interface which defines behaviors (i.e. GetListItems, SendListItem), which are two features that are initiated by the user via some button click or something.. NOW, each user can have their own "ListItemStore".. say one's on facebook, ones on myspace.. (for instance)..  and say it's saved as a user property / setting somewhere in the app via user prefrences.. and say it's possible for the App developers to add additional ListItemStore's over the course of time (mybook, facespace, etc..)

now there's a lot of details in connecting to facebook and getting them items.. and there's equally as much details when connecting to to myspace.. and so on...

now, after the initial "store access" code is written, it may not need to be modified (well in facebooks case we probably need a fulltime developer to keep up with the changes, zing..) ,

so when you use the code it's something like:

    new ItemManager(user) //passes in user, allowing class to get all user properties
    ItemManager.GetListItems()

and now you've got the User's data from wherever they've stored it, and since all i'm worried about is getting the list of items and doing something with it, and since it only took 2 lines which will work no matter how many more stores are added i can get back to answering / posting questions on stack... lol..

So, all the plumbing to make that happen is "hidden" and who really cares how it does it as long as i get the correct list of items.. if you have unit tests, then you can even rest easier because the results should've been quantified already..


答:
The reason for hiding the details isn't to keep the details hidden; it's to make it possible to modify the implementation without breaking dependent code.

Imagine that you've got a list of objects, and each object has a Name property and other data.  And a lot of times, you need to find an item in the list whose Name matches a certain string.

The obvious way is to loop over each item one by one, and check to see if Name matches the string.  But if you find that that's taking far too much time, (as it would if you have several thousand items in the list,) you might want to replace it with a string-object dictionary lookup.

Now if all of your lookups were done by retrieving the list and looping over it, you've got a huge amount of work to do to fix this.  It's even tougher if you're in a library and third-party users are using it; you can't go out and fix their code!

But if you had a FindByName method to encapsulate the process of the name lookup, you can simply change the way it's implemented and all the code that calls it will continue working, and get a lot faster for free.  That's the real value of abstraction and encapsulation.


答:
I just finished reading the section in Code Complete about abstraction, so that's where most of this sources.

The point of abstraction is to remove the need to ask "how is this implemented?". When you call user.get_id(), you know that an id is what you're going to get back. If you have to ask "how does this get the user id?" then you probably either don't need an id, or get_id() returns something that is unexpected and is poorly designed.

You use abstraction to allow you to design:

```<code>a house with doors and windows
</code>```

not design

```<code>a box with four walls,
    with 3 holes,
        two of which fit panes of glass surrounded by wood frames,
        one that fits a large plank of wood with hinges and a metal knob,
etc.
</code>```

Body:
I just finished reading the section in Code Complete about abstraction, so that's where most of this sources.

The point of abstraction is to remove the need to ask "how is this implemented?". When you call user.get_id(), you know that an id is what you're going to get back. If you have to ask "how does this get the user id?" then you probably either don't need an id, or get_id() returns something that is unexpected and is poorly designed.

You use abstraction to allow you to design:

a house with doors and windows

not design

a box with four walls,
    with 3 holes,
        two of which fit panes of glass surrounded by wood frames,
        one that fits a large plank of wood with hinges and a metal knob,
etc.


问:
When to stop writing user stories, and start coding?
When discovering stories for the first sprint, how do you know when to stop writing and move forward?

I've asked a few people I know, and basically the response I've gotten is, it depends on the context the project exists in and how timeboxed the overall project is as well.

Is there any standard way for knowing when to stop writing user stories, and if so, what is the basis for this, and how does it apply to future sprints?

答:
You need to estimate each story once you have fleshed it out - this assumes that you are getting your stories in order of priority and that they are elaborated enough for development.

When you have estimated enough for an iteration, start coding.


答:
when the stories become granular enough to turn into programmable logic.. and when programmers can award a certain amount of story points that fit within the sprints timeline..

a story that is estimated at 50 hours/story points would be tough (IMO) to take on over a week long sprint.. breaking the story down further would allow for others to take on various parts of the task, but if the code cant be developed in parallel, then that's probably as short as you can go.

Title: When to stop writing user stories, and start coding?

Body:
When discovering stories for the first sprint, how do you know when to stop writing and move forward?

I've asked a few people I know, and basically the response I've gotten is, it depends on the context the project exists in and how timeboxed the overall project is as well.

Is there any standard way for knowing when to stop writing user stories, and if so, what is the basis for this, and how does it apply to future sprints?


答:
When people say that abstractions hide implementation details, they don't actually mean "hide" in the sense to make it hard to find. What they mean is separate implementation details from public interface, to keep the interface simple, concise, and manageable. Just like a car "hides" most of its vital parts, and only offers a fairly rudimentary set of controls to operate them, a software module "hides" most of its functionality deep in its bowels and only exposes a limited number of access methods to drive it. Imagine a car where you had to manually operate all the engine's internals (and there's a whole freaking lot of them), you'd have a really hard time keeping an eye on the traffic and finding the way.

But keeping the interface simple is not merely an aesthetic thing; it can make the difference between a successful project and a Death March. Let's play devil's advocate for a minute; imagine a software project without any abstractions at all. If you need to keep a value around, you use a global variable. If you need to use functionality more than once, you copy-paste it. If you need two different versions of a certain code section, you copy-paste, wrap it in an if statement, and modify both branches. Technically speaking, it works, but a few months down the road, you'll be fighting a few really nasty problems:

When you find and fix a bug, it is likely to also exist in other copy-pasted instances of similar code, so on top of finding and fixing the bug, you also have to go hunting for other occurrences and fix them, too.

In order to find a bug or implement a change, a maintenance programmer must be able to understand the relevant code. The difficulty in doing this increases with the size of the relevant code section, but even more with its scope. Keeping half a dozen variables in your head while mentally stepping through some code is doable; but if you have a few hundred of them, your productivity is severely impacted (I like to compare the thought process with a program that runs out of physical RAM and has to dip into the swapfile: instead of reading through the code fluently in one go, the programmer has to jump back and forth to look things up).

The scope of a piece of code also impacts the size of the codebase one has to dig through in order to find the bug. If you have a ten-line function with two parameters, and no globals, and you know the values of the input and the line at which it crashes, finding the bug is usually trivial and often requires nothing more than looking at the code. If it's a few hundred lines, twenty parameters, fifteen globals, and calls a few other functions of similar nature, you're in for some serious pain.

Without proper abstraction, any change can potentially impact large parts of the codebase, as practically anything may depend on the code to be changed. A typical symptom with such codebases is that you make a small, seemingly innocent change, and a completely unrelated feature suddenly breaks. With abstraction, you can limit the amount of damage a change can do, and you make the impact more predictable. If you change the name of a private field, you only have one source file to check; if you change the name of a global variable, you need to run through the entire codebase.

In a badly-abstracted codebase, the impact typically grows exponentially with the size of the codebase, that is, adding a constant amount of code increases the maintenance effort by a constant factor. To make matters worse, adding more programmers to a project does not increase productivity linearly, but logarithmically at best (because the larger your team, the more overhead is required for communication).


答:
What you refer to as "Hiding", many see as a separation of concerns (e.g. Implementation vs. Interface).

In my opinion, one major benefit of abstraction is to reduce the clutter of unneeded details from the developer's limited brainspace.

If implementation code were obfuscated, I could see that as hindering transparency, but abstraction as I see it, is just good organization.


答:
First off, anything beyond a single machine code instruction is essentially abstraction--a while...do loop is an consistent symbolic way of representing the comparisons and address calls required to repeat a set of instructions until a condition is met.  Likewise the int type is an abstraction for X number of bits (depending on your system).  Programming is all about abstraction.

You'd probably agree that those primitive abstractions are mighty useful.  Well, so is being able to build your own.  OOAD and OOP are all about.

Suppose you've got a requirement where the users want to be able to export the data from a screen in a variety of formats: delimited text, excel, and pdf.  Isn't it handy that you can create an interface called "Exporter" with a method export(data), based on which you can build a  DelimitedTextExporter, an ExcelExporter, and a PDFExporter, each of which knows how to create it's particular output? All the calling program needs to know is that it can call the export(data) method, and whichever implementation is used will do its thing.  Moreover, if the delimited text rules change, you can change the  DelimitedTextExporter without having to mess with the ExcelExporter, possibly breaking it.

Pretty much all of the well known design patterns used in OO programming depend on abstraction.  I'd recommend reading Freeman and Freeman's Head First Design Patterns to get a better feeling for why abstraction is a good thing


答: When you have a complete product backlog, and good complete user stories of all cases. Then divide them into iterations, and start programming.</p>


答:
To answer your questions specifically:

Is there real value in hiding the details?

Yes. As you acknowledge in the first line of your question.

Aren't we sacrificing transparency?

Not really.  A well written abstraction will make it easy to understand the details if needed.

Isn't this transparency valuable?

Yes. Abstractions should be designed and implemented to make understanding the details easy when needed/desired.


问:
How do you use blank lines in your code?
There has been a few remarks about white space already in discussion about curly braces placements.

I myself tend to sprinkle my code with blank lines in an attempt to segregate things that go together in "logical" groups and hopefully make it easier for the next person to come by to read the code I just produced.

In fact, I would say I structure my code like I write: I make paragraphs, no longer than a few lines (definitely shorter than 10), and try to make each paragraph self-contained.

For example:

in a class, I will group methods that go together, while separating them by a blank line from the next group.

if I need to write a comment I'll usually put a blank line before the comment

in a method, I make one paragraph per step of the process

All in all, I rarely have more than 4/5 lines clustered together, meaning a very sparse code.

I don't consider all this white space a waste because I actually use it to structure the code (as I use the indentation in fact), and therefore I feel it worth the screen estate it takes.

For example:

```<code>for (int i = 0; i < 10; ++i)
{
    if (i % 3 == 0) continue;

    array[i] += 2;
}
</code>```

I consider than the two statements have clear distinct purposes and thus deserve to be separated to make it obvious.

So, how do you actually use (or not) blank lines in code ?

答:
Never a blank line, not in the whole file. That is not to say there are not breaks in the code:

```<code> code;
 //
 morecode;
</code>```

Blank lines are for opening sections of the code to work on, you have a couple hotkeys in your editor to take you to the prev/next blank line.

Body:
Never a blank line, not in the whole file. That is not to say there are not breaks in the code:

 code;
 //
 morecode;

Blank lines are for opening sections of the code to work on, you have a couple hotkeys in your editor to take you to the prev/next blank line.


答:
I think I understand your feeling about this, and I think I have a similar opinion.

I have worked with Java developers who turn 50 code line class into 3 classes and 3 interfaces because it's easy to understand. And I couldn't stand it.

The thing was awfully hard to understand, almost impossible to debug and never ever needed to "switch the implementation".

On the other hand, I've also seen code where multiple objects share similar behavior and are used in one place, and could really use common sorting/processing loops if the methods would have been exposed through common interface.

So, IMHO, core objects that are likely to be used in similar scenarios usually benefit from common behavior which should be accessible through interface. But that's pretty much it, abstracting simple things because it's right, or makes it possible to switch implementations is just a way to make code messy.

Then again, I prefer longer smarter classes over explosive amount of small classes with all the lifetime management issues, and hard to see relationships, and spaghetti call graphs. So some people will disagree with me.


问:
Can JavaScript be used as a general scripting language?
I've used JavaScript and some frameworks (jQuery, Prototype, some node.js) for client-side web programming, but never on the desktop, where I do most of my scripting work in either Python or Bash.

But IMHO, JavaScript would make a great scripting language if used outside of the browser. Has anyone tried this? Can JavaScript be an adequate replacement for Python/Perl/Bash for quick and dirty scripting tasks?

答: I am using JScript.net right now to create an intelligent command line interface. Its working out pretty well for this project because eval() comes in handy, but not everything works as you expect (its not pure js). But it does offer some RAD. I think it would make a good prototyping platform. Its kind of weird being in a no-mans-land between js and .net though. (Its obsolete too, so hard to find good resources on it)</p>


答:
Is there real value in hiding the details?

Yes.  By presenting abstractions we can think and program at a higher level.

Imagine modeling physical systems without calculus or matrix algebra.  It's completely impractical.  Similarly, if we can only program at a scalar level, we will be unable to solve interesting problems.  Even relatively simple web applications can benefit greatly from abstractions like tag libs.  It is much easier to insert a tag that means "address entry fields" than to repeatedly create four text fields and a select box.  And if you decide to expand overseas, you can just modify the tag definition, rather than fixing every form to handle international addresses.  Effective use of abstraction is what makes some programmers ten times as effective as others.

Humans have a limited working memory.  Abstraction allows us to reason about large systems.

```<code>Aren't we sacrificing transparency?
</code>```

No.  If abstractions are not used, then the purpose of a software component is buried in repeated details.  Developers spend their days wading through code like this:

```<code>for (i = 0; i < pilgrim.wives.size(); ++i) {
  wife = pilgrim.wives[i];
  for (j = 0; j < wife.sacks.size(); ++j) {
     sack = wife.sacks[i];
     for (k = 0; j < sack.cats.size(); ++j) {
        cat = sack.cats[k];
        for (m = 0; m < cat.kits.size(); ++m) {
           ++count;
        }
     }
  }
}
</code>```

and thinking "oh yes another four-level loop over the kits", instead of seeing

```<code>pilgrim.kits.each { ++count; }
</code>```

Isn't this transparency valuable?

As you pointed out, there is a cost to indirection.  There is no point in creating layers "just in case".  Use abstraction to reduce duplication and clarify code.

Body:
Is there real value in hiding the details?

Yes.  By presenting abstractions we can think and program at a higher level.

Imagine modeling physical systems without calculus or matrix algebra.  It's completely impractical.  Similarly, if we can only program at a scalar level, we will be unable to solve interesting problems.  Even relatively simple web applications can benefit greatly from abstractions like tag libs.  It is much easier to insert a tag that means "address entry fields" than to repeatedly create four text fields and a select box.  And if you decide to expand overseas, you can just modify the tag definition, rather than fixing every form to handle international addresses.  Effective use of abstraction is what makes some programmers ten times as effective as others.

Humans have a limited working memory.  Abstraction allows us to reason about large systems.

Aren't we sacrificing transparency?

No.  If abstractions are not used, then the purpose of a software component is buried in repeated details.  Developers spend their days wading through code like this:

for (i = 0; i < pilgrim.wives.size(); ++i) {
  wife = pilgrim.wives[i];
  for (j = 0; j < wife.sacks.size(); ++j) {
     sack = wife.sacks[i];
     for (k = 0; j < sack.cats.size(); ++j) {
        cat = sack.cats[k];
        for (m = 0; m < cat.kits.size(); ++m) {
           ++count;
        }
     }
  }
}

and thinking "oh yes another four-level loop over the kits", instead of seeing

pilgrim.kits.each { ++count; }

Isn't this transparency valuable?

As you pointed out, there is a cost to indirection.  There is no point in creating layers "just in case".  Use abstraction to reduce duplication and clarify code.


问:
Never use Strings in Java?
I stumbled upon a blog entry discouraging the use of Strings in Java for making your code lack semantics, suggesting that you should use thin wrapper classes instead. This is the before and after examples the said entry provides to illustrate the matter:

```<code>public void bookTicket(
  String name,
  String firstName,
  String film,
  int count,
  String cinema);

public void bookTicket(
  Name name,
  FirstName firstName,
  Film film,
  Count count,
  Cinema cinema);
</code>```

In my experience reading programming blogs I've come to the conclusion that 90% is nonsense, but I'm left wondering whether this is a valid point. Somehow it doesn't feel right to me, but I couldn't exactly pinpoint what is amiss with the style of programming.

答:
Don't do it; it will overcomplicate stuff and You Ain't Gonna Need It

... is the answer I would have written here 2 years ago. Now, though, I'm not so sure; in fact, in recent months I've started migrating old code to this format, not because I have nothing better to do but because I genuinely needed it for implementing new features or changing existing ones. I understand the automatic aversions others here have seeing that code, but I think this is something that deserves serious thought.

Benefits

Chief among benefits is the ability to modify and extend the code. If you use

```<code>class Point {
    int x,y;
    // other point operations
}
</code>```

instead of just passing a couple of integers around - which is something that, unfortunately, many interfaces do - then it becomes far easier to later add another dimension. Or change the type to double. If you use List<Author> authors or List<Person> authors instead of List<String> authors it later becomes much easier to add more information to what an author represents. Writing it down like this it feels like I'm stating the obvious, but in practice I've been guilty of using strings this way many times myself, especially in cases where it wasn't obvious at start then I'd need more than a string.

I'm currently trying to refactor some string list which is intertwined throughout my code because I need more information there, and I feel the pain :\

Beyond that, I agree with the blog's author that it carries more semantic information, making it easier for the reader to understand. While parameters are often given meaningful names and get a dedicated line of documentation, this is often not the case with fields or locals.

The final benefit is type safety, for obvious reasons, but in my eyes it's a minor thing here.

Drawbacks

It takes longer to write. Writing a small class is fast and easy but not effortless, especially if you need a lot of these classes. If you find yourself stopping every 3 minutes to write some new wrapper class, it can be a real detriment to your concentration, too. I'd like to think, however, that this state of effort will usually only happen at the first stage of writing any piece of code; I can usually get a pretty good idea quickly of what entities will need to be involved.

It can involve a lot of redundant setters (or constructions) and getters. The blog author gives the truly ugly example of new Point(x(10), y(10)) instead of new Point(10, 10), and I'd like to add that a usage might also involve stuff like Math.max(p.x.get(), p.y.get()) instead of Math.max(p.x, p.y). And long code is often considered harder to read, and justly so. But in all honesty, I have a feeling a lot of code moves objects around, and only select methods create it, and even fewer need access to its gritty details (which isn't OOPy anyway).

Debatable

I'd say whether or not this helps with the readability of code is debatable. Yes, more semantic information, but longer code. Yes, it's easier to understand the role of each local, but it's harder to understand what you can do with it unless you go and read its documentation.

As with most other programming schools of thought, I think it's unhealthy to take this one to the extreme. I don't see myself ever separating the x and y coordinate to be each of a different type. I don't think Count is necessary when an int should suffice. I dislike the unsigned int usage in C - while theoretically good, it just doesn't give you enough information, and it does prohibit extending your code later to support that magical -1. Sometimes you do need simplicity.

I think that blog post is a bit on the extreme side. But overall, I have learned from painful experience that the basic idea behind it is made from the right stuff.

I have a deep aversion to over-engineered code. I truly do. But used right, I don't think this over-engineering.

Title: Never use Strings in Java?

Body:
Don't do it; it will overcomplicate stuff and You Ain't Gonna Need It

... is the answer I would have written here 2 years ago. Now, though, I'm not so sure; in fact, in recent months I've started migrating old code to this format, not because I have nothing better to do but because I genuinely needed it for implementing new features or changing existing ones. I understand the automatic aversions others here have seeing that code, but I think this is something that deserves serious thought.

Benefits

Chief among benefits is the ability to modify and extend the code. If you use

class Point {
    int x,y;
    // other point operations
}

instead of just passing a couple of integers around - which is something that, unfortunately, many interfaces do - then it becomes far easier to later add another dimension. Or change the type to double. If you use List<Author> authors or List<Person> authors instead of List<String> authors it later becomes much easier to add more information to what an author represents. Writing it down like this it feels like I'm stating the obvious, but in practice I've been guilty of using strings this way many times myself, especially in cases where it wasn't obvious at start then I'd need more than a string.

I'm currently trying to refactor some string list which is intertwined throughout my code because I need more information there, and I feel the pain :\

Beyond that, I agree with the blog's author that it carries more semantic information, making it easier for the reader to understand. While parameters are often given meaningful names and get a dedicated line of documentation, this is often not the case with fields or locals.

The final benefit is type safety, for obvious reasons, but in my eyes it's a minor thing here.

Drawbacks

It takes longer to write. Writing a small class is fast and easy but not effortless, especially if you need a lot of these classes. If you find yourself stopping every 3 minutes to write some new wrapper class, it can be a real detriment to your concentration, too. I'd like to think, however, that this state of effort will usually only happen at the first stage of writing any piece of code; I can usually get a pretty good idea quickly of what entities will need to be involved.

It can involve a lot of redundant setters (or constructions) and getters. The blog author gives the truly ugly example of new Point(x(10), y(10)) instead of new Point(10, 10), and I'd like to add that a usage might also involve stuff like Math.max(p.x.get(), p.y.get()) instead of Math.max(p.x, p.y). And long code is often considered harder to read, and justly so. But in all honesty, I have a feeling a lot of code moves objects around, and only select methods create it, and even fewer need access to its gritty details (which isn't OOPy anyway).

Debatable

I'd say whether or not this helps with the readability of code is debatable. Yes, more semantic information, but longer code. Yes, it's easier to understand the role of each local, but it's harder to understand what you can do with it unless you go and read its documentation.

As with most other programming schools of thought, I think it's unhealthy to take this one to the extreme. I don't see myself ever separating the x and y coordinate to be each of a different type. I don't think Count is necessary when an int should suffice. I dislike the unsigned int usage in C - while theoretically good, it just doesn't give you enough information, and it does prohibit extending your code later to support that magical -1. Sometimes you do need simplicity.

I think that blog post is a bit on the extreme side. But overall, I have learned from painful experience that the basic idea behind it is made from the right stuff.

I have a deep aversion to over-engineered code. I truly do. But used right, I don't think this over-engineering.


答:
In so many cases you simply don't need to know how things are implemented.  I can almost guarantee that you'll write code like this people.Where(p => p.Surname == "Smith") so many times a day yet you will hardly ever think "how does this Where() method actually work?"  You just don't care - you know this method is there and that it gets you the results you want.  Why would you care how it works?

This is exactly the same for any in-house software; just because it's not written by Oracle, Microsoft, etc doesn't mean that you should have to go hunting into how it's implemented.  You can reasonably expect that a method called GetAllPeopleWithSurname(string name) to return you a list of people who have that surname.  It might iterate over a list, it might use a dictionary, it might do something completely crazy but you just shouldn't care.

There is an exception to this rule of course (it wouldn't be a rule without one would it!) and that is if there is a bug in the method.  So in the above example, if you have a list with 3 people in it and you know that one of them has the surname Smith and they aren't returned in the list then you care about the implementation of that method because it is clearly broken.

Abstraction, when done correctly, is wonderful because it allows you to filter out all of the stuff that isn't useful when you have to read it at a later date.  Don't forget that much more time is spent reading code than is spent writing it, therefore the emphasis must be on making that task as easy as possible.  You might also be thinking that abstraction means a hierarchy of objects as long as your arm but it can be as simple as refactoring a 100 line method into 10 methods, each 10 lines long.  So what was once 10 steps all bundled together is now 10 separate steps allowing you to go straight to the place where this pesky bug is hiding.


答:
Abstractions result in information hiding. This should end up in lower coupling. This should lead to fewer risks in change. This should lead to happy programmers, not getting nervous when touching code.

Those ideas are expressed through three essential laws in software architecture:

Simon's Law:
"Hierarchies reduce complexity." (Hierarchies introduce abstraction)

Parna's Law:
"Only what is hidden can be changed without risk."

Constantin's Law:
Robust programs need low coupling and high cohesion


答:
Use the one that makes your code most readable. Don't worry about performance.

For your example below I prefer B because it is just more readable. But the language translations above also makes sense. Don't let anyone force you into using string.Format, instead read and point to Jeff Atwoods excellent blog on the The Sad Tragedy of Micro Optimizations Theater

A:

```<code>string output;
int i = 10;
output = string.Format("the int is {0}", i);
</code>```

versus

B:

```<code>string output;
int i = 10;
output = "the int is " + i;
</code>```

Body:
Use the one that makes your code most readable. Don't worry about performance.

For your example below I prefer B because it is just more readable. But the language translations above also makes sense. Don't let anyone force you into using string.Format, instead read and point to Jeff Atwoods excellent blog on the The Sad Tragedy of Micro Optimizations Theater

A:

string output;
int i = 10;
output = string.Format("the int is {0}", i);

versus

B:

string output;
int i = 10;
output = "the int is " + i;


问:
How do I write a specification?

Possible Duplicate:

  how do I write a functional specification quickly and efficiently

With so many projects changing halfway - and clients assuming much can be changed at no additional cost - I would like to start writing specifications. However, I have not done this before and do not know much about the basics. Where do I start? Are there often-used formats or templates for writing specifications? Does the programmer write this, does the client do this, or do both write this up? Any places where to see sample specs? All advise on how to get started is welcome.

答:
There are entire university courses dedicated to requirements engineering, so a full discussion is beyond the scope of this question. I can, however, point you to some resources that should be helpful to get you started. I would suggest you poke around, both in what I provide and in other resources, and try to focus on more specific areas.

The textbook used in my requirements engineering course was Software Requirements. I also purchased an addendum to the book, More About Software Requirements. They tend to be more about requirements in plan-driven and documentation-heavy methodologies, they do discuss user stories and use cases in addition to formal requirement specification documents. They also walk through requirements elicitation techniques and vision and scope as well. The author of these books has a site, Process Impact, that has some resources as well, including various templates and guides.

If you are looking for more templates to follow, I usually recommend the ReadySet Templates. There are various templates to follow for different activities and phases of the lifecycle. Be sure to tailor them as appropriate to best fit into your development process.

As far as who develops the specification, it depends on how the project is structured, but usually it's a collaboration. I've seen where the customer knows what they want and they work with the development organization to develop a vision, scope for the work, and requirements specification. I've also seen where the customer has documents that specify the business and operational requirements and development organizations work with that to develop system requirements that can be used by engineers.

Title: How do I write a specification?


答:
If you have never written a specification before, start small. A short text about the planned processes, the most important database tables and/or classes and a few sketched screen layouts, together with all the hard facts (descriptions of import/export formats etc.) can work wonders.

It's all too easy to fall into analysis paralysis when you focus too much on doing it right, using UML to it's full extend and having every arrow with the right kind of tip. Specifications can literally grow to any size when you have no idea how much detail is enough.

Title: How do I write a specification?

Body:
Possible Duplicate:

  how do I write a functional specification quickly and efficiently

With so many projects changing halfway - and clients assuming much can be changed at no additional cost - I would like to start writing specifications. However, I have not done this before and do not know much about the basics. Where do I start? Are there often-used formats or templates for writing specifications? Does the programmer write this, does the client do this, or do both write this up? Any places where to see sample specs? All advise on how to get started is welcome.


问:
Difference between a service class and a Helper class
I would like to know what differentiates  a Service class from a utility class or a helper class?
A class only with underlying methods calls the dao's is a service? Doesn't the usage of Helper classes violates SRP?</p>

答: Not a scientific definition, but my general take is a service class has some context within the application whereas helpers are more generic and don't care what app they are helping. </p>


问:
Will giving new recruits a separate subproject from experienced developers help the newbies ramp up more quickly?
We have 7 developers in a team and need to double our development pace in a short period of time (around one month). I know there is a common sense rule that "if you hire more developers, you only lose in productivity for the first few months". The project is an e-commerce web service and has around 270K lines of code.

My idea for now is to divide the project in two more or less independent sub-projects and let the new team work on the smaller of the two sub-projects, while the current team works on the main project. Namely, the new team will work on checkout functionality, which will eventually become an independent web service in order to decrease coupling. This way, the new team works on a projects with only 100K lines of code.

My question is: will this approach help newbie developers to adapt easily to the new project? What are other ways to extend the development team rapidly without waiting two months until newbies start producing more software then bugs?

=======

UPDATE

This enterprise failed completely, but not for the reasons you guys mentioned. First of all, I was misinformed about the size and capability of the new team. I should have evaluated them myself. Second, hiring turned out to be a hard job at that site. At the site of the main office hiring was much more easy, but in the city of the second team there was apparently shortage of developers with the required qualification. As a result, instead of projected 1.5 months the job extended to about 4.5 months, and was cancelled in the middle of it by the top management.

Another mistake I made (and was warned about it by Alex D) is that I was trying to sell refactoring to the top management. You never sell refactoring, only features.

The startup turned out to be successful anyway. The refactoring that never happened turned into technical debt: the system became more monolithic and less maintainable, developer productivity gradually decreased. I am not in the team now, but I do hope they complete it in the nearest future. Otherwise, I wouldn't give a penny for the project's survival.

答:
Altought, Im agree like the everyone else here, that:

"...adding more developers to a delayed project, makes the project, to delay more..."

I have the feeling, you are going to do it, anywhere, so...

Your idea may help, if, your existing project, is enough organizated, by modules, subsystems or subprojects.

What you may want to try, its to give them small pieces / modules / forms / classes of your project, to work with, instead of all the project.

If you use a database, you may want to make a copy of a working D.B. with data, and access them from the module or subsystem of code there going to work with.

Having new developers that know the programming language or programming enviroment, is not enough, software aplications can become very complex.

Do you have some documentation of the aplication like: U.M.L., E.R., Codd-Yourdon, whatever ?

Good Luck.


问:
How to handle onsite interviews with multiple companies?
I currently live in Thailand now. I have done phone interviews with few companies in San Francisco and passed all of them.

Now the problem is I have onsite interviews with 3 companies, and they are willing to pay for the flights and the hotels.

I have no idea what to do right now. I don't want to fly back and forth between Thailand and San Francisco 3 times.

I believe I have 2 choices:

Lie to the first company that I want to do sight-seeing for some days, and ask them to move the flight back a little bit further.

Tell the HR directly that I will have an interview with other companies as well, and ask the first company to pay for the flight to SF and the second company to pay for the flight back to Thailand. (The third company gets a free pass)

The flight between Thailand and San Francisco should cost like 1,500 dollars. (round-trip)

What should I do?

答:
Remember, you're just as important to them as they are to you. Set up your schedule to what suits your needs.. AND you SHOULD do some sight seeing if you're going to be relocating..

EDIT:
I guess by sight seeing, i meant get familiar with the new environment to ensure you're going to like living there. As far as going to other companies.. I'm not sure on that one, one the one hand, yes, you are only there because company A got you there.. on the other hand, you need to do what's best for you..

Now there's no guarantee that you're going to get that initial job, maybe you dont want it, or maybe they find another candidate.. now if either of these occur, having those back-ups would be a great decision.

And i dont think anyone at Company A would hold it against you. I would however give Company A the top priority.. meaning if they make you a reasonable offer, while not be Obligated, it may

good luck!


问:
How do you respond to "Tell me a little bit about yourself." question in interviews?
I've been asked this in a few interviews. And it always catches me off guard.My professional and academic background are already in the resumé, which the interviewer has obviously looked at. What more to tell him/her? Should I start with my hobbies? I like gardening, or looking at NSFW pictures on reddit in my free time?

What and how do you answer to this specific question? Do you have a prepared answer for it? Am I wrong if I think this question is a bit silly?

UPDATE There have been a lot of great answers to this question. I'm in pickle which to choose as the 'correct' answer, because most of them are very insightful. I found a great writing on this subject matter. It's a bit crazy for my taste, but it's interesting:

How To Introduce Yourself… I Mean Practically

答:
I usually tell them what I have done in the past years, and why I am applying for a job.

Remember to make it short.


答:
Perhaps a great first step for you is to institute simple change control. The next time a client asks for a change, tell them that this is a change that was not included in the original estimate. Tell them if they would like to have the change to send you the details of what the want in an email and you will get back to the with a price.

The benefit of this is that it makes explicit that changes are occurring. By sending an email, the client is acknowledging that it is in fact a change.

What is likely to occur is that this will cause the client to ask for fewer changes. At a minimum it will cause them to understand the extent of the changes and make explicit wat was involved.

It is up to you if you choose to ask for additional money for the changes, some may be simple enough that you will throw them in for free like you do now. The difference would be that at the end of the job you have a paper trail of the extra value you delivered which should help you win repeat business. For bigger changes, definitely charge.

Title: How do I write a specification?


问:
Designing my password class(es). How to split it up?
I've inherited a custom made authentication system that needs some refactoring.  I'm not quite sure what the best way to split it up the password section and could use some help.

The password class(es) need the following functionality:

Check to see if a password conforms to restrictions. It needs to be able to provide feedback on why it is incorrect.

Generate three kinds of hashes.  We have several file-systems with incompatible hashes, so unfortunately I have to maintain three hashes.

Give a different hash for a certain user type. If a user is web-only we do not keep a password for them as they cannot use the system.  Their passwords are always *.

Be able to verify a password for a given user. Fortunately I only have to authenticate against one of the three hashes I have to maintain.

Be able to generate a random password, unencrypted.

Submit new password to the database.

I'm thinking about using four classes, Validator, Hasher, Generator, and Changer.

Validator

isCurrentPassword(int userid, string password): bool

getViolations(string password): array

Generator

generate(int length):string Creates a password.

Hasher

hash_*(string password): string where * is the hash type.  I'll have four hashing functions.

Changer

change(int userid, string password):void; throws database exceptions

What would you recommend and why?

答:
I think you need 2 interfaces:

IPasswordValidator : validates password / handles UI messaging about validation.

IAuthenticationScheme : handles the authentication / hashing / updating of passwords

IPasswordValidator probably only needs one concrete implementation but it is simple enough to put it behind an interface to document the contract at least. Testability is a bonus. IPasswordValidator covers your getViolations method.

IAuthenticationScheme is where the fun happens -- this is where you wire up your alternate hashing schemes and whatever data dependencies you have. In your original scheme this combines hasher and changer and your isCurrentPassword classes and methods.

Generation isn't really a concern covered in either, it would probably be best left to a utility library. If generation is implementation dependent -- such as if a certain provider had any particular requirements -- you could move generation into IAuthenticationScheme.


答:
Actually you have a third choice. Tell the first company that you want to stay in San Francisco for personal reasons, they do not need to know why you want to stay on. If pressed you can always say you want to take some time to decide if it is a place where you would want to work. Of course they would only pay for the hotel until you would have left, it is your responsibility after that.

For the other two companies, you can tell them that you will be coming to the USA for other reasons (once again you do not need to tell them why) and suggest that in lieu of providing you with an airline ticket they simply pay you a flat $1,500 (each) towards your travel expenses. That would save them money since they do not have to pay for a hotel, so I would think they would go for it.

Doing it this way you could end up with a couple of grand in your pocket. It is all perfectly ethical as you have not lied to anyone.

Title: How to handle onsite interviews with multiple companies?

Body:
I currently live in Thailand now. I have done phone interviews with few companies in San Francisco and passed all of them.

Now the problem is I have onsite interviews with 3 companies, and they are willing to pay for the flights and the hotels.

I have no idea what to do right now. I don't want to fly back and forth between Thailand and San Francisco 3 times.

I believe I have 2 choices:

Lie to the first company that I want to do sight-seeing for some days, and ask them to move the flight back a little bit further.

Tell the HR directly that I will have an interview with other companies as well, and ask the first company to pay for the flight to SF and the second company to pay for the flight back to Thailand. (The third company gets a free pass)

The flight between Thailand and San Francisco should cost like 1,500 dollars. (round-trip)

What should I do?


答:
Is there any standard way for knowing when to stop writing user stories, and if so, what is the basis for this, and how does it apply to future sprints?

I don't personally know of a standard method per se. It really comes down to a combination of your methodology, and your customer's expectations.

I have found that it is better to start coding as soon as you have "enough" stories from your customer to make a start.  As others have said, this could be for a single iteration, however it could be for more. Your measure of enough should be guided by how often you intend to release working code to your customer, and rather than have your customer give you and endless list of stories (many of which will probably never get done, or might change, or might not make your major release deadline), it's better to ask your customer for the first 3-5 most important and highest priority features.  When those are done and released to your customer, you collect the next most important 3-5 features and so on.  Ask for more or less depending on how long your iterations are likely to be.

Your customer or contract or deadline perhaps may guide you as to when to actually stop asking for stories, yet in the meantime, you have been asking for stories and stopping as often as you have had iterations.  When by agreement you and the customer feel the product is complete enough, you can then decide what to do with any left over stories that the customer may have not given you yet.

The main advantage of this approach is that you end up delivering the greatest value to the customer up front, and as the project grows and time passes, the amount of value you are delivering to the customer decreases to the point whee the customer can make a decision about the "last 20% of features" that they might have wished for which might never actually be used. It also cuts down on time wasted on trivial and low priority items, putting the responsibility (and stress) of prioritizing and scheduling iterations back on the customer, and all based solely on the customer's needs. That doesn't mean however you shouldn't provide guidance to the customer in order to avoid difficult scheduling bottlenecks that may become apparent as you talk requirements with the customer.

Have a read of the Poppendeicks' Lean Software Development if you'd like a more detailed description of this approach in a wider context.


问:
What is the name of ** in python?
When programming Python I sometimes do a ** to make a conversion. I understand what it does but what data structures am I manipulating? A dict and what is the other? An array? Is there a name for the ** operator?

答: If you are unsure what to call a particular operator or if it is unnamed, you can always resort to Waka Waka Bang Splat as a reference to help you figure out what to call it. In this case for ** I would call it double-splat, though there are some alternate names for symbols.

Title: What is the name of ** in python?


答:
Think about this, if your trip was paid for by one company, then you decided to work for another and the first found out you had taken another job during a trip they paid for, how would they react?

Your question is not easy to answer. One thing that springs to mind is to first be honest. Tell the companies that you have been asked to do interviews by other companies and that you propose to split the trip costs 3 ways. They each get to pay 1/3rd of what they where expecting and everything is open and on the table. Plus, if they know that there is competition, they may make addtional offers during the interviews that they would not normally do.

I don't know if this would work, but I to think that people appreciate honesty. They were going to pay for your trip anyway so you saving them most of the costs should be appreciated. If they don't like the fact that you are considering all options and other companies, I'd be inclined to think they might not be a good place to work for.