问:
Effective way of keeping past projects with their working development environment?
I find that whenever I want to go run a past project, it will take a long time before I can find it and before I have everything set-up again for it to be able to run.

For example, I have python projects I created in Linux, and it depends on software packages that are easily installed in Linux, yet I no longer have the Linux VM I was using.  And some of my other projects depend on other variables like web server configuration, PATH variables, sdk, IDE, OS version, device, etc.

Does someone have an effective way of handling this issue?  As of now I have only concerned myself with keeping the source code backed up yet it is difficult re-establish the working development environment and it is also difficult to keep the working development environment around as well.

答:
Docker would be a good option. You can use a dockerfile to act as a manifest for the VM you want. You do not need to store any image, it will download the required one. Also, it can use your own images, so you could make your own base image and then add the components required by the environment.

Using docker this can also improve other parts of your workflow:

The created environment can be put on the same CVS than your project, that gives you a versioned environment (neat!)

The docker can be used to provision the live environment, lowering the headaches of launching your projects in production.

If others start working with you, all they need is the dockerfile to load that huge environment setup.

So the ideas here about using a VM are only partly right, I know that HDD's are getting bigger and bigger but it's not a reason to use up all the space you have. Also, when a VM environment needs more HDD space internally, this can be a bit tricky and chances are you'll need to rebuild one. Although file size may not be an issue, internet speed still become the bottleneck when you need to send over 5Go on a normal DSL connection.


问:
How do I balance 100 clients checking the same database table in a loop?

What I have

This is a prototype. I have a pool of 100 clients connected to the server via websockets reporting things and awaiting for commands. The server polls the commands database table of type MEMORY in a loop using a query with WHERE client_id=?. I can insert a combination of client_id+command to that table, and once I do that, the corresponding loop will match and SELECT it and pass it back to the client.

What's the problem

The approach sounds like it would work, but as far as I understand I'm talking about n simultaneous database connections and queries in an endless loop (n being the number of clients), which doesn't sound effective. It'd be much better to do one query in one loop and then somehow check the client_id, if any, and distribute the results to the corresponding clients.

This reminds me of the approach where you're selecting articles first and then for () {} the resultset and do separate queries to get the details foe each of the items, which results in n+1 queries being made. The solution to that is doing a big query with JOINs and also preloading the other data that doesn't fit into the main JOINed query. There should be the similarly more effective way to do the database polling too.

UPDATE: I found this answer in the related section, and it says pretty much the same thing:

Hammering your database isn't really a good idea. While I'm pretty sure you've realized this, others might not have. I remember a friend of mine tried to use a php script and a Javascript AJAX function in a loop for a semi-real time game. He very quickly realized that performance degraded as more people joined, simply because he was executing a ton of queries per second which hammered the database.

So polling the database for each client sounds as unscalable and ineffective as building an AJAX chat application.

What I'm asking for

I guess that every possible programming approach must have been named and covered by now, so what is this one called? What is the common advice/approach here?

答:
IMO, you almost figured everything yourself already... I'll try to elaborate what kind of pattern my favorite framework uses for this kind of thing.

First you have your clients subscribe to the commands, that way your server knows which socket (client) wants the commands associated to which client_id.
The server polls the database, every X seconds (milliseconds?) OR uses oplog tailing* to see if there are commands to be ran, if there are, it will send that command to the sockets subscribed according to the target client_id...

*oplog tailing is used in replicasets, it is a log of all operations done in a database. Tailing it can be more effective than pooling the database directly... Either using the tail to just know when a new document has been inserted and then knowing that the database should be queried will lower loads on large sets, but might not be needed.

ContentLicense: CC BY-SA 3.0


问:
When to use CSS pseudo-elements?
::before and ::after are CSS pseudo-elements which allow stylesheet to specify the content.

Apart from html usually specifying the content, When do I think of using these pseudo-elements?

答:
The popular clear-fix solution uses a pseudo element to clear the elements' floats.

```<code>.clearfix:after {
    visibility: hidden;
    display: block;
    font-size: 0;
    content: " ";
    clear: both;
    height: 0;
}
</code>```

Also, there is wikipedia-like external links. One can auto-matically target links pointing to other domains, or that target _blank and add a little icon after it to let the user know...

There are a multitude of ingenious ways to use those pseudo elements. In your everyday life, you will very rarely encounter the need to use those elements, but it is very nice to know they exist for that exact time when you need them.

Edit:

I used it myself to effectively hide my e-mail adress on my website, since pseudo-elements cannot be target by JS, and do not appear in the HTML source, I thought it'd be nice to make sure crawlers wouldn't get to it.

Title: When to use CSS pseudo-elements?

Body:
The popular clear-fix solution uses a pseudo element to clear the elements' floats.

.clearfix:after {
    visibility: hidden;
    display: block;
    font-size: 0;
    content: " ";
    clear: both;
    height: 0;
}

Also, there is wikipedia-like external links. One can auto-matically target links pointing to other domains, or that target _blank and add a little icon after it to let the user know...

There are a multitude of ingenious ways to use those pseudo elements. In your everyday life, you will very rarely encounter the need to use those elements, but it is very nice to know they exist for that exact time when you need them.

Edit:

I used it myself to effectively hide my e-mail adress on my website, since pseudo-elements cannot be target by JS, and do not appear in the HTML source, I thought it'd be nice to make sure crawlers wouldn't get to it.


问:
Tracking time users spend on my website
We are going to track user engagement (i.e. time spent on website, most viewed part/page of the system, etc).

I don't see Google Analytics / MixPanel being able to do this, since we have to analyze based on factors only present in OUR backend (such as users who go to specific school, users who are a specific type, etc) - not the general stuff like Country, Gender, etc.

I can think of a REALLY simple solution, but I am not sure if it is, serverwise, bad. You have a table that looks something like this:

```<code>CREATE TABLE `log` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `uri` int(11) DEFAULT NULL,
  `date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `user` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
</code>```

And then whenever a page is loaded, a row is added to the "log" table, with current timestamp, the user id and the uri.

Now I got the data I want, which is great. I can figure out when the user was last online and how many minutes people spend in average.

BUT. Is this bad for the server? It is going to add a row each page load, which is a lot of rows, if you have 500 or 1000 active users. But will it matter? What are your thoughts?

答:
It is not necessarily bad for the server to log a line per page request. However, there are few things to consider here. First of all, I see you are using an AUTO_INCREMENT as a key. This will result in some performance loss as you are writing records to it.

You could replace the id with a GUID field and generate GUID's as you write lines.

Another optimization that you could to is to make this asynchronously. So the user requests a page, which you serve to the user, and while you do, you fire off a request, event, or whatever is suitable for your server side technology and does not block sending back the request, to actually write your logging.

Another thing to consider is, do you really need the data in a database immediately? It might be sufficient to just write to a log file first and import the data into a database at a later point in time.

Title: Tracking time users spend on my website


问:
Iterator pattern - why is it important to not expose the internal representation?
I am reading C# Design Pattern Essentials. I'm currently reading about the iterator pattern.

I fully understand how to implement, but I don't understand the importance or see a use case. In the book an example is given where someone needs to get a list of objects. They could have done this by exposing a public property, such as IList<T> or an Array.

The book writes

The problem with this is that the internal representation in both of these classes has been exposed to outside projects.

What is the internal representation? The fact it's an array or IList<T>? I really don't understand why this is a bad thing for the consumer (the programmer calling this) to know...

The book then says this pattern works by exposing its GetEnumerator function, so we can call GetEnumerator() and expose the 'list' this way.

I assume this patterns has a place (like all) in certain situations, but I fail to see where and when.

答:
Hiding the implementation is a core principle of OOP and a good idea in all paradigms, but it especially important for iterators(or whatever they're called in that specific language) in languages that support lazy iteration.

The problem with exposing the concrete type of iterables - or even interfaces like IList<T> - is not in the objects that expose them, but in the methods that use them. For example, let's say you have a function for printing a list of Foos:

```<code>void PrintFoos(IList<Foo> foos)
{
    foreach (foo in foos)
    {
        Console.WriteLine(foo);
    }
}
</code>```

You can only use that function to print lists of foo - but only if they implement IList<Foo>

```<code>IList<Foo> foos = //.....
PrintFoos(foos);
</code>```

But what if you want to print every even-indexed item of the list? You'll need to create a new list:

```<code>IList<Foo> everySecondFoo = new List<T>();
bool isIndexEven = true;
foreach (foo; foos)
{
    if (isIndexEven)
    {
        everySecondFoo.Add(foo);
    }
    isIndexEven = !isIndexEven;
}
PrintFoos(everySecondFoo);
</code>```

This is quite long, but with LINQ we can do it to a one-liner, which is actually more readable:

```<code>PrintFoos(foos.Where((foo, i) => i % 2 == 0).ToList());
</code>```

Now, did you notice the .ToList() in the end? This converts the lazy query into a list, so we can pass it to PrintFoos. This requires an allocation of a second list, and two passes on the items(one on the first list to create the second list, and another on the second list to print it). Also, what if we have this:

```<code>void Print6Foos(IList<Foo> foos)
{
    int counter = 0;
    foreach (foo in foos)
    {
        Console.WriteLine(foo);
        ++ counter;
        if (6 < counter)
        {
            return;
        }
    }
}

// ........

Print6Foos(foos.Where((foo, i) => i % 2 == 0).ToList());
</code>```

What if foos has thousands of entries? We will have to go through all of them and to allocate a huge list just to print 6 of them!

Enter Enumerators - C#'s version of The Iterator Pattern. Instead of having our function accept a list, we make it accept Enumerable:

```<code>void Print6Foos(Enumerable<Foo> foos)
{
    // everything else stays the same
}

// ........

Print6Foos(foos.Where((foo, i) => i % 2 == 0));
</code>```

Now Print6Foos can lazily iterate over the first 6 items of the list, and we don't need to touch the rest of it.

Not exposing the internal representation is the key here. When Print6Foos accepted a list, we had to give it a list - something that supports random access - and therefore we had to allocate a list, because the signature does not guarantee that it'll only iterate over it. By hiding the implementation, we can easily create a more efficient Enumerable object that supports only what the function actually needs.

Body:
Hiding the implementation is a core principle of OOP and a good idea in all paradigms, but it especially important for iterators(or whatever they're called in that specific language) in languages that support lazy iteration.

The problem with exposing the concrete type of iterables - or even interfaces like IList<T> - is not in the objects that expose them, but in the methods that use them. For example, let's say you have a function for printing a list of Foos:

void PrintFoos(IList<Foo> foos)
{
    foreach (foo in foos)
    {
        Console.WriteLine(foo);
    }
}

You can only use that function to print lists of foo - but only if they implement IList<Foo>

IList<Foo> foos = //.....
PrintFoos(foos);

But what if you want to print every even-indexed item of the list? You'll need to create a new list:

IList<Foo> everySecondFoo = new List<T>();
bool isIndexEven = true;
foreach (foo; foos)
{
    if (isIndexEven)
    {
        everySecondFoo.Add(foo);
    }
    isIndexEven = !isIndexEven;
}
PrintFoos(everySecondFoo);

This is quite long, but with LINQ we can do it to a one-liner, which is actually more readable:

PrintFoos(foos.Where((foo, i) => i % 2 == 0).ToList());

Now, did you notice the .ToList() in the end? This converts the lazy query into a list, so we can pass it to PrintFoos. This requires an allocation of a second list, and two passes on the items(one on the first list to create the second list, and another on the second list to print it). Also, what if we have this:

void Print6Foos(IList<Foo> foos)
{
    int counter = 0;
    foreach (foo in foos)
    {
        Console.WriteLine(foo);
        ++ counter;
        if (6 < counter)
        {
            return;
        }
    }
}

// ........

Print6Foos(foos.Where((foo, i) => i % 2 == 0).ToList());

What if foos has thousands of entries? We will have to go through all of them and to allocate a huge list just to print 6 of them!

Enter Enumerators - C#'s version of The Iterator Pattern. Instead of having our function accept a list, we make it accept Enumerable:

void Print6Foos(Enumerable<Foo> foos)
{
    // everything else stays the same
}

// ........

Print6Foos(foos.Where((foo, i) => i % 2 == 0));

Now Print6Foos can lazily iterate over the first 6 items of the list, and we don't need to touch the rest of it.

Not exposing the internal representation is the key here. When Print6Foos accepted a list, we had to give it a list - something that supports random access - and therefore we had to allocate a list, because the signature does not guarantee that it'll only iterate over it. By hiding the implementation, we can easily create a more efficient Enumerable object that supports only what the function actually needs.


问:
Lean or agile SaaS: deployment / release features during or after sprint
For SaaS (software as a service), when using a lean or agile development process with short sprints/iterations (e.g. 1 to 3 weeks), which approach produces better quality: deploying/releasing features...

during the sprint in which they are developed, or

after the sprint (possibly much later if limited alpha/beta release or feature flags are used)?

I call out "features" specifically because with SaaS, we may need to release hot fixes at any moment, 24/7.

What criteria may help determine which choice is better?

Some strawman advantages for deployment (1) during the sprint:

Gets the entire development team more focused on ushering features all the way through to deployment

Slightly earlier and possibly more predictable schedule for delivery to downstream consumers (customers, product management)

If you have a "demo day", you can demo deployed features

...and for (2) after:

If the release process requires fewer resources than development and testing, then pipelining in this way can lead to higher throughput because development and testing can continue until later in the sprint

Precise deployment timing can possibly be more flexibly controlled, e.g. for limited alpha/beta releases (but maybe we just say it's "deployed" when it's in alpha/beta), feature flags (ditto last comment), marketing communications

If release engineering resources are insufficient (e.g. due to illness), release does not have to wait another full sprint but can instead occur as soon as resources are available (of course, the during alternative does not absolutely preclude this)

Meh, why not? You should be able to release SaaS anytime anyway, right? (A bit tongue-in-cheek there.)

答:
I'd propose releasing immediately on sprint completion, or as soon after as is possible. For these reasons

During the sprint puts a requirement on the team to have a potentially shippable increment available at all times during the sprint *See note below on this

Too far after the sprint is complete opens you up to issues being reported with work which has been long forgotten by the team. The shorter the gap between someone completing some work and issues being logged with it the fast it will be to fix.

Deploying soon after the sprint is completed and then fixing any issues gives you more confidence that all previous work is actually done and isn't going to come back and bite your schedule in the arse.

*Note: If you have your source control processes set up in such a way that continuous delivery is possible then by all means adopt a release train approach where releases go out on some schedule and deploy all recent changes. I'd still suggest deploying as frequently as possible to get work out there and in the hands of customers asap.

I think the general principle here is that complete but undeployed work has no or negative value. It has cost you effort to create but until it is in your customers hands you are not realising the value it can create. So, you should always strive to get work out to customers as soon as possible.


答:
In a similar setup, one of the domain's I develop logs pageloads and other in-page events to a logging table on a SQL Server. It uses an auto-incrementing int-PK. Per Google Analytics (GA), we've definitely seen over 500 "active users." And we haven't seen any problems logging to the table.

The notable difference for us, I think, is that we actually wrap the GA logging and have the browser initiate a separate logging request "alongside" the GA request. That allows any the bottlenecks in the logger to stay out of the more important matter of actually building the page.

But, I can't say whether this is feasible for your application, which likely has very different server loads, traffic patterns, locking patterns, etc.. At the very surface of it, you're obviously using a different DMBS, and probably a different server-side stack ... I can't say what impact that'll have.

But, the basic logging you want certainly can be feasible if your server resources can handle it, and ideally if you keep it "out of the way" of your core application logic.

Title: Tracking time users spend on my website

Body:
We are going to track user engagement (i.e. time spent on website, most viewed part/page of the system, etc).

I don't see Google Analytics / MixPanel being able to do this, since we have to analyze based on factors only present in OUR backend (such as users who go to specific school, users who are a specific type, etc) - not the general stuff like Country, Gender, etc.

I can think of a REALLY simple solution, but I am not sure if it is, serverwise, bad. You have a table that looks something like this:

```<code>CREATE TABLE `log` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `uri` int(11) DEFAULT NULL,
  `date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `user` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
</code>```

And then whenever a page is loaded, a row is added to the "log" table, with current timestamp, the user id and the uri.

Now I got the data I want, which is great. I can figure out when the user was last online and how many minutes people spend in average.

BUT. Is this bad for the server? It is going to add a row each page load, which is a lot of rows, if you have 500 or 1000 active users. But will it matter? What are your thoughts?


问:
What are the justifications for annotations in a programming language?
After spending a great deal of time writing C# and looking at Java, it seems to me that annotations are just an ugly code smell that introduce another conceptual layer that could easily be replaced by existing language features, whether they be keywords (as in the case of C#'s override keyword versus Java's @override annotation) or inheritance (why not just have a ISerializable interface or base class instead of a [Serializable] attribute?) However, this conclusion could just as easily be due my relative inexperience as a professional programmer.

My question is compound:

What do annotations bring to the table that cannot be accomplished in other ways, without complicating the grammar of a language?

Are there things that can be implemented without annotations, but which would be much more difficult to implement without them?

More generally, where (if anywhere) is the demarcation line between data and metadata in a programming language?

My question is different from What problems are Java annotations well suited to?. For starters, this question is not Java-specific. I'm wanting to know, in general, whether annotations are indispensable or merely useful. I am also curious as to the theoretical distinction between data and metadata, and how useful that distinction really is.

答:
Annotations can be user specified and accessible by reflection.

This means you can create a framework to look into a user's classes and pull out the needed information.

The annotations are also close to where they have effect. It's possible to extract all annotations out to a config file and have the framework parse that but that can lead to typo related bugs and forgetting to update the configs.

For example a testing framework would iterate over all functions of an object and use the annotations to check whether a test should throw an exception and if so which one. without this the test would need to catch the exception and do a FailTest() call after the method that should throw. Even marking which methods are tests and which are helpers, setup or tear-down would be annoying.

A DI framework could look at a constructed object and fill the annotated field with the correct implementation without needing to add yet another parameter to the constructor.

They make life easier on the user's side of the API at the cost of often being a pain to program and debug.


问:
Why would you not use the 'using' directive in C#?
The existing coding standards on a large C# project includes a rule that all type names be fully qualified, forbidding employment of the 'using' directive. So, rather than the familiar:

```<code>using System.Collections.Generic;

.... other stuff ....

List<string> myList = new List<string>();
</code>```

(It's probably no surprise that var also is prohibited.)

I end up with:

```<code>System.Collections.Generic.List<string> myList = new System.Collections.Generic.List<string>();
</code>```

That's a 134% increase in typing, with none of that increase providing useful information. In my view, 100% of the increase is noise (clutter) that actually impedes understanding.

In 30+ years of programming, I've seen such a standard proposed once or twice, but never implemented. The rationale behind it escapes me. The person imposing the standard is not stupid, and I don't think he's malicious. Which leaves misguided as the only other alternative unless I'm missing something.

Have you ever heard of such a standard being imposed? If so, what was the reason behind it? Can you think of arguments other than "it's stupid," or "everybody else employs using" that might convince this person to remove this prohibition?

Reasoning

The reasons for this prohibition were:

It's cumbersome to hover the mouse over the name to get the fully qualified type. It's better to always have the fully qualified type visible all the time.

Emailed code snippets don't have the fully qualified name, and therefore can be difficult to understand.

When viewing or editing the code outside of Visual Studio (Notepad++, for example), it's impossible to get the fully qualified type name.

My contention is that all three cases are rare, and that making everybody pay the price of cluttered and less-understandable code just to accommodate a few rare cases is misguided.

Potential namespace conflict issues, which I expected to be the primary concern, weren't even mentioned. That's especially surprising because we have a namespace, MyCompany.MyProject.Core, which is an especially bad idea. I learned long ago that naming anything System or Core in C# is a quick path to insanity.

As others have pointed out, namespace conflicts are easily handled by refactoring, namespace aliases, or partial qualification.

答:
The broader question:

Have you ever heard of such a standard being imposed? If so, what was the reason behind it?

Yes, I've heard of this, and using fully qualified object names prevents name collisions.  Though rare, when they happen, they can be exceptionally thorny to figure out.

An Example:
That type of a scenario is probably better explained with an example.

Let's say we have two Lists<T> belonging to two separate projects.

```<code>System.Collections.Generic.List<T>
MyCorp.CustomCollections.Optimized.List<T>
</code>```

When we use the fully qualified object name, it's clear as to which List<T> is being used.  That clarity obviously comes at the cost of verbosity.

And you might be arguing, "Wait! No one would ever use two lists like that!"  Which is where I'll point out the maintenance scenario.

You've written module Foo for your corporation which uses the corporation approved, optimized List<T>.

```<code>using MyCorp.CustomCollections.Optimized;

public class Foo {
    List<object> myList = ...;
}
</code>```

Later on, a new developer decides to extend the work you've been doing.  Not being aware of the company's standards, they update the using block:

```<code>using MyCorp.CustomCollections.Optimized;
using System.Collections.Generic;
</code>```

And you can see how things go bad in a hurry.

It should be trivial to point out that you could have two proprietary classes of the same name but in different namespaces within the same project.  So it's not just a concern about colliding with .NET Framework supplied classes.

```<code>MyCorp.WeightsAndLengths.Measurement();
MyCorp.TimeAndSpace.Measurement();
</code>```

The reality:

Now, is this likely to occur in most projects?  No, not really.  But when you're working on a large project with a lot of inputs, you do your best to minimize the chances of things exploding on you.

Large projects with multiple contributing teams are a special kind of beast in the application world. Rules that seem unreasonable for other projects become more pertinent due to the input streams to the project and the likelihood that those contributing haven't read the project's guidelines.

This can also occur when two large projects are merged together.  If both projects had similarly named classes, then you'll see collisions when you start referencing from one project to the other.  And the projects may be too large to refactor or management won't approve the expense to fund the time spent on refactoring.

Alternatives:

While you didn't ask, it's worth pointing out that this is not a great solution to the problem.   It's not a good idea to be creating classes that will collide without their namespace declarations.

List<T>, in particular, ought to be treated as a reserved word and not used as the name for your classes.

Likewise, individual namespaces within the project should strive to have unique class names.  Having to try and recall which namespace's Foo() you're working with is mental overhead that is best avoided.  Said another way: having MyCorp.Bar.Foo() and MyCorp.Baz.Foo() is going to trip your developers up and best avoided.

If nothing else, you can use partial namespaces in order to resolve the ambiguity.  For example, if you absolutely can't rename either Foo() class you could use their partial namespaces:

```<code>Bar.Foo()
Baz.Foo()
</code>```

Specific reasons for your current project:

You updated your question with the specific reasons you were given for your current project following that standard.  Let's take a look at them and really digress down the bunny trail.

It's cumbersome to hover the mouse over the name to get the fully qualified type. It's better to always have the fully qualified type visible all the time.

"Cumbersome?" Um, no.  Annoying perhaps.  Moving a few ounces of plastic in order to shift an on-screen pointer is not cumbersome.  But I digress.

This line of reasoning seems more like a cover-up than anything else.  Offhand, I'd guess that the classes within the application are weakly named and you have to rely upon the namespace in order to glean the appropriate amount of semantic information surrounding the class name.

This is not a valid justification for fully qualified class names, perhaps it's a valid justification for using partially qualified class names.

Emailed code snippets don't have the fully qualified name, and therefore can be difficult to understand.

This (continued?) line of reasoning reinforces my suspicion that classes are currently poorly named.  Again, having poor class names is not a good justification for requiring everything to use a fully qualified class name.  If the class name is difficult to understand, there's a lot more wrong than what fully qualified class names can fix.

When viewing or editing the code outside of Visual Studio (Notepad++, for example), it's impossible to get the fully qualified type name.

Of all the reasons, this one nearly made me spit out my drink.  But again, I digress.

I'm left wondering why is the team frequently editing or viewing code outside of Visual Studio?  And now we're looking at a justification that's pretty well orthogonal to what namespaces are meant to provide.  This is a tooling backed argument whereas namespaces are there to provide organizational structure to the code.

It sounds like the project you own suffers from poor naming conventions along with developers who aren't taking advantage of what the tooling can provide for them.  And rather than resolve those actual issues, they attempt to slap a band-aid over one of the symptoms and are requiring fully qualified class names.  I think it's safe to categorize this as a misguided approach.

Given that there are poorly named classes, and assuming you can't refactor, the correct answer is to use the Visual Studio IDE to its full advantage.  Possibly consider adding in a plugin like the VS PowerTools package.  Then, when I'm looking at AtrociouslyNamedClass() I can click on the class name, press F12 and be taken directly to the definition of the class in order to better understand what it's trying to do.  Likewise, I can press Shift-F12 to find all the spots in the code currently suffering from having to use AtrociouslyNamedClass().

Regarding the outside tooling concerns - the best thing to do is to just stop it.  Don't email snippets back and forth if they aren't immediately clear what they refer to.  Don't use other tools outside of Visual Studio as those tools don't have the intelligence surrounding the code that your team needs.  Notepad++ is an awesome tool, but it's not cut out for this task.

So I agree with your assessment regarding the three specific justifications you were presented with.  That said, what I think you were told was "We have underlying issues on this project that can't / won't address and this is how we 'fixed' them."  And that obviously speaks to deeper issues within the team that may serve as red flags for you.

Body:
The broader question:

Have you ever heard of such a standard being imposed? If so, what was the reason behind it?

Yes, I've heard of this, and using fully qualified object names prevents name collisions.  Though rare, when they happen, they can be exceptionally thorny to figure out.

An Example:
That type of a scenario is probably better explained with an example.

Let's say we have two Lists<T> belonging to two separate projects.

System.Collections.Generic.List<T>
MyCorp.CustomCollections.Optimized.List<T>

When we use the fully qualified object name, it's clear as to which List<T> is being used.  That clarity obviously comes at the cost of verbosity.

And you might be arguing, "Wait! No one would ever use two lists like that!"  Which is where I'll point out the maintenance scenario.

You've written module Foo for your corporation which uses the corporation approved, optimized List<T>.

using MyCorp.CustomCollections.Optimized;

public class Foo {
    List<object> myList = ...;
}

Later on, a new developer decides to extend the work you've been doing.  Not being aware of the company's standards, they update the using block:

using MyCorp.CustomCollections.Optimized;
using System.Collections.Generic;

And you can see how things go bad in a hurry.

It should be trivial to point out that you could have two proprietary classes of the same name but in different namespaces within the same project.  So it's not just a concern about colliding with .NET Framework supplied classes.

MyCorp.WeightsAndLengths.Measurement();
MyCorp.TimeAndSpace.Measurement();

The reality:

Now, is this likely to occur in most projects?  No, not really.  But when you're working on a large project with a lot of inputs, you do your best to minimize the chances of things exploding on you.

Large projects with multiple contributing teams are a special kind of beast in the application world. Rules that seem unreasonable for other projects become more pertinent due to the input streams to the project and the likelihood that those contributing haven't read the project's guidelines.

This can also occur when two large projects are merged together.  If both projects had similarly named classes, then you'll see collisions when you start referencing from one project to the other.  And the projects may be too large to refactor or management won't approve the expense to fund the time spent on refactoring.

Alternatives:

While you didn't ask, it's worth pointing out that this is not a great solution to the problem.   It's not a good idea to be creating classes that will collide without their namespace declarations.

List<T>, in particular, ought to be treated as a reserved word and not used as the name for your classes.

Likewise, individual namespaces within the project should strive to have unique class names.  Having to try and recall which namespace's Foo() you're working with is mental overhead that is best avoided.  Said another way: having MyCorp.Bar.Foo() and MyCorp.Baz.Foo() is going to trip your developers up and best avoided.

If nothing else, you can use partial namespaces in order to resolve the ambiguity.  For example, if you absolutely can't rename either Foo() class you could use their partial namespaces:

Bar.Foo()
Baz.Foo()

Specific reasons for your current project:

You updated your question with the specific reasons you were given for your current project following that standard.  Let's take a look at them and really digress down the bunny trail.

It's cumbersome to hover the mouse over the name to get the fully qualified type. It's better to always have the fully qualified type visible all the time.

"Cumbersome?" Um, no.  Annoying perhaps.  Moving a few ounces of plastic in order to shift an on-screen pointer is not cumbersome.  But I digress.

This line of reasoning seems more like a cover-up than anything else.  Offhand, I'd guess that the classes within the application are weakly named and you have to rely upon the namespace in order to glean the appropriate amount of semantic information surrounding the class name.

This is not a valid justification for fully qualified class names, perhaps it's a valid justification for using partially qualified class names.

Emailed code snippets don't have the fully qualified name, and therefore can be difficult to understand.

This (continued?) line of reasoning reinforces my suspicion that classes are currently poorly named.  Again, having poor class names is not a good justification for requiring everything to use a fully qualified class name.  If the class name is difficult to understand, there's a lot more wrong than what fully qualified class names can fix.

When viewing or editing the code outside of Visual Studio (Notepad++, for example), it's impossible to get the fully qualified type name.

Of all the reasons, this one nearly made me spit out my drink.  But again, I digress.

I'm left wondering why is the team frequently editing or viewing code outside of Visual Studio?  And now we're looking at a justification that's pretty well orthogonal to what namespaces are meant to provide.  This is a tooling backed argument whereas namespaces are there to provide organizational structure to the code.

It sounds like the project you own suffers from poor naming conventions along with developers who aren't taking advantage of what the tooling can provide for them.  And rather than resolve those actual issues, they attempt to slap a band-aid over one of the symptoms and are requiring fully qualified class names.  I think it's safe to categorize this as a misguided approach.

Given that there are poorly named classes, and assuming you can't refactor, the correct answer is to use the Visual Studio IDE to its full advantage.  Possibly consider adding in a plugin like the VS PowerTools package.  Then, when I'm looking at AtrociouslyNamedClass() I can click on the class name, press F12 and be taken directly to the definition of the class in order to better understand what it's trying to do.  Likewise, I can press Shift-F12 to find all the spots in the code currently suffering from having to use AtrociouslyNamedClass().

Regarding the outside tooling concerns - the best thing to do is to just stop it.  Don't email snippets back and forth if they aren't immediately clear what they refer to.  Don't use other tools outside of Visual Studio as those tools don't have the intelligence surrounding the code that your team needs.  Notepad++ is an awesome tool, but it's not cut out for this task.

So I agree with your assessment regarding the three specific justifications you were presented with.  That said, what I think you were told was "We have underlying issues on this project that can't / won't address and this is how we 'fixed' them."  And that obviously speaks to deeper issues within the team that may serve as red flags for you.

ContentLicense: CC BY-SA 4.0


答:
I did work at one company where they had many classes with the same name, but in different class libraries.

For example,

Domain.Customer

Legacy.Customer

ServiceX.Customer

ViewModel.Customer

Database.Customer

Bad design, you might say, but you know how these things develop organically, and what's the alternative - rename all the classes to include the namespace? Major refactoring of everything?

In any case, there were several places where projects which referenced all these different libraries needed to use multiple versions of the class.

With the using directly at the top, this was a major pain in the arse, ReSharper would do odd things to try and make it work, rewriting the using directives on the fly, you would get Customer-can't-be-cast-as-Customer-style errors and not know which type was the correct one.

So, having at least the partial namespace,

```<code>var cust = new Domain.Customer
</code>```

or

```<code>public void Purchase(ViewModel.Customer customer)
</code>```

greatly improved the readability of the code and made it explicit which object you wanted.

It wasn't a coding standard, it wasn't the full namespace, and it wasn't applied to all classes as standard.

Title: Why would you not use the 'using' directive in C#?

Body:
The existing coding standards on a large C# project includes a rule that all type names be fully qualified, forbidding employment of the 'using' directive. So, rather than the familiar:

```<code>using System.Collections.Generic;

.... other stuff ....

List<string> myList = new List<string>();
</code>```

(It's probably no surprise that var also is prohibited.)

I end up with:

```<code>System.Collections.Generic.List<string> myList = new System.Collections.Generic.List<string>();
</code>```

That's a 134% increase in typing, with none of that increase providing useful information. In my view, 100% of the increase is noise (clutter) that actually impedes understanding.

In 30+ years of programming, I've seen such a standard proposed once or twice, but never implemented. The rationale behind it escapes me. The person imposing the standard is not stupid, and I don't think he's malicious. Which leaves misguided as the only other alternative unless I'm missing something.

Have you ever heard of such a standard being imposed? If so, what was the reason behind it? Can you think of arguments other than "it's stupid," or "everybody else employs using" that might convince this person to remove this prohibition?

Reasoning

The reasons for this prohibition were:

It's cumbersome to hover the mouse over the name to get the fully qualified type. It's better to always have the fully qualified type visible all the time.

Emailed code snippets don't have the fully qualified name, and therefore can be difficult to understand.

When viewing or editing the code outside of Visual Studio (Notepad++, for example), it's impossible to get the fully qualified type name.

My contention is that all three cases are rare, and that making everybody pay the price of cluttered and less-understandable code just to accommodate a few rare cases is misguided.

Potential namespace conflict issues, which I expected to be the primary concern, weren't even mentioned. That's especially surprising because we have a namespace, MyCompany.MyProject.Core, which is an especially bad idea. I learned long ago that naming anything System or Core in C# is a quick path to insanity.

As others have pointed out, namespace conflicts are easily handled by refactoring, namespace aliases, or partial qualification.

Body:
I did work at one company where they had many classes with the same name, but in different class libraries.

For example,

Domain.Customer

Legacy.Customer

ServiceX.Customer

ViewModel.Customer

Database.Customer

Bad design, you might say, but you know how these things develop organically, and what's the alternative - rename all the classes to include the namespace? Major refactoring of everything?

In any case, there were several places where projects which referenced all these different libraries needed to use multiple versions of the class.

With the using directly at the top, this was a major pain in the arse, ReSharper would do odd things to try and make it work, rewriting the using directives on the fly, you would get Customer-can't-be-cast-as-Customer-style errors and not know which type was the correct one.

So, having at least the partial namespace,

var cust = new Domain.Customer

or

public void Purchase(ViewModel.Customer customer)

greatly improved the readability of the code and made it explicit which object you wanted.

It wasn't a coding standard, it wasn't the full namespace, and it wasn't applied to all classes as standard.


答:
There is no good to be too verbose or too short: one should find a golden middle in being detailed enough in order to prevent subtle bugs, while avoiding to write too much code.

In C#, an example of that are the names of arguments. I encountered several times a problem where I spent hours looking for a solution, while a more verbose style of writing could prevent the bug in the first place. The problem consists of an error in the order of the arguments. For instance, does it look right to you?

```<code>if (...) throw new ArgumentNullException("name", "The name should be specified.");
if (...) throw new ArgumentException("name", "The name contains forbidden characters.");
</code>```

At the first sight, it looks perfectly fine, but there is a bug. The signatures of the exceptions' constructors are:

```<code>public ArgumentException(string message, string paramName)
public ArgumentNullException(string paramName, string message)
</code>```

Noticed the order of arguments?

By adopting a more verbose style where the name of an argument is specified every time the method accepts two or more arguments of the same type, we prevent the error from happening again, and so:

```<code>if (...) throw new ArgumentNullException(paramName: "name", message: "The name should be specified.");
if (...) throw new ArgumentException(paramName: "name", message: "The name contains forbidden characters.");
</code>```

is obviously longer to write, but results in less time wasted debugging.

Pushed to extremes, one could force to use named arguments everywhere, including in methods such as doSomething(int, string) where there is no way to mix the order of the parameters. This will probably harm the project in long term, resulting in much more code without the benefit of preventing the bug I described above.

In your case, the motivation behind the “No using” rule is that it should make it more difficult to use the wrong type, such as MyCompany.Something.List<T> vs. System.Collections.Generic.List<T>.

Personally, I would avoid such rule because, IMHO, the cost of difficult to read code is much above the benefit of a slightly reduced risk of misusing the wrong type, but at least, there is a valid reason for this rule.

Body:
There is no good to be too verbose or too short: one should find a golden middle in being detailed enough in order to prevent subtle bugs, while avoiding to write too much code.

In C#, an example of that are the names of arguments. I encountered several times a problem where I spent hours looking for a solution, while a more verbose style of writing could prevent the bug in the first place. The problem consists of an error in the order of the arguments. For instance, does it look right to you?

if (...) throw new ArgumentNullException("name", "The name should be specified.");
if (...) throw new ArgumentException("name", "The name contains forbidden characters.");

At the first sight, it looks perfectly fine, but there is a bug. The signatures of the exceptions' constructors are:

public ArgumentException(string message, string paramName)
public ArgumentNullException(string paramName, string message)

Noticed the order of arguments?

By adopting a more verbose style where the name of an argument is specified every time the method accepts two or more arguments of the same type, we prevent the error from happening again, and so:

if (...) throw new ArgumentNullException(paramName: "name", message: "The name should be specified.");
if (...) throw new ArgumentException(paramName: "name", message: "The name contains forbidden characters.");

is obviously longer to write, but results in less time wasted debugging.

Pushed to extremes, one could force to use named arguments everywhere, including in methods such as doSomething(int, string) where there is no way to mix the order of the parameters. This will probably harm the project in long term, resulting in much more code without the benefit of preventing the bug I described above.

In your case, the motivation behind the “No using” rule is that it should make it more difficult to use the wrong type, such as MyCompany.Something.List<T> vs. System.Collections.Generic.List<T>.

Personally, I would avoid such rule because, IMHO, the cost of difficult to read code is much above the benefit of a slightly reduced risk of misusing the wrong type, but at least, there is a valid reason for this rule.


问:
Does context (like as an argument in a function) allow for numbers in code that aren't magic numbers?
I've been reading many of the articles and such about magic numbers, i.e.

wikipedia article

programmers.stackexchange.com article

It seemed like no one has considered context as a means of making it acceptable to use a number and not have it considered magic.

For example

```<code>connection.setLoginTimeoutSeconds(30);
</code>```

Vs

```<code>final int LOGIN_TIMEOUT_30_SECONDS = 30;
connection.setLoginTimeoutSeconds(LOGIN_TIMEOUT_30_SECONDS);
</code>```

or even

```<code>final int LOGIN_TIMEOUT = 30;
connection.setLoginTimeoutSeconds(LOGIN_TIMEOUT);
</code>```

The function name and value has all of the information as the variable name and value:

```<code>setLoginTimeoutSeconds(30);
LOGIN_TIMEOUT_SECONDS = 30;
</code>```

In the case where a variable for the login time out is not needed anywhere else in the code it seems like the first example is more readable and even more maintainable than the latter two and that the number 30 is not magic because of where it resides. Does anyone agree or disagree?

I am not asking about well known constants here like in are-all-magic-numbers-created-the-same. Any constant value can will do. Nor am I asking for my example to be found as flawed because someone could make a problem from it. What I am really asking is form anyone's opinion on if magic number rules need not apply.

答:
It isn't just that the number itself is bad, but that misunderstandings can be introduced when the purpose isn't made clear and there a number of such values. Building on your example:

```<code>connection.setLoginTimeout(30);
connection.setSessionTimeout(30);
</code>```

Unless you're intimately familiar with the code, it isn't clear whether both values should be the same or whether they can be different. So if they are supposed to be the same then:

```<code>const TIMEOUT = 30;

connection.setLoginTimeout(TIMEOUT);
connection.setSessionTimeout(TIMEOUT);
</code>```

Or if they could be different values then:

```<code>const LOG_TIMEOUT = 30;
const SESS_TIMEOUT = 30;

connection.setLoginTimeout(LOG_TIMEOUT);
connection.setSessionTimeout(SESS_TIMEOUT);
</code>```

You may argue that this doesn't apply for one setting, but should another be added later with the same initial value, the misunderstanding I've outlined above could easily occur.

Body:
It isn't just that the number itself is bad, but that misunderstandings can be introduced when the purpose isn't made clear and there a number of such values. Building on your example:

connection.setLoginTimeout(30);
connection.setSessionTimeout(30);

Unless you're intimately familiar with the code, it isn't clear whether both values should be the same or whether they can be different. So if they are supposed to be the same then:

const TIMEOUT = 30;

connection.setLoginTimeout(TIMEOUT);
connection.setSessionTimeout(TIMEOUT);

Or if they could be different values then:

const LOG_TIMEOUT = 30;
const SESS_TIMEOUT = 30;

connection.setLoginTimeout(LOG_TIMEOUT);
connection.setSessionTimeout(SESS_TIMEOUT);

You may argue that this doesn't apply for one setting, but should another be added later with the same initial value, the misunderstanding I've outlined above could easily occur.


答:
The first major problem with

```<code>connection.setLoginTimeout(30);
</code>```

Is that you're assuming the junior developer you just hired who's looking at this 6 months from now will know that "30" is seconds & not milliseconds.

The second major problem (as @KilianFoth pointed out in a comment) is that again, 6 months from now, that junior developer might not be able to find this parameter very easily if at all.

An important point not brought up in your examples or the examples in the other question is that there is absolutely no reason to declare the constant right next to where it's used.

Instead, stick all of those "tuning parameters" in a common well documented place - perhaps a Constants.h file or equivalent.

Title: Does context (like as an argument in a function) allow for numbers in code that aren't magic numbers?

Body:
I've been reading many of the articles and such about magic numbers, i.e.

wikipedia article

programmers.stackexchange.com article

It seemed like no one has considered context as a means of making it acceptable to use a number and not have it considered magic.

For example

```<code>connection.setLoginTimeoutSeconds(30);
</code>```

Vs

```<code>final int LOGIN_TIMEOUT_30_SECONDS = 30;
connection.setLoginTimeoutSeconds(LOGIN_TIMEOUT_30_SECONDS);
</code>```

or even

```<code>final int LOGIN_TIMEOUT = 30;
connection.setLoginTimeoutSeconds(LOGIN_TIMEOUT);
</code>```

The function name and value has all of the information as the variable name and value:

```<code>setLoginTimeoutSeconds(30);
LOGIN_TIMEOUT_SECONDS = 30;
</code>```

In the case where a variable for the login time out is not needed anywhere else in the code it seems like the first example is more readable and even more maintainable than the latter two and that the number 30 is not magic because of where it resides. Does anyone agree or disagree?

I am not asking about well known constants here like in are-all-magic-numbers-created-the-same. Any constant value can will do. Nor am I asking for my example to be found as flawed because someone could make a problem from it. What I am really asking is form anyone's opinion on if magic number rules need not apply.

Body:
The first major problem with

connection.setLoginTimeout(30);

Is that you're assuming the junior developer you just hired who's looking at this 6 months from now will know that "30" is seconds & not milliseconds.

The second major problem (as @KilianFoth pointed out in a comment) is that again, 6 months from now, that junior developer might not be able to find this parameter very easily if at all.

An important point not brought up in your examples or the examples in the other question is that there is absolutely no reason to declare the constant right next to where it's used.

Instead, stick all of those "tuning parameters" in a common well documented place - perhaps a Constants.h file or equivalent.


答:
The less you say, the less you have to keep saying.

The less you ask, the less you have to be told.

If your code only exposes IEnumerable<T>, which supports only GetEnumrator() it can be replaced by any other code that can support IEnumerable<T>. This adds flexibility.

If your code only uses IEnumerable<T> it can be supported by any code that implements IEnumerable<T>. Again, there is extra flexibility.

All of linq-to-objects for example, depends only on IEnumerable<T>. While it fast-paths some particular implementations of IEnumerable<T> it does this in a test-and-use way that can always fallback to just using GetEnumerator() and the IEnumerator<T> implementation that returns. This gives it much more flexibility than if it was built on top of arrays or lists.

Title: Iterator pattern - why is it important to not expose the internal representation?

Body:
I am reading C# Design Pattern Essentials. I'm currently reading about the iterator pattern.

I fully understand how to implement, but I don't understand the importance or see a use case. In the book an example is given where someone needs to get a list of objects. They could have done this by exposing a public property, such as IList<T> or an Array.

The book writes

The problem with this is that the internal representation in both of these classes has been exposed to outside projects.

What is the internal representation? The fact it's an array or IList<T>? I really don't understand why this is a bad thing for the consumer (the programmer calling this) to know...

The book then says this pattern works by exposing its GetEnumerator function, so we can call GetEnumerator() and expose the 'list' this way.

I assume this patterns has a place (like all) in certain situations, but I fail to see where and when.


答:
There is no such thing, after all, before annotations were available, we have used XML files for everything.

It is just nicer to have everything related to class or its field in one place/file. I guess method level annotations are hard to replace since the alternatives require providing class name, method name and sometimes list of parameters, if method is overloaded.

There isn't any theoretical distinction beyond the basic "metadata is data about data". We might as well say that access modifiers (public/private) are metadata and replace them with annotations (Project Lombok does something related)

Title: What are the justifications for annotations in a programming language?

Body:
After spending a great deal of time writing C# and looking at Java, it seems to me that annotations are just an ugly code smell that introduce another conceptual layer that could easily be replaced by existing language features, whether they be keywords (as in the case of C#'s override keyword versus Java's @override annotation) or inheritance (why not just have a ISerializable interface or base class instead of a [Serializable] attribute?) However, this conclusion could just as easily be due my relative inexperience as a professional programmer.

My question is compound:

What do annotations bring to the table that cannot be accomplished in other ways, without complicating the grammar of a language?

Are there things that can be implemented without annotations, but which would be much more difficult to implement without them?

More generally, where (if anywhere) is the demarcation line between data and metadata in a programming language?

My question is different from What problems are Java annotations well suited to?. For starters, this question is not Java-specific. I'm wanting to know, in general, whether annotations are indispensable or merely useful. I am also curious as to the theoretical distinction between data and metadata, and how useful that distinction really is.


问:
Why is there not a basic SortedList<T>?
As far as I know, there is no way to get a List<T> with the capacity to sort itself. If I add a element, I want the data-structure to insert it in the right position (based on the associated IComparer<T>). I am looking for something with the same logic than SortedSet<T>.

I am aware of System.Collections.Generic.SortedList<TKey, TValue> but it is more a kind of Dictionary.

I don't really need one (it is not very difficult to implement). I just wonder whether a such data-structure exists and if not, why?

source:

List<T> OrderBy Alphabetical Order

Is there a list that is sorted automatically in .NET?

SortedList Class

SortedList<TKey, TValue> Class

SortedSet<T> Class

答:
It would break the IList interface.

You retrieve elements out of a list by index, if the indices for the elements keep changing this is useless, also Insert would be useless.

Item[Int32] - Gets or sets the element at the specified index.

Insert(Int32, T) - Inserts an item to the IList<T> at the specified index.

So the reason there is no SortedList<T> implementation is because other ADTs can handle the functionality in a more rational and efficient manner.

Title: Why is there not a basic SortedList<T>?


答:
Namespaces gives code a hierarchical structure, allowing for shorter names.

```<code>   MyCompany.Headquarters.Team.Leader
   MyCompany.Warehouse.Team.Leader
</code>```

If you allow the "using" keyword, there is a chain of events...

Everyone is really using one global namespace

(because they include every namespace they could possibly want)

People start to get name clashes, or

worry about getting name clashes.

So to avoid the risk, everyone starts using really long names:

```<code>   HeadquartersTeamLeader
   WarehouseTeamLeader
</code>```

The situation escalates...

Someone else may already have chosen a name, so you use a longer one.

Names get longer and longer.

Lengths can exceed 60 characters, with no maximum - it gets ridiculous.

I have seen this happen, so can sympathize with companies which ban "using".

Body:
Namespaces gives code a hierarchical structure, allowing for shorter names.

   MyCompany.Headquarters.Team.Leader
   MyCompany.Warehouse.Team.Leader

If you allow the "using" keyword, there is a chain of events...

Everyone is really using one global namespace

(because they include every namespace they could possibly want)

People start to get name clashes, or

worry about getting name clashes.

So to avoid the risk, everyone starts using really long names:

   HeadquartersTeamLeader
   WarehouseTeamLeader

The situation escalates...

Someone else may already have chosen a name, so you use a longer one.

Names get longer and longer.

Lengths can exceed 60 characters, with no maximum - it gets ridiculous.

I have seen this happen, so can sympathize with companies which ban "using".


问:
How far should I abstract my pseudo-database?
I'm building a [Process-Tracker] thing In Excel. I would use Access but I can't guarantee that the End-Users will all have it.

So there will be a list of open cases, with a history of the previous steps in the process, the next step to be completed, key information etc. In a nice tabulated layout and sorted by next due date.

E.G.

[UNID] | Client A | Person B |,,,,| Step N | [task] | [Due Date] | [Other Info] |,,,,| Step 1 |..| Step 2 |..

I've spent a week trying to build one and realised that it needed way more abstraction.

I've come up with a new structure and I wanted to know, is it a good structural model or do I need to abstract the data into more layers?

I would really like to avoid starting from scratch again.

Design:
The basic units will be CaseItem objects and ProcessStep objects.

CaseItem objects will have as properties:

A unique ID

An ordered list of KeyInformation

A list of the IDs of the associated ProcessSteps

ProcessStep objects will have as properties:

A bunch of general properties (description, due date, is completed, date completed, completed by etc.)

An index for their stage in the process.

A unique ID consisting of their index concatenated with the CaseItem ID E.G. Case ID = #00000001, Step 12 ID = #00000001,#12

There will be a [Hidden] Master Sheet storing all item data.

答:
Let me speak from personal experience: this is a great sounding idea which you will regret doing.

Excel is just not a good database tool. Just some of the reasons:

Nearly impossible to have appropriate systems for permissions (which users can view/modify specific data. At least use xlVeryHidden if you go this route for your main "data sheet"). You will have to create a lot of custom dialog boxes or deal with really complicated/frustrating locking on sheets. This is a nightmare.

It's not designed to be a database. It's spreadsheets. Doing queries/etc on it can be done (you can write SQL vs spreadsheets if you <s>hate your life</s> want) but why? There are so many better tools, specifically designed for this purpose.

Shared workbooks are a disaster waiting to happen when many people update them frequently

It doesn't model table logic with queries/views easily

Each data view will have to be custom created (it does not have the easy table/query logic that Access does, for example. You can create forms/views much more easily with a TON more expanded logic than in Excel)

These reasons are made even worse in that many tools (such as Access) exist that are specifically designed to provide easy functionality to do all of the things you want to do with a database.

this is as much about me gaining experience in designing/implementing software as it is about the end result

You are asking about gaining insight into writing software. If you are a carpenter trying to learn how to put nails in a board, you wouldn't use a saw - you'd use a hammer, nail gun, etc.

Trying to make this application in Excel is the equivalent of using a saw to learn how to nail. It might work, sure. But you won't really learn how to put nails into a board the right way.

I've come up with a new structure and I wanted to know, is it a good structural model or do I need to abstract the data into more layers?

There are two answers here.

First, if you want to use Excel, you are going to want to actually minimize how well designed your database schema is. When designing a database you want it normalized as much as possible. However with Excel, you don't actually want to do this, because it creates a nightmare for actual implementation. You want to use range lookups and then have a single sheet for all the lookups. In a database these would be tables with foreign keys.

Second, I would strongly suggest looking into Microsoft Access for what you are doing. It will make this design process go from being insanely frustrating/complicated to very simple. For that route:

A unique ID consisting of their index concatenated with the CaseItem ID E.G. Case ID = #00000001, Step 12 ID = #00000001,#12

This is the sort of thing that Excel is going to make you do. Because you are thinking in a spreadsheet the concept of a unique key hardly makes sense to you (since you will "see" the key).

If you instead use a real database program you can make it:

```<code>CaseItem table
 - Unique ID
 - Misc information
 - CurrentProcessStep

ProcessStep table (for definition of process steps. these items can be reused)
 - Unique ID
 - Misc information (description / etc)

CaseProcessSteps table (matches processsteps to caseitems
 - CaseItemID
 - ProcessStepID
 - Date related items
</code>```

You could also have a separate table for date information if you'd like.

This is more like a database. Not a spreadsheet. Representing the above in a spreadsheet gets really hard conceptually because if you do it like this, you need a query to represent the data in "human readable" format - since it's all using IDs (like a database should) but Excel fails for that. You can do a SQL query or a bunch of index/match/vlookups, but this is a complete hacky thing.

This sort of setup is trivial to implement in Access. It's also a million times easier to make appropriate views to enter/edit this information in Access than Excel..

Body:
Let me speak from personal experience: this is a great sounding idea which you will regret doing.

Excel is just not a good database tool. Just some of the reasons:

Nearly impossible to have appropriate systems for permissions (which users can view/modify specific data. At least use xlVeryHidden if you go this route for your main "data sheet"). You will have to create a lot of custom dialog boxes or deal with really complicated/frustrating locking on sheets. This is a nightmare.

It's not designed to be a database. It's spreadsheets. Doing queries/etc on it can be done (you can write SQL vs spreadsheets if you <s>hate your life</s> want) but why? There are so many better tools, specifically designed for this purpose.

Shared workbooks are a disaster waiting to happen when many people update them frequently

It doesn't model table logic with queries/views easily

Each data view will have to be custom created (it does not have the easy table/query logic that Access does, for example. You can create forms/views much more easily with a TON more expanded logic than in Excel)

These reasons are made even worse in that many tools (such as Access) exist that are specifically designed to provide easy functionality to do all of the things you want to do with a database.

this is as much about me gaining experience in designing/implementing software as it is about the end result

You are asking about gaining insight into writing software. If you are a carpenter trying to learn how to put nails in a board, you wouldn't use a saw - you'd use a hammer, nail gun, etc.

Trying to make this application in Excel is the equivalent of using a saw to learn how to nail. It might work, sure. But you won't really learn how to put nails into a board the right way.

I've come up with a new structure and I wanted to know, is it a good structural model or do I need to abstract the data into more layers?

There are two answers here.

First, if you want to use Excel, you are going to want to actually minimize how well designed your database schema is. When designing a database you want it normalized as much as possible. However with Excel, you don't actually want to do this, because it creates a nightmare for actual implementation. You want to use range lookups and then have a single sheet for all the lookups. In a database these would be tables with foreign keys.

Second, I would strongly suggest looking into Microsoft Access for what you are doing. It will make this design process go from being insanely frustrating/complicated to very simple. For that route:

A unique ID consisting of their index concatenated with the CaseItem ID E.G. Case ID = #00000001, Step 12 ID = #00000001,#12

This is the sort of thing that Excel is going to make you do. Because you are thinking in a spreadsheet the concept of a unique key hardly makes sense to you (since you will "see" the key).

If you instead use a real database program you can make it:

CaseItem table
 - Unique ID
 - Misc information
 - CurrentProcessStep

ProcessStep table (for definition of process steps. these items can be reused)
 - Unique ID
 - Misc information (description / etc)

CaseProcessSteps table (matches processsteps to caseitems
 - CaseItemID
 - ProcessStepID
 - Date related items

You could also have a separate table for date information if you'd like.

This is more like a database. Not a spreadsheet. Representing the above in a spreadsheet gets really hard conceptually because if you do it like this, you need a query to represent the data in "human readable" format - since it's all using IDs (like a database should) but Excel fails for that. You can do a SQL query or a bunch of index/match/vlookups, but this is a complete hacky thing.

This sort of setup is trivial to implement in Access. It's also a million times easier to make appropriate views to enter/edit this information in Access than Excel..


问:
Should public API classes have helper methods that provide anticipated functionality?
For the purposes of providing a concrete example for my question, let's say I'm building an API that provides access to an email system and contains a set of public classes e.g. Mailbox, MailboxFolder, Message, MessageAttachment, and so on.

Is it a good idea to try to anticipate how clients may use the API and provide "helper" methods for common operations?

For example, imagine my Message class has a Save(string toFilePath) method.  Maybe it would be helpful to provide another method in Message that builds a "safe file name" from the subject of the message, i.e. a file name that is some reasonable portion of the subject (since the length of an email subject can far exceed the maximum length of a file path) where all characters that are not valid for use in a file name have been replaced with a usable character.

The reason for this would be that I anticipate clients may often want to save an email with a name that resembles the subject.

答:
"Safe file name builder" is not something I'd expect (or even want) to see in an email-related library. Building a "safe" string from arbitrary message subject can be a rather complicated task if you think about encoding, allowed characters for paths in different OSs, etc., so it's better be handled by specialized API/library.

General principles are:

Assume less, make your API as agnostic to it's "environment" as possible. Imagine that your API can be used in a browser, which can't even save a file, so it wouldn't even need the Save method. It would be better to provide some form of serialization instead of Save method and let users decide how to handle serialized massages: print, save to files, transfer over a network, etc.

Don't clutter your API with stuff your users can only possibly need - see scope creep and YAGNI

Respect the single responsibility principle. Choosing a name for a file is not something that email message should do or even be aware about.

As for helper methods which don't violate the principles mentioned above: if you choose to put such methods to appropriate classes, it's fine.


答:
setLoginTimeoutSeconds(30) tells you that 30 is (now) the timeout.

It provides no explanation about why we set the timeout to 30.

Is it because the server timeout is 20 and we want an additional 10 seconds for network delays? Is it the same with the logout timeout that's defined in the next line? Is it something that was decided by usability testing and sits in a configuration file? Or maybe it has no meaning and was just picked as a default randomly (something that is still good to know)?

Yes, it could be that there is nothing more to say about this number in which case naming it TIMEOUT is equally meaningless with calling it THIRTY (and TIMEOUT_IN_SECONDS isn't particularly helpful either; this should be ideally deduced by the context imho).
But in that case, why do we need to set it at all? It might make more sense to have the connection work without having to set it to 30.

In other words, if there's nothing outside the context to be said, perhaps there shouldn't be a number at all.


答:
```<code>final int LOGIN_TIMEOUT_SECONDS = 30;
// other code
connection.setLoginTimeoutSeconds(LOGIN_TIMEOUT_SECONDS);
</code>```

This seems to solve all the problems/dilemma you are wondering about.

It also helps with some quick verification, since you see you are passing correct units into the method (if it was setLoginTimeoutMS(LOGIN_TIMEOUT_SECONDS) you'd clearly see an error.

I was going to write a comment but want instead to address:

It seemed like no one considered has context as a means of making it acceptable to use a number and not have it considered magic.

Context changes. You don't want to rely on something which may change.

Let's look at your "good" example:

```<code>final int LOGIN_TIMEOUT = 30;
connection.setLoginTimeoutSeconds(LOGIN_TIMEOUT);
</code>```

The problem with magic numbers is not knowing what they mean. In this example your naming doesn't really help and makes it worse. Is 30 in seconds? Was there a unit conversion problem?

I know that your connection takes a value in seconds, but the problem is that your magic constant doesn't help make this clear. It can be really easily read "call the login timeout function, which takes an argument of seconds, and pass in a value of arbitrary time which hopefully is seconds."

If you declare this immediately before the login call it can be clear. But what happens when the code is refactored to have a common login timeout? Or when other code gets added between the definition/usage?

And last, don't depend on the context to add clarity when you can make very simple naming changes to add the same clarity. Context changes. If someone moves that declaration to a header file to support common usage, your context is gone. Boom. And just like that you have made your system less maintainable.

Also note there are times when a constant may be beneficial (single usages, etc). But the question you are asking still applies - you just may know more matter-of-fact that the context won't change.

Body:
final int LOGIN_TIMEOUT_SECONDS = 30;
// other code
connection.setLoginTimeoutSeconds(LOGIN_TIMEOUT_SECONDS);

This seems to solve all the problems/dilemma you are wondering about.

It also helps with some quick verification, since you see you are passing correct units into the method (if it was setLoginTimeoutMS(LOGIN_TIMEOUT_SECONDS) you'd clearly see an error.

I was going to write a comment but want instead to address:

It seemed like no one considered has context as a means of making it acceptable to use a number and not have it considered magic.

Context changes. You don't want to rely on something which may change.

Let's look at your "good" example:

final int LOGIN_TIMEOUT = 30;
connection.setLoginTimeoutSeconds(LOGIN_TIMEOUT);

The problem with magic numbers is not knowing what they mean. In this example your naming doesn't really help and makes it worse. Is 30 in seconds? Was there a unit conversion problem?

I know that your connection takes a value in seconds, but the problem is that your magic constant doesn't help make this clear. It can be really easily read "call the login timeout function, which takes an argument of seconds, and pass in a value of arbitrary time which hopefully is seconds."

If you declare this immediately before the login call it can be clear. But what happens when the code is refactored to have a common login timeout? Or when other code gets added between the definition/usage?

And last, don't depend on the context to add clarity when you can make very simple naming changes to add the same clarity. Context changes. If someone moves that declaration to a header file to support common usage, your context is gone. Boom. And just like that you have made your system less maintainable.

Also note there are times when a constant may be beneficial (single usages, etc). But the question you are asking still applies - you just may know more matter-of-fact that the context won't change.


问:
Roles and permissions: a good approach in defining permissions?
My application has users and administrators. The administrators split into two: super-admin and limited-admin. The super gets all permissions while the limited can be configured to inherit just the admin permissions that are specifically needed.

I am thinking to define my permissions the following way. Any user permission has an administrator permission:

User:

 - post_create

 - post_update

 - post_delete

Administrator:

 - administrator_post_create

 - administrator_post_update

 - administrator_post_delete

Is this a good approach? Should I rather assign to an Admin all the users permissions and then another one like 'administrator_post_manage_all' which bypasses the ownership check and allows an admin to make modification?

Edit

The following rules must be satisfied:

Only some users can create, update, delete posts; however, they must be the owners of the post to update, delete. Every user of the application should be able to read posts. My administrators should be able to update and delete any user's post.

答: Then I would suggest you think about a general data model for storing the permissions that can handle more complex situations in the future. This answer has a good abstraction https://stackoverflow.com/a/10311479/329496 using a table for permissions, another to link roles to permissions, and another to link users to roles, and another to giving permissions directly to users. You could choose to use that data model and manually insert rows into the tables and work out the queries to load which users have what permissions. Then if your application gets more complex you can add more rows without having to change your queries. </p>


问:
Maintaing drop down lists for the application
What would be the best approach to maintain the dropdown lists for the whole application (like city, state etc) taking into account the SOLID principles and performance?

Right now am loading the list values into a static property and using the same like

```<code>public int DestCountry { get; set; }

private string _CountryText;
public string CountryText
{
    get
    {
        if (this.DestCountry > 0)
        {
            _CountryText = Lists.CountryList.Find(x => x.Value == Convert.ToString(this.DestCountry)).Text;
        }
        return _CountryText;
    }
}
</code>```

But I am not sure whether this is the best approach possible. Could you please suggest.

答:
I would start with a data access interface which provides all the data your app needs. Here's a simple version with just the method in question to provide the allowable counties:

```<code>public interface IDataAccessProvider
{
    Country[] GetCountries();
}

public class Country
{
    public string Id { get; set; }
    public string Name { get; set; }
}
</code>```

And here's the first implementation of that interface:

```<code>public class DataAccessProvider : IDataAccessProvider
{
   // gets them from dbase, file, xml, blah blah blah
   // doesn't matter, just some resource that isn't hard coded
   return new List<County>() { ... };
}
</code>```

Now, here's a static helper class to get things in and out of your Application Cache. Application Cache is a great way to store data in an app to save on network/database/fileIO etc, without having to resort to statics and such.

```<code>public static class CacheHelper
{
    public static void Insert<T>(string cacheKey, T objToCache, double hoursBeforeExpiration)
    {
        if (objToCache != null && typeof(T).IsValueType && Nullable.GetUnderlyingType(typeof(T)) == null)
            throw new Exception(string.Format("Dont add non-nullable stuff to the cache. Type: {0} KeyName: {1}", typeof(T), cacheKey));

        var expire = DateTime.Now.AddHours(hoursBeforeExpiration);
        HttpContext.Current.Cache.Insert(cacheKey, objToCache, null, expire, Cache.NoSlidingExpiration);
    }

    public static T Get<T>(string cacheItemName)
    {
        try { return (T)HttpContext.Current.Cache[cacheItemName]; }
        catch { return default(T); }
    }

    public static T RetrieveThroughCache<T>(string keyName, Func<T> retrievalCall, double hoursBeforeExpiration = 1)
    {
        var objFromCache = CacheHelper.Get<T>(keyName);
        if (objFromCache != null)
            return objFromCache;

        var objFromDataCall = retrievalCall();
        Insert(keyName, objFromDataCall, hoursBeforeExpiration);
        return objFromDataCall;
    }

    public static void Remove(string keyName)
    {
        HttpContext.Current.Cache.Remove(keyName);
    }
}
</code>```

Next, we inherit from that DataAccessProvider class with a new class that knows how to use the above caching methods:

```<code>public class CachedDataAccessProvider : DataAccessProvider
{
    public override Country[] GetCountries()
    {
        return CacheHelper.RetrieveThroughCache("AppCountries", () => base.GetCountries());
    }
}
</code>```

Now in your MVC ViewModels, you get an instance of the dataprovider interface from somewhere lower (base ViewModel constructor, DI from controller, etc etc) and you can just call the dataprovider's GetCountries() method without worrying if its in cache or not. The first call will get it fresh from the database, and subsequent hits throughout the day (the default in my static class is 24 hours in the cache) will just grab it straight from Cache. You can convert the County[] values into SelectListItems to power the dropdowns.

```<code>public class MyWhateverViewModel
{
    public string SelectedCountryId { get; set; }

    public IEnumerable<SelectListItem> GetCountryChoices()
    {
        var dataProvider = GetIDataProviderInstance(); // or pass as param in constructor, etc
        return from country in dataProvider.GetCountries()
               select new SelectListItem {
                Text = country.Name,
                Value = country.Id,
                Selected = country.Id == SelectedCountryId
               };
    }
}
</code>```

Body:
I would start with a data access interface which provides all the data your app needs. Here's a simple version with just the method in question to provide the allowable counties:

public interface IDataAccessProvider
{
    Country[] GetCountries();
}

public class Country
{
    public string Id { get; set; }
    public string Name { get; set; }
}

And here's the first implementation of that interface:

public class DataAccessProvider : IDataAccessProvider
{
   // gets them from dbase, file, xml, blah blah blah
   // doesn't matter, just some resource that isn't hard coded
   return new List<County>() { ... };
}

Now, here's a static helper class to get things in and out of your Application Cache. Application Cache is a great way to store data in an app to save on network/database/fileIO etc, without having to resort to statics and such.

public static class CacheHelper
{
    public static void Insert<T>(string cacheKey, T objToCache, double hoursBeforeExpiration)
    {
        if (objToCache != null && typeof(T).IsValueType && Nullable.GetUnderlyingType(typeof(T)) == null)
            throw new Exception(string.Format("Dont add non-nullable stuff to the cache. Type: {0} KeyName: {1}", typeof(T), cacheKey));

        var expire = DateTime.Now.AddHours(hoursBeforeExpiration);
        HttpContext.Current.Cache.Insert(cacheKey, objToCache, null, expire, Cache.NoSlidingExpiration);
    }

    public static T Get<T>(string cacheItemName)
    {
        try { return (T)HttpContext.Current.Cache[cacheItemName]; }
        catch { return default(T); }
    }

    public static T RetrieveThroughCache<T>(string keyName, Func<T> retrievalCall, double hoursBeforeExpiration = 1)
    {
        var objFromCache = CacheHelper.Get<T>(keyName);
        if (objFromCache != null)
            return objFromCache;

        var objFromDataCall = retrievalCall();
        Insert(keyName, objFromDataCall, hoursBeforeExpiration);
        return objFromDataCall;
    }

    public static void Remove(string keyName)
    {
        HttpContext.Current.Cache.Remove(keyName);
    }
}

Next, we inherit from that DataAccessProvider class with a new class that knows how to use the above caching methods:

public class CachedDataAccessProvider : DataAccessProvider
{
    public override Country[] GetCountries()
    {
        return CacheHelper.RetrieveThroughCache("AppCountries", () => base.GetCountries());
    }
}

Now in your MVC ViewModels, you get an instance of the dataprovider interface from somewhere lower (base ViewModel constructor, DI from controller, etc etc) and you can just call the dataprovider's GetCountries() method without worrying if its in cache or not. The first call will get it fresh from the database, and subsequent hits throughout the day (the default in my static class is 24 hours in the cache) will just grab it straight from Cache. You can convert the County[] values into SelectListItems to power the dropdowns.

public class MyWhateverViewModel
{
    public string SelectedCountryId { get; set; }

    public IEnumerable<SelectListItem> GetCountryChoices()
    {
        var dataProvider = GetIDataProviderInstance(); // or pass as param in constructor, etc
        return from country in dataProvider.GetCountries()
               select new SelectListItem {
                Text = country.Name,
                Value = country.Id,
                Selected = country.Id == SelectedCountryId
               };
    }
}


答:
The primary purpose of the DATA statement is to give names to
  constants; instead of referring to pi as 3.141592653589793 at every
  appearance, the variable PI can be given that value with a DATA
  statement and used instead of the longer form of the constant. This
  also simplifies modifying the program, should the value of pi change.

Xerox Basic FORTRAN and Basic FORTRAN IV Manual, attributed to David H. Owens.  Source: https://en.wikiquote.org/wiki/Fortran

Of course, commonly used constant values should be used via constant declarations which make it plainly evident to whoever is looking at the code what the value stands for, and to make it easy to change the value in the future, if need be.  However, this is not to be viewed as some absolutely binding dictum that should be followed with dogmatic devotion.

Consider the following implementation of a hashCode() function:

```<code>/**
 * Computes the FNV hash code of all elements in this unmodifiable enumerable.
 */
static <E> int hashCode( UnmodifiableEnumerable<E> self )
{
    int hash = 17;
    for( E element : self )
        hash = 31 * hash + Objects.hashCode( element );
    return hash;
}
</code>```

As the comment says, this is the (most common simplified version of the) standard Fowler–Noll–Vo hash function that most programmers are familiar with. There is no point in creating constants for 17 and 31, since that would only further complicate things.  They are just two prime numbers, their use is highly localized, (only within this function,) they are highly unlikely to ever change, and if there is ever a need to change them, the person who will decide to change them better know very well what they are doing, and therefore better know very well what they stand for.

Other times, there exist numbers that are so permanently cast in stone, and so very well known by everyone, that constants are sometimes not necessary.  The hilarious quote from the Basic FORTRAN IV Manual illustrates this nicely, but here is another example: A week has seven days everywhere around the world, and this is very highly unlikely to ever change, so a simple expression which involves existing identifiers that already have meaningful names does not have anything to benefit from replacing a hard-coded literal 7 with a constant.  Who really needs to see days = weeks * DAYS_PER_WEEK instead of days = weeks * 7?

(Of course, if the expression is more complicated, or if the other identifiers that take part in the expression do not have such self-explanatory names, it may still be better to use DAYS_PER_WEEK rather than 7, for the purpose of documenting what you are doing.)

That having been said, you have to be careful with cultural issues.

On page 300 of the book "Clean Code" by Prentice Hall, author Robert C. Martin says:

And in the FEET_PER_MILE case, the number 5280 is so very well known and so unique a constant that readers would recognize it even if it stood alone on a page with no context surrounding it.

To which I have to say (excerpt from my blog)

The world is not the USA. Most of the world uses the metric system, and knows very little about miles and feet. When given a number in "United States customary units", many people outside the USA know how to convert it to metric, but it is rare to meet someone who is proficient in converting from metric to US units, and even more rare to meet someone who has the slightest clue, or the slightest interest, in converting between US units. Therefore, the number 5280 means absolutely nothing to the vast majority of the population of the planet. As a matter of fact, there are so many non-USAians working as software engineers in the USA, that even in the USA it would be a bad idea to assume that anyone who sees the number 5280 in a piece of code will know what it stands for.

Finally, magic numbers in their true sense (of having some secret meaning) should nearly always be declared with a constant, otherwise their occurrence in the middle of source code can be very puzzling, but even this rule has an exception.  If you are only going to use a particular magic number once in your entire code base, and if it is to appear in a piece of code like the following, then it is okay, because what is going on is very obvious:

```<code>if( fileObject.getMagicNumber() == 0xbadbeef ) { ... }
</code>```

Body:
The primary purpose of the DATA statement is to give names to
  constants; instead of referring to pi as 3.141592653589793 at every
  appearance, the variable PI can be given that value with a DATA
  statement and used instead of the longer form of the constant. This
  also simplifies modifying the program, should the value of pi change.

Xerox Basic FORTRAN and Basic FORTRAN IV Manual, attributed to David H. Owens.  Source: https://en.wikiquote.org/wiki/Fortran

Of course, commonly used constant values should be used via constant declarations which make it plainly evident to whoever is looking at the code what the value stands for, and to make it easy to change the value in the future, if need be.  However, this is not to be viewed as some absolutely binding dictum that should be followed with dogmatic devotion.

Consider the following implementation of a hashCode() function:

/**
 * Computes the FNV hash code of all elements in this unmodifiable enumerable.
 */
static <E> int hashCode( UnmodifiableEnumerable<E> self )
{
    int hash = 17;
    for( E element : self )
        hash = 31 * hash + Objects.hashCode( element );
    return hash;
}

As the comment says, this is the (most common simplified version of the) standard Fowler–Noll–Vo hash function that most programmers are familiar with. There is no point in creating constants for 17 and 31, since that would only further complicate things.  They are just two prime numbers, their use is highly localized, (only within this function,) they are highly unlikely to ever change, and if there is ever a need to change them, the person who will decide to change them better know very well what they are doing, and therefore better know very well what they stand for.

Other times, there exist numbers that are so permanently cast in stone, and so very well known by everyone, that constants are sometimes not necessary.  The hilarious quote from the Basic FORTRAN IV Manual illustrates this nicely, but here is another example: A week has seven days everywhere around the world, and this is very highly unlikely to ever change, so a simple expression which involves existing identifiers that already have meaningful names does not have anything to benefit from replacing a hard-coded literal 7 with a constant.  Who really needs to see days = weeks * DAYS_PER_WEEK instead of days = weeks * 7?

(Of course, if the expression is more complicated, or if the other identifiers that take part in the expression do not have such self-explanatory names, it may still be better to use DAYS_PER_WEEK rather than 7, for the purpose of documenting what you are doing.)

That having been said, you have to be careful with cultural issues.

On page 300 of the book "Clean Code" by Prentice Hall, author Robert C. Martin says:

And in the FEET_PER_MILE case, the number 5280 is so very well known and so unique a constant that readers would recognize it even if it stood alone on a page with no context surrounding it.

To which I have to say (excerpt from my blog)

The world is not the USA. Most of the world uses the metric system, and knows very little about miles and feet. When given a number in "United States customary units", many people outside the USA know how to convert it to metric, but it is rare to meet someone who is proficient in converting from metric to US units, and even more rare to meet someone who has the slightest clue, or the slightest interest, in converting between US units. Therefore, the number 5280 means absolutely nothing to the vast majority of the population of the planet. As a matter of fact, there are so many non-USAians working as software engineers in the USA, that even in the USA it would be a bad idea to assume that anyone who sees the number 5280 in a piece of code will know what it stands for.

Finally, magic numbers in their true sense (of having some secret meaning) should nearly always be declared with a constant, otherwise their occurrence in the middle of source code can be very puzzling, but even this rule has an exception.  If you are only going to use a particular magic number once in your entire code base, and if it is to appear in a piece of code like the following, then it is okay, because what is going on is very obvious:

if( fileObject.getMagicNumber() == 0xbadbeef ) { ... }


问:
API Breaking Changes
I have a public REST API for creating new business profile records in my system. The request itself looks similar to this:

```<code>{
    "BusinessName" : "AName",
    "CurrencyCode" : "USD"
}
</code>```

You can see the CurrencyCode property on the request is set to "USD" and our REST API documentation incorrectly asserts that we support "USD" or "EUR" as values to this property.

Here's the problem, in recent talks with the busisness it became clear that while we may support multiple currency codes in the future today we only support "USD", and on top of that we will never support changing the CurrencyCode on the request since it's a limitation in our industry. Our existing code ignores the value of "CurrencyCode" on the request and  hardcodes it to "USD" throughout our system (legacy code).

So due to the fact that we will never support CurrencyCode being passed on the request the decision was made to remove it. So going forward if "CurrencyCode" is provided on the request we will continue to ignore it so the user wont get an error and processing will continue as expected as long as they are passing "USD".  If however they coded against our current API documentation and expected that support to be in place then they will encounter problems when their software attempts to use "EUR" for currency code.

Granted today's users of the API do not have any way of using the "Eur" currency code because our applicaiton is ignoring this value. However, I would argue that this is a bug and that the removal of this value without any kind of versioning of the api is a bad practice. I assert this should be considered a breaking change.

So the question, "Is removing the "CurrencyCode" property from the request a breaking change even though we don't support it today(bug) and will never support it in the future?"

答:
No.

If your code ever actually allowed public consumers to set their CurrencyCode to EUR, and now it doesn't, then that is a breaking change since you're changing the semantics. If your code always used USD even if that was a bug, then it is not a breaking change.

But ignoring the input itself and changing the documentation to reflect that is not a breaking change in and of itself.

Title: API Breaking Changes