问:
How do you cope with ugly code that you wrote?
So your client asks you to write some code, so you do. He then changes the specs on you, as expected, and you diligently implement his new features like a good little lad. Except... the new features kind of conflict with the old features, so now your code is a mess. You really want to go back and fix it, but he keeps requesting new things and every time you finish cleaning something, it winds up a mess again.

What do you do? Stop being an OCD maniac and just accept that your code is going to wind up a mess no matter what you do, and just keep tacking on features to this monstrosity? Save the cleaning for version 2?

答:
I think writing software needs to go hand in hand with business needs. If it is a throwaway project (like a prototype that needs to be built in a week, with new inputs coming in every day), then there is no need to worry about code maintainability and other stuff - time is crucial and you just need to push your code out of the door as fast as you can.

But if you are writing a long term app, then it makes sense to consider all this, because there is a sizable impact on how long it takes to build new features, to fix existing bugs, to integrate into other applications and other stuff - and this translates into business impact (because of more time required later and more cost).

So it is better to sensitize the decision maker to the actual costs of not refactoring code whenever necessary - in my experience, if the costs and time impact of both the options are explained in measurable terms to the decision owner, then the decision can be a no-brainer. Don't expect people to tell you 'yeah go ahead write beautiful code, even though it takes twice as much time and gives me no extra benefit'. It just doesn't work that way.


问:
What does SVN do better than Git?
No question that the majority of debates over programmer tools distill to either personal choice (by the user) or design emphasis, that is, optimizing design according to particular uses cases (by the tool builder). Text editors are probably the most prominent example--a coder who works on Windows at work and codes in Haskell on the Mac at home, values cross-platform and compiler integration and so chooses Emacs over TextMate, etc.

It's less common that a newly introduced technology is genuinely, demonstrably superior to the extant options.

Is this in fact the case with version-control systems (VCS), in particular, centralized VCS (CVS and SVN) versus distributed VCS (Git and Mercurial)?

I used SVN for about five years, and SVN is currently used where I work. A little less than three years ago, I switched to Git (and GitHub) for all of my personal projects.

I can think of a number of advantages of Git over Subversion (and which for the most part abstract to advantages of distributed over centralized VCS), but I cannot think of one contra example--some task (that's relevant and arises in a programmers usual workflow) that Subversion does better than Git.

The only conclusion I have drawn from this is that I don't have any data--not that Git is better, etc.

My guess is that such counter-examples exist, hence this question.

答:
In Subversion, you can edit log messages (also called "commit messages") after the commit is done and pushed.  For most practical uses, this is impossible by design in decentralized systems, including git.  Of course, in git you can do "git commit --amend", but that doesn't help you after your commit has been pushed elsewhere.  In SVN, when you edit the log message, you're doing it on the central repository that everyone shares, so everyone will get the edit, and without the revision's identifier changing.

Editing log messages after the fact is often very useful.  Aside from just fixing a mistake or an omission in a log message, it enables you to do things like update a log message to refer to a future commit (such as a revision that fixes a bug or completes the work introduced in the current revision).

There need be no danger of losing information, by the way.  The pre-revprop-change and post-revprop-change hooks can save a history of the old messages if you're really concerned, or send out emails with the log message diff (this is more common, actually), so that there's an audit trail.

ContentLicense: CC BY-SA 3.0

Title: What does SVN do better than Git?


问:
Ordering if conditions for efficiency and clean code
This is purely a design question and the example is simple to illustrate what I am asking and there are too many permutations of more complex code to provide examples that would cover the topic. I am not referring specifically to this example, just using the example to illustrate what I am referring to.

In an if statement, is there a preferred way to order conditions, in terms of coding convention and, more importantly, efficiency?

For such a simple example, efficiency will not be an issue, but I am not asking for a code review per se, but an understanding of the concept.

Two alternatives:

1.

```<code>public double myStuff(int i)
{
    // check for an invalid number of tourists
    if (i > 0)
    {
        // do something here

        return doubleSomething;
    } else
    {
        return Double.NaN;
    }
}
</code>```

2.

```<code>public double myStuff(int i)
{

    if (i <= 0)
    {
        return Double.NaN;

    } else
    {

        {
            // do something here

            return doubleSomething;
        }
</code>```

If the if statement was to become more complex, and possibly nested, in what order should conditions be addressed?

答:
Efficiency is not usually a real concern for structuring if-statements, even if they are complex or nested.  There are ways to nest if-statements that could be less efficient than others, but if the code is only run once and takes 5 nanoseconds too long, you aren't even going to be able to notice that there's a difference.

It is possible for this sort of thing to make a real difference in the running time of a program, especially if it's in the innermost loop of some nested loops.  However, the best way to deal with a slow program is to measure it and find out where it's spending most of its time, so you can make that spot more efficient -- whether or not that spot has anything to do with nested if-statements.

What should be the concern for if-statements (especially nested or complex ones) is readability.  It is very easy to make an unreadable mess out of complex nested if-statements, and the harder code is to read, the harder it is to ensure that it's correct or to debug it.

For simple if-statements, try to keep the condition from being too crazy.  If you can't avoid a complex condition, try using formatting to clarify it, or use a helper function to evaluate the condition.

Mess:

```<code>if(a <= 5 && b > 10 && c < 4 && b <= 100
   && a > 2 && c > 1)
</code>```

Better formatting:

```<code>if( (a > 2)  && (a <= 5)   &&
    (b > 10) && (b <= 100) &&
    (c > 1)  && (c < 4) )
</code>```

Helper function:

```<code>if( withinLimits(a, b, c) )
</code>```

Also, try to avoid double-negatives.  "I wouldn't say that's not an incorrect statement" is hard to read.  "That's wrong" is easy to read, and means the same thing.  Single negatives aren't so bad, but sometimes you can make things a bit clearer by stating something positively instead.

For nested if-statements, it depends on how they're nested.

For something like this:

```<code>if(a) {
  if(b) {
    if(c) {
      something;
    }
  }
}
</code>```

You could replace it with something like this:

```<code>if(a && b && c) {
  something;
}
</code>```

If you have a complex nesting of if-statements, it's probably a mess.  How to clean it up exactly depends on what exactly it is.  It may be possible to create a decision table -- an array that has indices that represent what we're basing the decision on and entries that are the resulting decision.  If so, we can just look up the answer without using any if-statements at all.

Body:
Efficiency is not usually a real concern for structuring if-statements, even if they are complex or nested.  There are ways to nest if-statements that could be less efficient than others, but if the code is only run once and takes 5 nanoseconds too long, you aren't even going to be able to notice that there's a difference.

It is possible for this sort of thing to make a real difference in the running time of a program, especially if it's in the innermost loop of some nested loops.  However, the best way to deal with a slow program is to measure it and find out where it's spending most of its time, so you can make that spot more efficient -- whether or not that spot has anything to do with nested if-statements.

What should be the concern for if-statements (especially nested or complex ones) is readability.  It is very easy to make an unreadable mess out of complex nested if-statements, and the harder code is to read, the harder it is to ensure that it's correct or to debug it.

For simple if-statements, try to keep the condition from being too crazy.  If you can't avoid a complex condition, try using formatting to clarify it, or use a helper function to evaluate the condition.

Mess:

if(a <= 5 && b > 10 && c < 4 && b <= 100
   && a > 2 && c > 1)

Better formatting:

if( (a > 2)  && (a <= 5)   &&
    (b > 10) && (b <= 100) &&
    (c > 1)  && (c < 4) )

Helper function:

if( withinLimits(a, b, c) )

Also, try to avoid double-negatives.  "I wouldn't say that's not an incorrect statement" is hard to read.  "That's wrong" is easy to read, and means the same thing.  Single negatives aren't so bad, but sometimes you can make things a bit clearer by stating something positively instead.

For nested if-statements, it depends on how they're nested.

For something like this:

if(a) {
  if(b) {
    if(c) {
      something;
    }
  }
}

You could replace it with something like this:

if(a && b && c) {
  something;
}

If you have a complex nesting of if-statements, it's probably a mess.  How to clean it up exactly depends on what exactly it is.  It may be possible to create a decision table -- an array that has indices that represent what we're basing the decision on and entries that are the resulting decision.  If so, we can just look up the answer without using any if-statements at all.


问:
Why do large IT projects tend to fail or have big cost/schedule overruns?
I always read about large scale transformation or integration project that are total or almost total disaster. Even if they somehow manage to succeed  the cost and schedule blow out is enormous. What is the real reason behind large projects being more prone to failure. Can agile be used in these sort of projects or traditional approach is still the best.

One example from Australia is the Queensland Payroll project where they changed test success criteria to deliver the project.

See some more failed projects in this SO question (on Wayback Machine)

Have you got any personal experience to share?

答: The larger the project, the more likely you are working for a large organization.  The larger the organization, the more layers of management.  The more layers of management, the harder it is for bad news ("we can't have what we want for what we can afford") to make it up the chain of command.  The less likely bad news can make it up the chain of command, the more likely a fantasy plan will be accepted and then held to long after it is known to be untenable.</p>

ContentLicense: CC BY-SA 2.5


问:
iOS7 apps only using iPad only
I would like to develop iOS apps but due to budgetary issues I can only afford an iPad mini gen1 or iPod touch 5th gen. Is it possible for me to make apps for all iPhones and iPads/iPods using just a single device? Another question is how does the latest iOS7 work on ipad mini gen 1/iPod touch and what are the limitations when working with these devices when compared to an iPhone(My target apps are trivia and endless runner games).

Thanks

P.S. I do have a mac with xcode on it and I am developing a cocoa app right now and the question is if i can develop for all io7 devices using just one deceive for final testing.

答:
You can develop and do preliminary testing using the simulator for any iOS device.  But you will find some things (e.g., camera) that cannot be tested on the simulator so ultimately you will have to have some kind of access to actual devices for serious testing, or at least have access to someone who does has them.

It is easy enough to email the app to people who are willing to work with the program to test it on various devices.  We started with just the devices we had and have tried to add a more diverse selection as the testing progresses.

I would not be put off by the lack of availability of a particular device for testing; for any real testing, you're going to have have different USERS as well as devices.  Finding users who are willing to commit time to testing a project they may or may not have any interest in is far more difficult than finding a diversity of devices.

Given a choice I'd much prefer having five users test on a single device than one user testing on five devices...

Title: iOS7 apps only using iPad only


问:
How could Clang release under BSD license?
I found that llvm could only generate assembly code. If someone want generate and link assembly code to native executable code, they should use external tool(GNU as/ld, for example. Currently lld is not ready, and there no more information about llvm-mc).

This question's answer and other answers imply that Clang use Binutils(as and ld) to generate and link native code(I'm not quite sure about this). If so, how could Clang release  under BSD like license? I can't find any license exception(like Bison Exception) about ld or as.

If I misunderstand some concepts, please forgive me! BTW, could we use GNU as and ld in programmatically way?

EDIT: Thanks for these answers. It seems that clang still not a standalone toolchain and have to use VS or GNU tools. Does it mean if someone write a compiler based on llvm. If users didn't install GNU or VS tools. The compiler is not a out-of-the-box compiler?

答:
I am not a lawyer.  To get an authoritative answer on this, I would dig around FreeBSD.org to find the contact information for a lawyer for that project.  All that follows is a layman's understanding of copyrights - in particular derivative works and the originality requirement.

In order for something to be copyrighted, it must show some amount of original material in it (wiki: threshold of originality, uslegal.com originality in copyright) .  It cannot be a purely mechanical transformation.

Taking the assembly code produce by clang and linking it against existing libraries do not meet this threshold.  This is no different really than a compiler taking the source (that you write - original, has a copyright) and mechanically translating it to assembly.  There is no creativity in this process, the produced output of clang (or gcc, or ld) is not something that incorporates material that is under another license, there is no exception needed as part of the process to create code.

Just think for a moment the implications if this wasn't the case.  Every program that was linked on a linux system (using ld from gnu bin tools) would need to be free (libre) under the gpl.  You would be required to distribute the source of every program.  This would cripple the possibility of commercial code development on linux, and well... you wouldn't have any games for Linux.

So, because the process of creating a linked executable from assembly (or assembly from some language) does not have any originality to it, the product isn't a derivative work of the program (or the author of the program - read more on this in that small text block up next), and the license of the original work does not change.

Tangentially related, music that is composed by a computer is an interesting area of law being settled currently.  From Music Tracks to Google Maps: Who owns computer-generated works? and MIDI Files: Copyright Protection for Computer- Generated Works are likely good reads if you want to get into the level of being able to talk to lawyers directly about things.

This is where the bison exception gets into play (gnu.org FAQ Can I use GPL-covered editors such as GNU Emacs to develop non-free programs? Can I use GPL-covered tools such as GCC to compile them?, gnu.org Conditions for Using Bison).  The code that bison generates, while being a transformation of the .y file that bison reads, the created code also includes a substantial part of material that is copyrightable and covered under the GPL.  Thus, the final output would be considered a derivative work of the two (the .y file, and the parser generator that was written by some human and embedded in bison itself).

Since the code within bison is under the gpl, the impact of this without the bison exception would mean that every derivative work created (all of them) would also be under the gpl.  The final generated code is still a derivative work, but it isn't required to be GPL'ed.

I would point out that the bison exception refers to the product of bison.  If one was to take the raw code out of bison and use it in some other way that isn't a product of bison, it is still covered by the GPL.

Additional note, Free BSD still uses binutils 2.15 (from 2004) because of difficulties meshing gpl v3 with the BSD license (2.15 is under v2, there is work being done to get binutils 2.17 which is the last released version under gpl v2 - see FreeBSD wiki - Bintuils 2.17).


问:
How does the CPU know when it received RAM data and instructions?
Well, the title is pretty much self explanatory, but I'll expound it a bit, and say the origin of my question.

So, I've been wondering as to how the CPU knows when it received the RAM. I'm pretty sure it doesn't OR the RAM outputs together, because 0x00 is still a number, yet ORing that together says that the RAM has not outputed anything. Does the RAM have some kind of "request acknowledged" line? Well, my friend was making an MC CPU, and he used interrupts for RAM reading, so that's where I got this idea.

Anyways, the origin of my problem is probably when I was thinking about Virtual Memory. In virtual memory, you have to fetch from the disk and to the RAM. How does one compensate for the gap between the speeds? May this be answered too?

答:
Yes, there is a Data Acknowledge signal.  It asserts that the data has been placed onto the memory bus, and is available to the processor for reading.

Briefly, the memory read cycle works like this:

The processor initiates a read bus cycle by floating the address of the memory location on the address lines.

Once the address lines are stable, the processor asserts the address strobe signal on the bus. The address strobe signals the validity of the address lines.

The processor then sets the Read/Write signal to high, i.e. read.

Now the processor asserts the data strobe signal. This signals to the memory that the processor is ready to read data.

The memory subsystem decodes the address and places the data on the data lines.

The memory subsystem then asserts the data acknowledge signal. This signals to the processor that valid data can now be latched in.

The processor latches in the data and negates the data strobe. This signals to the memory that the data has been latched by the processor.
The processor also negates the address strobe signal.

Memory subsystem now negates the data acknowledgement signal. This signals the end of the read bus cycle.

The Data Acknowledge signal is asserted in Step 6.

Processors compensate for the amount of time it takes to read memory by imposing Wait States.  However, virtual memory is an operating system function, so the operating system manages the time it takes to read the data off the hard disk and swap it into memory, where the CPU can read it in the usual way.

In simple terms, the CPU simply waits in a loop until the data is available.


问:
Where did Java go wrong on the client?
Not talking about the recent Java/Oracle debacle here, but something I've been wondering recently.

When I first started programming, Java was the big thing client-side, however these days you hardly ever see a Java applet whereas Flash and Javascript are ubiquitous.

Where did Java go wrong? Did Sun decide to concentrate on the server-side and let client-side stagnate? How did Flash become dominant over Java? Flashy (no pun intended) graphics? Marketing?

Never having been a Java developer, I've not followed this closely so I'm interested to hear your thoughts.

答:
Besides what everybody else pointed out, I'd like to note the developing difference: Java is more appreciated by serious coders and is seen a lot in universities, while Flash is meant to target web developers (programmers too, but as a secondary audience to the platform).

So you see Flash doing things it shouldn't (like whole websites) in the hands of designers, while Java isn't in the hands of designers in the first place.

Title: Where did Java go wrong on the client?


问:
How to ensure that a member variable is initialized before calling a class method
There's a class with a parametrized constructor that initializes a member variable. All public methods of the class then use this member variable to do something.

I want to ensure that the caller always creates an object using the parametrized constructor (there is also a setter for this member variable) and then call that object's methods. In essence, it should be impossible for the caller to call any method without setting a value to the member variable (either by using the parametrized constructor or the setter). Here's the catch - there is just one method that itself generates a value to be initialized in the member variable (and returns it) - and to call that function, one would need a default constructor.

Currently, a caller can simply make an object using the default constructor and then call that object's method - I want to avoid checking whether or not the member variable is set in each and every one of the 20-odd methods of the class (and throw an exception if it is not) - except for the one method mentioned above.

Though a runtime solution is acceptable (better than the one I mentioned above); a compile-time solution is preferable so that any developer will not be allowed to make that mistake and then waste hours debuggging it!

Update: Here's an artist's impression of the current implementation in code:

```<code>class MyClass
{
private:
string m_strProperty;

void InternalNonStaticMethod(int iSomeParam);

public:
MyClass(string strValue)
{
m_strProperty = strValue;
}

MyClass() {}

void setProperty(string strValue)
{
    m_strProperty = strValue;
}

string MethodOddManOut()
{
    /* Do some computations to generate a value for the property */
    string strGeneratedValue("");
    InternalNonStaticMethod(4);
    /* ... */
    return strGeneratedValue;  // The value has to be returned and this method cannot simply update the member due to design issues that are beyond the realm of this question
}

void MethodLikeEveryoneElse()
{
    /* Do some computation based on the property */
    string strTemp = m_strProperty + "EXTEND";

    /* If strProperty is empty/garbage then this is going to fail miserably
       Trying to avoid the following snippet at 20 other similar methods:
       if (!strProperty.empty()) {
           strTemp = m_strProperty + "EXTEND";
       } else {
           throw exception
       }
    */
}

void MethodLikeEveryoneElse2()
{
    /* Similar to the above method */
}

}
</code>```

The caller would be a function in some other class using it like this:

```<code>void MethodThatUsesThis()
{
    MyClass objA;
    m_strHandle = objA.MethodOddManOut();  // Save the handle as a member of this object

    /* Some other lines of code */

    objA.setProperty(strHandle);
    objA.MethodLikeEveryoneElse();
}

void AnotherMethodThatUsesThisLater(string strHandle)
{
    MyClass objA(strHandle);  // The handle that the above method received was passed to this method since they are in different classes
    objA.MethodLikeEveryoneElse2();
}
</code>```

This code snippet is bound to raise tons of allegations on the horrendous design that is being implemented - but my only defense is, this is legacy code (ha! you saw this coming) and I only have the right to change anything in class A (it's more of an API and a library module) but the caller is not in my jurisdiction.

答:
```<code>   class A {
     static const INVALID_PROPERTY_VALUE = -1; //null_ptr for non-primitives?
     int property;
     public :
     explicit A (int initialPropertyValue):
       property(initialPropertyValue) {
        if (initialPropertyValue == INVALID_PROPERTY_VALUE)
          throw illegal_argument("property can't be unset");
     }
     int setProperty(int newValue) {
        if (newValue == INVALID_PROPERTY_VALUE)
          throw illegal_argument("property can't be unset");
        int rv = property;
        property = newValue;
        return rv;
     }
   }

   int main() {
     A a(56);
     a.doSome();
     a.setProperty(-1); // fails early, requires no long debug when property is used
     a.doNext();
   }
</code>```


问:
Do $_POST, $_GET, etc violate the encapsulation principle?
Using globals makes your code hard to test thus more prone to bugs, not secure and unpredictable. That's why we pass the variables we want inside a function/object. So my question is simple:

Do $_POST, $_GET, etc violate the encapsulation principle?

I'm thinking that, to retain control of those variables in an OO way, an ideal solution would be to add some lines like this to the code:

```<code>// Convert the $_GET array to an object
$get = json_decode(json_encode($_GET), FALSE);  // stackoverflow.com/a/1869147
// Stop it from being included from anywhere
unset($_GET);

// Small example of what could be done later on
$DB = new PDO(/* ... */);
$Person = new Person($DB, $get->id);
</code>```

I haven't seen this anywhere, not even a tutorial nor recommendation. Also, we can clearly see how the code above is much easier to be tested than one that includes $Person = new Person($DB, $_GET['id']); or even (the ugly) $Person = new Person($DB); as you can use a mock $get object.

Is the code above in the right direction or am I missing something?

EDIT: After some investigation (Zend framework and Cake PHP) as Alexander Kuzmin suggested, it seems to be the right thing to go. They're probably too big for me to dig into the code ATM, but I'll keep it in mind.

答:
POST- and GET-vars are sent to the server in one bulk and php has to make sense of them. In a way, it makes sense to have them available globally, so the developer can choose where to process them.

Many frameworks (like CakePHP for example) read the Parameters and then place them all in some array, object or similar structure. After that, they are handled like any other data and are passed to all methods needing them.

OwnerDisplayName: Francisco Presencia

OwnerDisplayName: Lars Ebert


答:
Encapsulation is a good principle when there's a chance that you might need multiple instances of something. But there's only one set of parameters to a web page. If they were in a class instead of global variables, they would probably be singletons. There's no significant improvement going from global variables to singleton classes, it's just a different syntax to access them. They're still inherently global objects, it's just more cumbersome because you have to get a handle on the class instance and pass it around.

Since these parameters are accessed so frequently, the PHP designers made a decision to make them easy to access, rather than adhere to rigid design principles. It's a good idea to make the most common operations convenient, otherwise programmers will curse you for making them retype the same, long thing every time.

Body:
Using globals makes your code hard to test thus more prone to bugs, not secure and unpredictable. That's why we pass the variables we want inside a function/object. So my question is simple:

Do $_POST, $_GET, etc violate the encapsulation principle?

I'm thinking that, to retain control of those variables in an OO way, an ideal solution would be to add some lines like this to the code:

```<code>// Convert the $_GET array to an object
$get = json_decode(json_encode($_GET), FALSE);  // stackoverflow.com/a/1869147
// Stop it from being included from anywhere
unset($_GET);

// Small example of what could be done later on
$DB = new PDO(/* ... */);
$Person = new Person($DB, $get->id);
</code>```

I haven't seen this anywhere, not even a tutorial nor recommendation. Also, we can clearly see how the code above is much easier to be tested than one that includes $Person = new Person($DB, $_GET['id']); or even (the ugly) $Person = new Person($DB); as you can use a mock $get object.

Is the code above in the right direction or am I missing something?

EDIT: After some investigation (Zend framework and Cake PHP) as Alexander Kuzmin suggested, it seems to be the right thing to go. They're probably too big for me to dig into the code ATM, but I'll keep it in mind.

OwnerDisplayName: Barmar


答:
Using superglobals $_{POST,GET,SERVER} or whatever surely violates the encapsulation.

This problem grows when you want do create "local requests" within the server side of you application as many frameworks do nowadays.

I'm not used to work with frameworkds, but what I usually do is to create a Request/Response pair at the beginning of my processing. The request contains the values these global parameters.

If I want to create a server-side subrequest, I have two options: use the current context or create a entirely new one. So, I think you shouldn't unset these superglobal variables because MAYBE you'd want do use them again. Also, for this reason, I disagree that request params should be singletons.

By containing only values, not references to these superglobals, a change in one Request object will never affect another, so, the problem with global state is solved.

So, basically, I have two options:

```<code>// Using global context
$request = new Request(array(
    'post' => $_POST,
    'get' => $_GET
));

// or creating a new context

$request = new Request(array(
    'post' => ['someKey' => 'someValue'],
    'get' => ['queryParam' => 'queryValue'],
));
</code>```

Title: Do $_POST, $_GET, etc violate the encapsulation principle?

Body:
Using superglobals $_{POST,GET,SERVER} or whatever surely violates the encapsulation.

This problem grows when you want do create "local requests" within the server side of you application as many frameworks do nowadays.

I'm not used to work with frameworkds, but what I usually do is to create a Request/Response pair at the beginning of my processing. The request contains the values these global parameters.

If I want to create a server-side subrequest, I have two options: use the current context or create a entirely new one. So, I think you shouldn't unset these superglobal variables because MAYBE you'd want do use them again. Also, for this reason, I disagree that request params should be singletons.

By containing only values, not references to these superglobals, a change in one Request object will never affect another, so, the problem with global state is solved.

So, basically, I have two options:

// Using global context
$request = new Request(array(
    'post' => $_POST,
    'get' => $_GET
));

// or creating a new context

$request = new Request(array(
    'post' => ['someKey' => 'someValue'],
    'get' => ['queryParam' => 'queryValue'],
));

OwnerDisplayName: Henrique Barcelos


答:
I’m not quite sure why you apply json_decode to $_GET to “convert it to an a array”; $_GET already is an array.

Using the super-globals ($_GET, $_POST etc) is a violation of the encapsulation principle. But there has been to be a line drawn where you stop encapsulating things. Request data is a good candidate for encapsulation, but don’t get sucked down the rabbit hole of trying to encapsulate all the things.

Most frameworks usually wrap PHP’s super-globals into some form of request object. Doing this then makes it easier to mock for tests etc. The simplest approach would be:

```<code><?php
class Request
{
    public $get;
    public $post;
    public $session;
    public $cookie;

    public function __construct($get, $post, $session, $cookie)
    {
        $this->get = $get;
        $this->post = $post;
        $this->session = $session;
        $this->cookie = $cookie;
    }
}

$request = new Request($_GET, $_POST, $_SESSION, $_COOKIE);
</code>```

It’s simple and rudimentary, but does the job. It’s also advisable to filter the data at this point, to defend against XSS injections.

But it’s wrapped in a Request object. The Request object has four arrays, and these arrays can easily be mocked:

```<code>$get = array(
    'foo' => 'bar'
);
$post = array();
$session = array(
    'user' => 1
);
$cookie = array();

$request = new Request($get, $post, $session, $cookie);
</code>```

Body:
I’m not quite sure why you apply json_decode to $_GET to “convert it to an a array”; $_GET already is an array.

Using the super-globals ($_GET, $_POST etc) is a violation of the encapsulation principle. But there has been to be a line drawn where you stop encapsulating things. Request data is a good candidate for encapsulation, but don’t get sucked down the rabbit hole of trying to encapsulate all the things.

Most frameworks usually wrap PHP’s super-globals into some form of request object. Doing this then makes it easier to mock for tests etc. The simplest approach would be:

<?php
class Request
{
    public $get;
    public $post;
    public $session;
    public $cookie;

    public function __construct($get, $post, $session, $cookie)
    {
        $this->get = $get;
        $this->post = $post;
        $this->session = $session;
        $this->cookie = $cookie;
    }
}

$request = new Request($_GET, $_POST, $_SESSION, $_COOKIE);

It’s simple and rudimentary, but does the job. It’s also advisable to filter the data at this point, to defend against XSS injections.

But it’s wrapped in a Request object. The Request object has four arrays, and these arrays can easily be mocked:

$get = array(
    'foo' => 'bar'
);
$post = array();
$session = array(
    'user' => 1
);
$cookie = array();

$request = new Request($get, $post, $session, $cookie);

OwnerDisplayName: Martin Bean


问:
Client-server application design issue
I have a collection of clients on server's side. And there are some objects that need to work with that collection - adding and removing clients, sending message to them, updating connection settings and so on. They should perform these actions simultaneously, so mutex or another synchronization primitive is required. I want to share one instance of collection between these objects, but all of them require access to private fields of collection. I hope that code sample makes it more clear[C++]:

```<code>class Collection
{
    std::vector< Client* > clients;
    Mutex mLock;
    ...
}

class ClientNotifier
{
    void sendMessage()
    {
         mLock.lock();
         // loop over clients and send message to each of them
    }
}

class ConnectionSettingsUpdater
{
    void changeSettings( const std::string& name )
    {
        mLock.lock();
        // if client with this name is inside collection, change its settings
    }
}
</code>```

As you can see, all these classes require direct access to Collection's private fields.

Can you give me an advice about how to implement such behaviour correctly, i.e. keeping Collection's interface simple without it knowing about its users?

答:
From your limited code snippet, what I understand is that the Collection class is a data-centric class that holds a vector of Client* and so on. The other 2 classes are method-centric and use a Collection object (not sure how, but presumably the object is a member of this class or is being passed to the methods somehow).

My suggestion would be to merge these data-centric and method-centric classes. The Collection class correctly represents a collection of Clients so that design is spot-on. But the other classes are actually performing operations on the Collection - which is why you end up needing access to private members. Any operations that are performed on an instance of a class should be member functions of that class itself.

Thus, sendMessage() should be a member of the Collection class, since you are sending a message to all Clients in the Collection.

Now, that might seems like a naive suggestion since it looks like you are trying to group together methods related to notifying the clients in the ClientNotifier class. If you want to stay with this approach then here's a solution that might help:

```<code>class Collection
{
    private:
        std::vector< Client* > m_clients;
        Mutex m_mLock;

    public:
        void sendMessage()
        {
            ClientNotifier objClientNotifier;  // Create an instance of the ClientNotifier class that provides this functionality

            /* Loop through all clients in the member vector to send a message to each of them */
            for (std::vector<Client*>::iterator itrClients = m_clients.begin(); itrClients != m_clients.end(); ++itrClients) {
                m_mLock.lock();  // Member mutex access through a member function, which is acceptable
                objClientNotifier.sendMessage(*itrClients);
                m_mLock.unlock();
            }
        }
}

class ClientNotifier
{
    public:
        void sendMessage(Client* pobjClient)
        {
             /* Use the pointer to a Client object to send a message to that client */
        }
}
</code>```

Title: Client-server application design issue

Body:
From your limited code snippet, what I understand is that the Collection class is a data-centric class that holds a vector of Client* and so on. The other 2 classes are method-centric and use a Collection object (not sure how, but presumably the object is a member of this class or is being passed to the methods somehow).

My suggestion would be to merge these data-centric and method-centric classes. The Collection class correctly represents a collection of Clients so that design is spot-on. But the other classes are actually performing operations on the Collection - which is why you end up needing access to private members. Any operations that are performed on an instance of a class should be member functions of that class itself.

Thus, sendMessage() should be a member of the Collection class, since you are sending a message to all Clients in the Collection.

Now, that might seems like a naive suggestion since it looks like you are trying to group together methods related to notifying the clients in the ClientNotifier class. If you want to stay with this approach then here's a solution that might help:

class Collection
{
    private:
        std::vector< Client* > m_clients;
        Mutex m_mLock;

    public:
        void sendMessage()
        {
            ClientNotifier objClientNotifier;  // Create an instance of the ClientNotifier class that provides this functionality

            /* Loop through all clients in the member vector to send a message to each of them */
            for (std::vector<Client*>::iterator itrClients = m_clients.begin(); itrClients != m_clients.end(); ++itrClients) {
                m_mLock.lock();  // Member mutex access through a member function, which is acceptable
                objClientNotifier.sendMessage(*itrClients);
                m_mLock.unlock();
            }
        }
}

class ClientNotifier
{
    public:
        void sendMessage(Client* pobjClient)
        {
             /* Use the pointer to a Client object to send a message to that client */
        }
}


答:
Can agile be used in these sort of projects or traditional approach is still the best.

The reason why well applied agile processes don't seem to suffer from this problem as much is for a simple reason.  You cannot start a large project in an agile manner.  You can chose one or the other.

With an agile process, you are never really looking past one or two iterations into the future of the project.  there is no 'plan' for the next 2 years, only the next two weeks.  When your view is that short, you have to make a few compromises.  You cannot ever start with a plan to make "The final word in widgets", for whatever sort of widget you are designing.  At most, you can start with "A widget that can frob", because thats about the most work you can get done in one or two iterations.

The good thing about this, is after a few iterations, you already have a completed, working product that someone can find useful, especially that one customer who desperately needs a widget that can frob and zort.

Essentially, large projects can fail because they aim to solve all of the problems of all of the potential customers.  An agile project never has this goal, instead addressing in each version just one critical issue a single customer might have.  After a good long while, though, an agile project might be solving alot of critical issues for alot of customers.

Title: Why do large IT projects tend to fail or have big cost/schedule overruns?

Body:
I always read about large scale transformation or integration project that are total or almost total disaster. Even if they somehow manage to succeed  the cost and schedule blow out is enormous. What is the real reason behind large projects being more prone to failure. Can agile be used in these sort of projects or traditional approach is still the best.

One example from Australia is the Queensland Payroll project where they changed test success criteria to deliver the project.

See some more failed projects in this SO question (on Wayback Machine)

Have you got any personal experience to share?


问:
Good design for a recreation of pokemon
I'm currently working on a group project to recreate the original Pokemon Yellow version in Java. We've only just started planning it out but they way we've drawn out the design right now is to have an abstract Pokemon class and have 151 (Count of the original Pokemon) classes that extend it, each one being a different Pokemon. Each class will be able to store data such as an ID, its name, the type of Pokemon it is (ie: rock/water/fire/etc), and the moves it can use and learn. It seems a little much to be creating 151 classes for the Pokemon but it also seems like a good way to limit coupling. As far as design goes is this a good way to go about doing it, if not what are some better methods to go about doing it? </p>

答:
I believe that if you have a base pokemon type, it may be easier to derive only the fire,water,electric types from the base class to limit the number of different classes needed. From that, you can set the relationships between the pokemon types without too much hassle, eg. Fire beats water and grass, weak to electric etc.

From there  you can probably have a database or JSON/XML file that stores all of the stats of each pokemom, ID, name and which evolution it is from. This format could definitely help with grouping and classing the data without much overhead at all. The data can then be pulled by each pokemon type class once the program initializes by reading the JSON/XML file in sequence. A whole lot of that process can be automated once you've set up all of the stats in the file-store. From there, accessing each pokemon should be simples!

Title: Good design for a recreation of pokemon


答:
do different pokemons should expose different APIs in your code? You should analyze this first.

Their ID, name & type can be stored in members. Now you could say that they have different abilities. So each ability should be a method. But you would be wrong. Doing so would prevent you from writing simple code when managing combat.

You should abstract an ability in a separate class. It may be defined by its cost & effect. Then each creature has a List of ability. Your 151 pokemons are defined in a service method or a config file. When writing features, the code should never care what type of pokemon is passed.

151 class for modeling something is a huge complexity cost. Most likely, you would have to use reflection to inspect data relevant to one particular class. This would be a misuse of the java class system.

Title: Good design for a recreation of pokemon

Body: I'm currently working on a group project to recreate the original Pokemon Yellow version in Java. We've only just started planning it out but they way we've drawn out the design right now is to have an abstract Pokemon class and have 151 (Count of the original Pokemon) classes that extend it, each one being a different Pokemon. Each class will be able to store data such as an ID, its name, the type of Pokemon it is (ie: rock/water/fire/etc), and the moves it can use and learn. It seems a little much to be creating 151 classes for the Pokemon but it also seems like a good way to limit coupling. As far as design goes is this a good way to go about doing it, if not what are some better methods to go about doing it? </p>


答:
I'm not sure why you would need 151 separate classes to store the data for each Pokémon.

If I'm reading your intent correctly, you want to have 151 classes, one to store the base data for each species of Pokémon (ostensibly as static data for the class). But this is hopelessly inelegant. If you just need a structure to store the base data for each Pokémon, why not have something like a PokemonBaseData class?

You could structure it like this (forgive me if the syntax is incorrect, my Java is a little rusty):

```<code>public class PokemonBaseData {

    public int ID;
    public int type1, type2;
    public int height_cm, weight_hg;
    public int base_HP, base_AT, base_DF, base_SA, base_SD, base_SP;
    public Vector<Integer> usable_moves; // or move IDs
    // other properties as you desire them here

}
</code>```

And have each Pokémon of a certain species ID refer to the PokemonBaseData class with a matching ID for the data inherent to that species.

Title: Good design for a recreation of pokemon

Body:
I'm not sure why you would need 151 separate classes to store the data for each Pokémon.

If I'm reading your intent correctly, you want to have 151 classes, one to store the base data for each species of Pokémon (ostensibly as static data for the class). But this is hopelessly inelegant. If you just need a structure to store the base data for each Pokémon, why not have something like a PokemonBaseData class?

You could structure it like this (forgive me if the syntax is incorrect, my Java is a little rusty):

public class PokemonBaseData {

    public int ID;
    public int type1, type2;
    public int height_cm, weight_hg;
    public int base_HP, base_AT, base_DF, base_SA, base_SD, base_SP;
    public Vector<Integer> usable_moves; // or move IDs
    // other properties as you desire them here

}

And have each Pokémon of a certain species ID refer to the PokemonBaseData class with a matching ID for the data inherent to that species.


答:
You don't really explain why your group thought it would be a good idea to (hopefully) generate 151 classes, as "to reduce coupling" doesn't really make sense yet as you had no design or code and therefore no coupling.

Each class will be able to store data such as an ID, its name, the type of Pokemon it is (ie: rock/water/fire/etc), and the moves it can use and learn.

Change 'class' to 'instance' in that sentence and you get why you only need to create one Pokemon class: they all share the same properties. A derived class should add or implement properties (and / or methods) unique to that derivation.

If you define the properties of ElementType, Move and PokemonBase as such:

```<code>enum ElementType
{
    Fire = 1,
    Water = 2,
    Grass = 4,
    Rock = 8,
}

class Move
{
    int ID;
    string Name;
    ElementType ElementType;
    int BaseDamage;
}

class PokemonBase
{
    int ID;
    string Name;
    ElementType ElementTypes;
    List<Move> Moves;

    decimal HitPointsPerLevel;
    decimal AttackPointsPerLevel;
}
</code>```

Then your various instances only differ in what is in those properties. Your class and code should not care about that. A Pokemon that has the type Fire can be stored in exactly the same class as a Pokemon of type Water: they only carry a different value of their ElementTypes property.

You can now fill a list of Pokemon instances with their properties and moves, for example by loading a text file or reading from a database, in a format you like.

You can solve all those problems when loading the Pokemon. In the data source you can store additional properties, which in the case of "the moves it can use and learn" can be a relational table (or flat text equivalent) where you join Pokemon.ID, Move.ID and Level to each other (if memory serves me right, they learn a new move on reaching preset levels), storing it in a list or dictionary property in your Pokemon class.

Or perhaps while designing you thought you needed a different class to implement the fighting system differently for each Pokémon. You don't have to, as by combining the various properties you can give each instance its unique properties.

The problem of course starts when you realize that you actually have two types of Pokemon: a 'blueprint' for all Pokemon that can possibly occur in the game, and an actual Pokemon that a player carries, which has a Level, HitPoints, and so on, all properties depending on or calculated through the Level or based on the fact that the isntance is "in the game". You can implement those properties in a derived class:

```<code>class Pokemon : PokemonBase
{
    int Level;
    int MaxHitPoints;
    int HitPoints;

    // Stats, for example
    int Attack { get { return Level * base.AttackPointsPerLevel } };
    int Defense;

    // This method directly applies the attack results to the incoming Pokemon, by reference.
    int Attack(Pokemon other, Move attack)
    {
        int damageDone = (this.Attack * attack.BaseDamage) - defender.Defense;

        // TODO: http://bulbapedia.bulbagarden.net/wiki/Type_chart
        decimal modifier = CalculateEffectiveness(other, attack);
        damageDone *= modifier;

        other.HitPoints -= damageDone;

        return damageDone;
    }
}
</code>```

And all Pokemon instances can use it, without having to derive anything. The key is modeling your class and method so, that the actions you want to undertake on each of them can be applied to all combinations of types. You can also for exampla add a List<DamageOverTimeAttack> to a Pokemon to implement attacks that should stay active for a few turns, handling it in the Attack() method.

Now when a player encounters a new Pokemon, you might want create that from a Factory:

```<code>class PokemonFactory
{
    List<PokemonBase> _allPokemon;

    Pokemon GetPokemon(id, level)
    {
        blueprint = _allPokemon.Find(id);

        return new Pokemon
        {
            ID = blueprint.ID,
            Name = blueprint.Name,
            ...
            Level = level,
            ...
        };
    }
}
</code>```

Title: Good design for a recreation of pokemon

Body:
You don't really explain why your group thought it would be a good idea to (hopefully) generate 151 classes, as "to reduce coupling" doesn't really make sense yet as you had no design or code and therefore no coupling.

Each class will be able to store data such as an ID, its name, the type of Pokemon it is (ie: rock/water/fire/etc), and the moves it can use and learn.

Change 'class' to 'instance' in that sentence and you get why you only need to create one Pokemon class: they all share the same properties. A derived class should add or implement properties (and / or methods) unique to that derivation.

If you define the properties of ElementType, Move and PokemonBase as such:

enum ElementType
{
    Fire = 1,
    Water = 2,
    Grass = 4,
    Rock = 8,
}

class Move
{
    int ID;
    string Name;
    ElementType ElementType;
    int BaseDamage;
}

class PokemonBase
{
    int ID;
    string Name;
    ElementType ElementTypes;
    List<Move> Moves;

    decimal HitPointsPerLevel;
    decimal AttackPointsPerLevel;
}

Then your various instances only differ in what is in those properties. Your class and code should not care about that. A Pokemon that has the type Fire can be stored in exactly the same class as a Pokemon of type Water: they only carry a different value of their ElementTypes property.

You can now fill a list of Pokemon instances with their properties and moves, for example by loading a text file or reading from a database, in a format you like.

You can solve all those problems when loading the Pokemon. In the data source you can store additional properties, which in the case of "the moves it can use and learn" can be a relational table (or flat text equivalent) where you join Pokemon.ID, Move.ID and Level to each other (if memory serves me right, they learn a new move on reaching preset levels), storing it in a list or dictionary property in your Pokemon class.

Or perhaps while designing you thought you needed a different class to implement the fighting system differently for each Pokémon. You don't have to, as by combining the various properties you can give each instance its unique properties.

The problem of course starts when you realize that you actually have two types of Pokemon: a 'blueprint' for all Pokemon that can possibly occur in the game, and an actual Pokemon that a player carries, which has a Level, HitPoints, and so on, all properties depending on or calculated through the Level or based on the fact that the isntance is "in the game". You can implement those properties in a derived class:

class Pokemon : PokemonBase
{
    int Level;
    int MaxHitPoints;
    int HitPoints;

    // Stats, for example
    int Attack { get { return Level * base.AttackPointsPerLevel } };
    int Defense;

    // This method directly applies the attack results to the incoming Pokemon, by reference.
    int Attack(Pokemon other, Move attack)
    {
        int damageDone = (this.Attack * attack.BaseDamage) - defender.Defense;

        // TODO: http://bulbapedia.bulbagarden.net/wiki/Type_chart
        decimal modifier = CalculateEffectiveness(other, attack);
        damageDone *= modifier;

        other.HitPoints -= damageDone;

        return damageDone;
    }
}

And all Pokemon instances can use it, without having to derive anything. The key is modeling your class and method so, that the actions you want to undertake on each of them can be applied to all combinations of types. You can also for exampla add a List<DamageOverTimeAttack> to a Pokemon to implement attacks that should stay active for a few turns, handling it in the Attack() method.

Now when a player encounters a new Pokemon, you might want create that from a Factory:

class PokemonFactory
{
    List<PokemonBase> _allPokemon;

    Pokemon GetPokemon(id, level)
    {
        blueprint = _allPokemon.Find(id);

        return new Pokemon
        {
            ID = blueprint.ID,
            Name = blueprint.Name,
            ...
            Level = level,
            ...
        };
    }
}


问:
Why "mainstream language" is so opposed to "built on a small core of orthogonal features"?
On "hammerprinciple.com" website there are programming languages, statements about them and voting that associates languages with statements.

In particular, there are statements:

"This language is built on a small core of orthogonal features"

"This is a mainstream language"

Why they are so opposed to each other? Is being incoherent, history-encumbrant, ridden with extra special cases a must for being popular, "mainstream" programming language?

Maybe is it similar reason as why beautiful and coherent artificial natural languages (like Esperanto) are not that popular?

答:
"Small, orthogonal features" is brilliant in a teaching language. It is something I want, in a language I write production code in.

But, I also value "there are good standard libraries" and "I can get stuff done quickly", where there is a strong correlation between a "lack of good standard libraries" and "small orthogonal language". There is a weak correlation between "get stuff done quickly" and "small orthogonal", but a massive anti-correlation between "get stuff done" and "lack of libraries".

Some small, orthogonal languages also take their "purity" (for want of a better word) one or two steps too far, so while purer and cleaner, untainted by practical considerations, they actually end up being harder to write code in.

When I say "production code" and "code", I mean code bases of 100k lines and more.


答:
Why designed natural languages are not common

There are three reasons why you learn a natural language:

Your parents or environment speak a language, and you naturally try to understand what they are talking about.

Your school requires you to learn a couple of foreign languages.

ohmygosh {Esperanto,Quenya,Klingon,Lojban} is awesome because I am {interested in linguistics,a {LoTR,Star Trek} fan}.

As it happens, the languages you'd learn under point 3 are ususually not spoken in public or at home, and are not taught in school in place of French or Spanish. Therefore, they are all very niche.

Correlation does not imply causation

Oh wow, so A and B seem to have some correlation. Does A cause B? Or the other way round? Or are there other factors that I didn't consider?

Your question seems to ask if a programming language can only become mainstream if it is not orthogonal. This is misleading.

Languages evolve

Languages change over time. Their standard library gets reworked. New syntax is added. Object orientation is made available. Lambda expressions start looking useful. But closures and objects can be implemented in terms of each other, so why would I need both? Why would I want generics or other type system additions? I clearly do not need them…

A language that does not evolve is probably dead.

Some languages are made to get the the job done

For some languages, practicality is of utmost importance. It doesn't matter if there are five or more screwdrivers in my toolbox, because not all screws are equal. An experienced user will pick the right one for the situation.

Other languages strive to be more minimal and/or elegant. This can be useful for didactic purposes, or in research settings. Small languages are easier to port. They are often useful, but not always when you have to ship your application yesterday.

Market Share is Ballast and Obligation to Move On

A language that tries to be relevant tomorrow has to keep evolving, and include new concepts. For example, the C++ standard is slowly but constantly being reworked. Each release of Java is a step forward. C# is often ahead of the pack as far as mainstream languages go. A language like SML or Smalltalk has no serious ambitions to go mainstream.

A language that already is widely used has to stay backwards compatible, or it will loose market share. Features that were there yesterday have to stay available even if a better alternative was introduced. In Java, type parameters are erased during compilation for back-compat. In PHP, the main namespace is riddled with dangerous and deprecated functions that can't be removed without breaking a good part of the internet.

Conclusion

I would suggest that successful languages tend to become less orthogonal over time, not only that less orthogonal languages tend to become mainstream more easily. However, there is no clear causation because there are more factors to consider.

If I look through the list of languages you linked to we see as orthogonal languages: Scheme and Lua had minimalism as a design goal, academic languages like Coq, Haskell, SML are less useful for day-to-day programming or difficult to learn, and some languages like Forth and APL are barely used any longer.

The less orthogonal languages are all quite mainstream, or have a long history. Fortran and COBOL are ancient, but still have a strong niche. Languages like PHP and Shell grew beyond what they where intended to do. Some languages are explicitly pluralistic, e.g. Perl and its descendant Ruby. The C# language is in direct competition to Java and tries to score with better features. Some languages have a religious commitment to backcompat, e.g. C++ or Perl.

Title: Why "mainstream language" is so opposed to "built on a small core of orthogonal features"?

Body:
On "hammerprinciple.com" website there are programming languages, statements about them and voting that associates languages with statements.

In particular, there are statements:

"This language is built on a small core of orthogonal features"

"This is a mainstream language"

Why they are so opposed to each other? Is being incoherent, history-encumbrant, ridden with extra special cases a must for being popular, "mainstream" programming language?

Maybe is it similar reason as why beautiful and coherent artificial natural languages (like Esperanto) are not that popular?


答: Have you considered the flyweight pattern? That would allow you to avoid creating the 151 classes and still have the required functionality.</p>

Title: Good design for a recreation of pokemon


问:
Worst coding standard you've ever had to follow?
Have you ever had to work to coding standards that:

Greatly decreased your productivity?

Were originally included for good reasons but were kept long after the original concern became irrelevant?

Were in a list so long that it was impossible to remember them all?

Made you think the author was just trying to leave their mark rather than encouraging good coding practice?

You had no idea why they were included?

If so, what is your least favorite rule and why?

Some examples here

答:
Not really a coding standard, but we had a file in source control called 'changelog.txt'

Every time you made a checkin, you had to manually add an entry to this file. This entry was the subversion revision number and your checkin comment.

When the new CTO started and someone told him this, he promptly made an executive decision and said, "We're not going to do this anymore" and deleted the file. This had been going on for years.


问:
Multiple roles in Ruby On Rails
I've been asked to put together an application in RoR which has multiple roles for users. The idea is that a user will have a role, Admin, Moderator, User ect... and they will also have a department as well, HR, IT, Customer Care ect....

The app will have designated sections for each department to manage data and other basic CRUD based tasks.

What the app needs to allow is so a user can only access departments they are assigned to, a user can have multiple departments, a user can be a Admin of one department but may be only a user of another department.

Whats the best way of putting something like this together?

答:
There is an n:m relationship between users and departments and another n:m relationship between users and roles. Each of these relationships could be represented by its own table in the DB. Assuming that each user object has an ID, you can query the database during the authorization to see whether an appropriate relationship exists. This could be checked by an authorization manager, but it would be good UX to not even display links to resources which an user is not authorized to use.

If you need to store this information inside your objects (which I'd rather not, because of the single-responsibility principle), each user would have a set of roles or departments. Each role/department would be a singleton object, so one could do (pseudocode:) user.roles.contains?(Role.admin).

Title: Multiple roles in Ruby On Rails


问:
Notify client about changes in database in Java
I'm working on a distributed client-server system that uses TCP. The program's functions is to transfer money to an from the server, but also between the clients, a sort of MobilePay.

When one client wishes to transfer money to another client, that client will need to accept the transfer before it is succeeded (one of the systems requirements).

So, my problem is, I would like the client to get notified (preferably through a message dialog) whenever a transfer is ready to get accepted. All the payments/transfers is stored in a SQL table. I would like the client to get notified when there is a pending payment/transfer in his/hers name, that is, when a new row (with the clients name as receiver) in the transfer table is added, in stead of the client needing to actively see if there is any pending payments (as it is now).

Can anybody help me how to get around this problem?

答:
There's likely a few layers to this solution. I'm assuming of course that the client isn't connected directly to to the database and there's at least one or more application layers in between. Between the client and application server, using a pub/sub protocol like STOMP of AMQP should fit the bill.

Triggering notifications from the database is a bit trickier. Most of the approaches tend to be database specific. If you're using Oracle, you can set up register for data change notifications, and your application and respond to the event. Most likely, you'll need to transform the notification into a meaningful business event before sending that notification to the client.

A slightly less sexy version would be to create an event log table that tacks the changes to the payment/transfer tables. Then create a small process to poll this table and fire events when new data is found and then create a message that is published over your pub/sub layer. Not as sexy as something like Oracle's DCN, but it works.


问:
Can you be Agile without doing TDD (test driven development)?
Is is possible to correctly call yourself (or your team) "Agile" if you don't do TDD (Test-Driven Development)?</p>

答:
I say

No [sort of]

If you go back to the original source http://en.wikipedia.org/wiki/Extreme_Programming TDD is fundamental to the process; the tests replace the requirements specifications and use-cases of waterfall, serve as living documentation and functioning examples, etc. They're indispensible.

However, there's so many different flavors of 'agile' floating around now that it's entirely possible that one of them eschews TDD

EDIT: @Murph's interpretation of the question seems to be the preferred one. Heck I even upvoted it, it's a good answer. However, I maintain my position that the Agile Manifesto is a set of principles, not a development methodology. I see no use in saying "oh yes I'm agile" without actually implementing the practices that bring the benefits. In particular:

Working software is the primary measure of progress.

and

Agile processes promote sustainable development.
The sponsors, developers, and users should be able
to maintain a constant pace indefinitely.

To me, these two principles imply if not require TDD - at least I know of no other way to achieve them without it!

EDIT 2: yes, technically you can write the tests afterwards; but I still regard test-first/TDD as fundamental. Not because you can't "be agile" without it, but because you will be more agile with it. Test-first/test-driven is a far more efficient approach than test-later/test-afterthought. The test descriptions are the requirements. Don't put them off until later ;-)

EDIT 3: I finally figured out what bothers me so much about Murph's very well-written answer. It's that notion that one could "be Agile" without actually doing it. And "doing it" (as shown above) pretty much requires TDD.


问:
Zend Framework 2 - Keeping all the models and mappers in Application module?
I am in process of planning web application by following the best practices and approaches of software development. I am building this application using zend framework 2 and going through its documentation and best practices of building applications through zend framework 2 and MVC patterns.

Right now I am confused about where to keep my model layers. So far all the applications I have developed using Zend I used to keep my model layers in application module because I think models are not related to single module and a single module may communicate with multiple models. Also in Zf2 modules gets loaded only when it is requested except the Application module which loads with every request despite which module is requested. If I place my models in the specific modules and load them in the service config of there relative modules. I will not be able to use them in other modules.

So what should I do?

答:
You should not get worry about how the models will load. Zend Framework 2 is 'engineered' in modular way,  what I want to say here is that it uses the famous design patterns (factory, dependency injection, service locater) and architecutral patterns to do the things. Remember, each module 'must be' cohesive in itself. And not coupled with any other module. Like the application module and your-other-module must implement their own models respectively to interact with the database. And in future if you replace your-other-module with some another-amazing-module, no other module would be disturbed.

At the end app runs, it integrates all the configurations in each module in one configuration and thus it works. Yes, it integrates all the end, but the framework is made to be modular and maintainable for long-lasting and separated chunks. You may use the chunks in your app or use whole MVC stack.

Thats why also a developer of Yii and CI, i feel Zend Framework 2 is most less forcing developers to use something and giving you so many choices. It may not be quick to develop apps in it but it is very flexible and a master piece.


问:
What are the set of skills that every programmer graduating from college should have?
We had a guest lecturer at our school he went on a tangent regarding those graduating and not being upto the skill level he expects ie. knowledge of one big-time compiled languague like Java, C++ or C#, one scripting language like Python or Ruby, one web framework. What are some other skills that you guys think should be absolutely critical to graduating student?</p>

答: By far, I would say an eagerness to learn.  College isn't really intended to give you the skills you need to become a programmer.  It's intended to teach you the skills you need to learn those skills.

OwnerDisplayName: Wallz


问:
Does changing the name of a namespace count as a MAJOR change in semantic versioning?
I'm writing a C++ library, and
according to this site here: http://semver.org/,

I should increment the MAJOR version when I make incompatible API changes.

Is changing the name of a namespace considered an incompatible change in the API?  I'm not quite sure. I don't know whether I should increment the MAJOR or MINOR version number.

答:
(pasted from my comment)

When a dev updates to the new version of your library – can he compile his own code without any changes? If yes, you have a minor change.

But if he does have to update the code – e.g. using your_namespace; or new your_namespace::foo() – then this is a major, incompatible change, which should be denoted by incrementing the major version number.

An interesting way around such problems is to not only version your library but also the API itself. This way, a newer library version can also be used under an old interface – which does not offer the newer features.


问:
Compiler doesn't inline anything?
I've rolled my own SIMD-accelerated math library. It's gotten pretty complete, so naturally I went to conduct speed tests and optimize it.

Btw this isn't premature optimization, the lib is actually complete in functionality, I really need it to be fast now.

So anyway, I'm testing some vector dot product methods against the ones in Microsoft's DirectXMath. The difference between my vectors and the ones in DirectXMath is, that in DirectXMath XMVECTOR is just a naked __m128, while mine is a __m128 inside a vector_simd class that is 16 byte aligned and with an aligned allocator.

Now one would assume that with all possible optimizations enabled in release mode they would compile to the same thing. I mean int a; and int arr[1]; compile to the same thing in release mode, just like my array template class has the same performance as a raw array and so on... but to my surprise my class's methods came up 2 times slower. I even tried just pasting the SSE code from DirectXMath into my class's method, it still came out slower. So the only thing left was the difference that one is a class and the other is raw.

It seemed for a while that the overhead of accessing it as a class member and/or the extra overhead from the constructor (which is empty...). However I put all the definitions of my vector class methods in it's header and still it came up 2x slower than DirectXMath.

Maybe the overhead comes from the __m128 being a class member?

I don't understand why the compiler can't optimize that away, it's like having a struct with a single integer in it?Has anyone else had such issues?

EDIT: OK, so it seems that my vector_simd class is 32 bytes, while __m128 is only 16 bytes, which is strange. When I removed the 16-byte alignment from my class it also became 16 bytes large. But this makes no sense, aligning a 16-byte class to 16 bytes should make it remain 16 bytes....

答:
Working out why code is slower can be exceptionally difficult, but for a gross difference like a doubling of execution time, you can get a good idea of at least where to start looking by using a profiler. You need to particularly be aware of anywhere where data is copied around, especially inside a loop; that can easily get expensive. (I'd suggest a tool like cachegrind, but I don't know if it is available for your platform.)

Alignment problems are actually easier to detect and fix. In particular, if you have a structure like this:

```<code>struct {
   eightByteQuantity a;
   eightByteQuantity b;
};
</code>```

Setting its alignment to 16 bytes easily force the alignment of each of the members to be on a 16-byte boundary, doubling the effective size. Be aware that the size of things like vtable pointers must also be paid for.

Title: Compiler doesn't inline anything?

Body:
Working out why code is slower can be exceptionally difficult, but for a gross difference like a doubling of execution time, you can get a good idea of at least where to start looking by using a profiler. You need to particularly be aware of anywhere where data is copied around, especially inside a loop; that can easily get expensive. (I'd suggest a tool like cachegrind, but I don't know if it is available for your platform.)

Alignment problems are actually easier to detect and fix. In particular, if you have a structure like this:

struct {
   eightByteQuantity a;
   eightByteQuantity b;
};

Setting its alignment to 16 bytes easily force the alignment of each of the members to be on a 16-byte boundary, doubling the effective size. Be aware that the size of things like vtable pointers must also be paid for.


问:
How does a chess engine decide what move to make?
I'm writing a simple chess engine in LISP. I actually know how the engine decide the move, it evaluates and reads some opening books. But that's not what i mean. This is my design.

```<code>57 58 59 60 61 62 63 64
49 50 51 52 53 54 55 56
41 42 43 44 45 46 47 48
33 34 35 36 37 38 39 40
25 26 27 28 29 30 31 32
17 18 19 20 21 22 23 24
09 10 11 12 13 14 15 16
01 02 03 04 05 06 07 08
</code>```

I looked at more  complicated solutions but i came out with what i believe is the simplest one. Say the bishop is on the square 23, it could move 4 possible moves, (to  16 or 14 or 32 or 30), so  it moves -7 or +7 or +9 or -9.

I create an array

```<code>(make-array '(8 8) :initial-contents
'((R B N Q K B N R)
 (P P P P P P P P)
(NIL NIL NIL NIL NIL NIL NIL NIL)
(NIL NIL NIL NIL NIL NIL NIL NIL)
(NIL NIL NIL NIL NIL NIL NIL NIL)
(NIL NIL NIL NIL NIL NIL NIL NIL)
          (P P P P P P P P))
          (R B N Q K B N R)))
</code>```

And move the pieces from index to index. My question is, i cannot simply tell the bishop to move +7 or whatever, if it's an open diagonal. I need to tell it to move +9 * 1  or +9 * 2 etc. and you bishop have to decide which one to go to. I cannot write a condition and a loop for every possible square

答:
As @MichaelT pointed out, you should read up on minimax search and alpha-beta pruning.

The issue here is algorithmic, and has almost nothing to do with design. At each turn you have some number of possible moves. For each of your possible moves, your opponent has some number of moves of her own. This generates the game tree that you need to search. At each node you need to be able to evaluate the position of the board to determine which outcome is most advantageous for you.  The algorithm to search such trees is called minimax search. The way to avoid having to search the entire tree is called alpha-beta pruning.


问:
Using multiple Git repositories instead of a single one containing many apps from different teams?
I am migrating a 10-years-old big CVS repository to Git. It seemed obvious to split this multiple-projects repository into several Git ones. But the decision-makers are used to CVS, therefore their point of view is influenced by CVS philosophy.

To convince them to migrate from one CVS repo to different Git repositories I need to give them some arguments.

When I speak with mates working on Git repo for years, they say that using multiple Git repo is the way to use Git. I do not know really why (they give me some ideas). I am a newbie in this field so I ask here my question.

What are the arguments to use multiple Git repositories instead of a single one containing different applications and libraries from different teams?

I have already listed:

branches/tags impact the whole Git repository files => pollutes other team projects

4GB limit Git repo size but this is wrong

git annotate may be slower on bloat Git repo...

Eamon Nerbonne has noticed the related question:

Choosing between Single or multiple projects in a git repository?

The reason the team managers finally have accepted the split: the single Git repo (550 MB) was requiring 13 minutes to be cloned on Windows (one minute on Linux).

The bloat CVS repo split in 100 Git repositories:

each dead apps in one repo

each stabilized library in one repo (source code almost never changed any longer)

related apps/libs kept together in one repo

moved large files not used for compilation (config...) to other repos (Git does not like large files)

skipped other unrelevant files (*.jar, *.pcb, *.dll, *.so, *.backup ...)

Successfully installed the repo tool used by Android Open Source Project in order to handle all these Git repos:

easy installation on Linux

more difficult on Windows because of Cygwin and NTFS native symlinks requirements

答:
Git operates on a whole tree at once, not on just the subdirectory you're on.

Let's say you have your project at

```<code>C:\MyCode\ProjectABC
</code>```

And let's say these two files have changed:

```<code>C:\MyCode\ProjectABC\stuff.txt
C:\MyCode\ProjectABC\Stuff\MoreStuff\morestuff.txt
</code>```

When you're in the project root and you do a git status, you'll see these files as having changed:

```<code>stuff.txt
Stuff\MoreStuff\morestuff.txt
</code>```

If you cd to the MoreStuff directory, though, will you see only the morestuff.txt file?  No.  You'll still see both files, relative to your position:

```<code>..\..\stuff.txt
morestuff.txt
</code>```

As a result, if you lump all your projects together in one big ol' Git repository, then every time you go to check in, you'll have to pick from among changes in every project.

Now there could be ways to mitigate that; for instance, you can try to make sure you at least temporarily commit your changes before switching to work on a different project.  But that's a lot of overhead that each person on your team would have to deal with, compared to simply doing it the right way: one Git repository per project.

Body:
Git operates on a whole tree at once, not on just the subdirectory you're on.

Let's say you have your project at

C:\MyCode\ProjectABC

And let's say these two files have changed:

C:\MyCode\ProjectABC\stuff.txt
C:\MyCode\ProjectABC\Stuff\MoreStuff\morestuff.txt

When you're in the project root and you do a git status, you'll see these files as having changed:

stuff.txt
Stuff\MoreStuff\morestuff.txt

If you cd to the MoreStuff directory, though, will you see only the morestuff.txt file?  No.  You'll still see both files, relative to your position:

..\..\stuff.txt
morestuff.txt

As a result, if you lump all your projects together in one big ol' Git repository, then every time you go to check in, you'll have to pick from among changes in every project.

Now there could be ways to mitigate that; for instance, you can try to make sure you at least temporarily commit your changes before switching to work on a different project.  But that's a lot of overhead that each person on your team would have to deal with, compared to simply doing it the right way: one Git repository per project.


问:
PHP SplFixedArray How To Deal With billions of indexes?
I've built a flatfile db system that will work like mini-noSQL system
and it split db to smaller files, and I did a SplFixedArray wrapper for it
with a method for searching usage built on preg_grep.

Everything working very good till now, but if the array became more than billions of indexes how to handle it? When searching it, it will iterate over the small files then get the matches and put it in a temporary fixedArray so, what if it found very large matches?

How the noSQL dbms do that?

NOTE: If you wonder why I do that without a real noSQL solution, I'll say because I want to know more.

答:
Generally a buffer is used for this sort of operation, often a FIFO (First In, First Out) data structure where when new information comes in that would be beyond the buffer capacity, the oldest (first) info in the buffer is purged out to make room for the new data.

This is sort of like reading a file line by line, outputting the results wherever you want them, and then reading the next line. The same goal is sought - to avoid crashing your script due to excess memory usage.

So, what happens when you have a dataset that is just too big to keep in memory? In short - you can't continue. You either need to stop the work and return something like "result set too large - here are first n occurrences", or you need to output the results to a file or some such that lets you get things out of RAM so you can keep working.

A canonical example has become SAX vs DOM in XML processing. When data sets are large, the downside is that you lose the simplicity and convenience of being able to just shove everything into RAM and not worry about it. It almost always requires a shift in the strategy and coding techniques to handle such problems.

"He who increaseth in raw data, increaseth in coding complexity." - computerized Proverb


答:
As an employer, I will only employ people as programmers who:

Have experience of single stepping through code.

Can select an appropriate design patern
to solve a simple specific problem.

Can implement code that reflects
their chosen design patern.

In my experience, less than 5% of computer science graduates applying for programming jobs actually have these skills, at a basic level. These are the minimum skills that are needed to be commercially useful, and importantly, not everyone is capable of learning these skills.

Other nice to haves are:

Experience of working on a team
project

Use of source control

Experience of Unit testing

These make their integration with the existing development team easier, but are subjects that can normally be taught on the job.

Title: What are the set of skills that every programmer graduating from college should have?

Body: We had a guest lecturer at our school he went on a tangent regarding those graduating and not being upto the skill level he expects ie. knowledge of one big-time compiled languague like Java, C++ or C#, one scripting language like Python or Ruby, one web framework. What are some other skills that you guys think should be absolutely critical to graduating student?</p>


问:
computing whether service level times are met
For a ticket reporting tool, I want to compute whether certain service level times (slt) are met. That is (a bit simplified): Was the timespan between opening and closing of the ticket within a certain slt. Now there is also something called a service window (SW), like mo-fr,9:00-17:00. Now to compute whether a slt was met, times not within the SW have to be excluded. Even though not forseen, tickets can be opened or closed outside the SW, since there are other sla wich allow for 24x7 service. An engineer could work on a ticket outside the SW, since it might be easier for him to close a ticket while he is at it. Maybe he was doing work on a related ticket.

In order to determine the time a ticket took between opening and closing time, I though of two algorithms:

1) Distinguish all possible combinations of start_date and end_date beeing within or outside the SW, on different days and so on (I see 8 combinations). Then for each combination, set up a seperate formula to compute the time the ticket took.

Plus: little computational overhead

Minus: Rather complex, lots of code

2) Decide for a smallest possible unit (minutes seem to be apropriate), then for each unit between start_date and end_date, decide whether this unit is inside or outside the SW. If inside, add to the time the ticket took.

Plus: very simple

Minus: big computational overhead.

I am leaning towards 2) since compuation is cheap, simple code is to be preferred, and the rest of the programm contains lots of time consuming db queries, so a little computation will not be noticable.

However, both solutions seem not very elegant to me. Does anyone see a third way?

答:
Here is how I would probably solve the problem:

if the start date is outside the service window, change it to the next following date/time combination which is inside. Note that this change won't affect the final result.

same for the end date

Let T1 be the time span between start and end date (in an arbitrary unit)

Let T2 be the sum all non-service-time intervals between start and end date. Note that this calculation is now very easy due to the change in the first two steps

T1-T2 ist the result you are looking for


问:
What is the benefit of switching on Strings in Java 7?
When I was starting to programme in Java, the fact that switch statements didn't take strings frustrated me. Then on using Enums, I realised the benefits that you get with them rather than passing around raw values — type safety (which brings easier refactoring) & also clarity to other developers.

I'm struggling to think of a situation where with SE7 I'll now decide to use a switch with strings as inputs rather than Enums. If they are implemented via switching on whole strings (e.g. rather than partial or regex matches), it doesn't seem to offer less reason for the code to change.

And with IDE tools and the read-write ratio of coding, I'd be much happier auto-generating an extra Enum than passing around string values.

What benefit do they bring to us as programmers? Less boiler-plate?

It doesn't feel like the language was crying-out for this feature. Though maybe there's a use-case I'm overlooking.

答:
Most improvements in any language are to make the code easier to read. I favor readable code over fancy any day.

You may not believe this but try:

```<code>public enum JettStaff {
  ADRIAN("Adrian German") {
    public String toString() {
      return name + " (dgerman@indiana.edu)";
    }
  },
  ARJIT("Arjit Sengupta") {
    public String toString() {
      return name + " (asengupt@indiana.edu)";
    }
  },

  // and on for the rest...

  private String name;

  public JettStaff(String n) { this.name = n; }
}

JettStaff x = JettStaff.SUZANNE;
System.out.println(x);
</code>```

OwnerDisplayName: anotherdave

Body:
Most improvements in any language are to make the code easier to read. I favor readable code over fancy any day.

You may not believe this but try:

public enum JettStaff {
  ADRIAN("Adrian German") {
    public String toString() {
      return name + " (dgerman@indiana.edu)";
    }
  },
  ARJIT("Arjit Sengupta") {
    public String toString() {
      return name + " (asengupt@indiana.edu)";
    }
  },

  // and on for the rest...

  private String name;

  public JettStaff(String n) { this.name = n; }
}

JettStaff x = JettStaff.SUZANNE;
System.out.println(x);


答:
Simplicity

String in Switch support are useful for processing data without conversion to enum or if-else logic. Sometimes is just easier to switch on String.

From feature proposal at JDK 7 (project Coin) mailing list (@gnat answer)

introducing an enum for its switchable constants, one per string value of interest, would add another type to a program without good cause...

If-Else version

This is short, but many if's are hard to read. And this is slow.

```<code>if (color.equals("red")) {
    System.out.println("Color is Red");
} else if (color.equals("green")) {
    System.out.println("Color is Green");
} else {
    System.out.println("Color not found");
}
</code>```

Enum version

Enums need to be defined, this is good, but sometime not needed.

```<code>enum Color {RED, GREEN}
</code>```

Processing as usual

```<code>try {
    switch (Color.valueOf(color)) {
        case RED:
            System.out.println("Color is Red");
            break;
        case GREEN:
            System.out.println("Color is Green");
            break;
    }
} catch (IllegalArgumentException e) {
    System.out.println("Color not found");
}
</code>```

JDK 7 - Strings in switch Statements version

We can process without converting and defining additional types.

```<code>switch (color) {
    case "red":
        System.out.println("Color is Red");
        break;
    case "green":
        System.out.println("Color is Green");
        break;
    default:
        System.out.println("Color not found");
}
</code>```

Title: What is the benefit of switching on Strings in Java 7?

Body:
When I was starting to programme in Java, the fact that switch statements didn't take strings frustrated me. Then on using Enums, I realised the benefits that you get with them rather than passing around raw values — type safety (which brings easier refactoring) & also clarity to other developers.

I'm struggling to think of a situation where with SE7 I'll now decide to use a switch with strings as inputs rather than Enums. If they are implemented via switching on whole strings (e.g. rather than partial or regex matches), it doesn't seem to offer less reason for the code to change.

And with IDE tools and the read-write ratio of coding, I'd be much happier auto-generating an extra Enum than passing around string values.

What benefit do they bring to us as programmers? Less boiler-plate?

It doesn't feel like the language was crying-out for this feature. Though maybe there's a use-case I'm overlooking.

Body:
Simplicity

String in Switch support are useful for processing data without conversion to enum or if-else logic. Sometimes is just easier to switch on String.

From feature proposal at JDK 7 (project Coin) mailing list (@gnat answer)

introducing an enum for its switchable constants, one per string value of interest, would add another type to a program without good cause...

If-Else version

This is short, but many if's are hard to read. And this is slow.

if (color.equals("red")) {
    System.out.println("Color is Red");
} else if (color.equals("green")) {
    System.out.println("Color is Green");
} else {
    System.out.println("Color not found");
}

Enum version

Enums need to be defined, this is good, but sometime not needed.

enum Color {RED, GREEN}

Processing as usual

try {
    switch (Color.valueOf(color)) {
        case RED:
            System.out.println("Color is Red");
            break;
        case GREEN:
            System.out.println("Color is Green");
            break;
    }
} catch (IllegalArgumentException e) {
    System.out.println("Color not found");
}

JDK 7 - Strings in switch Statements version

We can process without converting and defining additional types.

switch (color) {
    case "red":
        System.out.println("Color is Red");
        break;
    case "green":
        System.out.println("Color is Green");
        break;
    default:
        System.out.println("Color not found");
}

OwnerDisplayName: MariuszS


答:
Switch for strings could be used when your enum values come from outside, i.e. stored in a database.

Another notable thing in JDK 7 switch is that it's much more perfomant than if-else constructs.

And a nice use case for speedy string switches could be JSON/XML stream parsing when you need to make a lot of switches on node and attribute types. I can't think of any better option for this.

OwnerDisplayName: Andrey Chaschev


答:
Apart from making the code more readable, there are potential performance gains relative to if/else if comparisons.  Whether the change is worthwhile depends on how many comparisons you would be making.  A string switch will be emitted as two separate switch instructions.  The first operates on hash codes, so it tends to be a lookupswitch, ultimately yielding O(log n) complexity.  The second is always a perfect O(1) tableswitch, so the combined complexity is still O(log n).  A single, linear chain of if/else if statements would give slightly worse O(n) complexity.

If you're comparing more than, say, three strings, then a switch is probably more readable and compact.  It will likely perform better, though you are unlikely to notice a difference unless you are doing a large number of comparisons on a hot code path.

OwnerDisplayName: Mike Strobel


答:
Enums are great and you should use those instead of Strings when you have an ability to do so. But there are some times when you just couldn't, for example when you need to work with some external object coming from outside of Java. Imagine that you have to parse something. Like server response, configuration, log file or something similar: you have a bunch of options that you're looking for and there is no way those could be enums. So in Java < 7 you'd be stuck with a bunch of

```<code>  if (something.equals("foo")) {
    // foo processing
  } else
  if (something.equals("bar")) {
   // bar processing
  }
</code>```

You can still use enums in this case by just trying to get those by names and/or by providing custom String->Enum routine but sometimes it's not possible or just not practical (i.e. when you'd have to create too many enums)

TLDR: you absolutely should use Enums when you are working purely with Java code but it's not always possible with external objects. I hope my explanation makes sense.

Body:
Enums are great and you should use those instead of Strings when you have an ability to do so. But there are some times when you just couldn't, for example when you need to work with some external object coming from outside of Java. Imagine that you have to parse something. Like server response, configuration, log file or something similar: you have a bunch of options that you're looking for and there is no way those could be enums. So in Java < 7 you'd be stuck with a bunch of

  if (something.equals("foo")) {
    // foo processing
  } else
  if (something.equals("bar")) {
   // bar processing
  }

You can still use enums in this case by just trying to get those by names and/or by providing custom String->Enum routine but sometimes it's not possible or just not practical (i.e. when you'd have to create too many enums)

TLDR: you absolutely should use Enums when you are working purely with Java code but it's not always possible with external objects. I hope my explanation makes sense.

OwnerDisplayName: dimoniy


答:
I don't agree with the opinion that it's cleaner and readable code when you use Strings in switch statements and think that it's a bad programming practice. If you change the value that you use to store, you have to change it every switch or if-elseif occurance. This is not good since you're putting hardcoded values to every bir of your code. What are you going to do if one day you decide to change one of these hard coded values? Search and replace every copy of it?

If you have some hardcoded values that you do if-elseif statements, using constant primitive values for them is much better in prior to Java 1.5 just because it brings type safety.

OK, there will be situations you'll get String values (from HTTP Request, files etc.) and converting them to the primitive values is a lof of pain. But Enums do a good job at this point. Because when you want to change the value you store in Enum, just change it when you declare. There is no need to change anything else in your code. (You of course need to change the values stored somewhere else).

Of couse if you're just implementing a dirty and lazy code, it's perfect. You don't want to involve to code lots of Enums, but in a big scale complex software that'll kill you.

OwnerDisplayName: regulus


答:
If you know what information coming in and that it could only be of 5 states then use an Enum. However if the possible states could be over 9000 and you only need to find 42, then using a switch is better because you don't want to be typing all those states out.

An Enum tends to be the choice by most in most circumstances unless where the possible states are unknown or there are a lot and you only care about a few.

But why they introduced it now? It was just a change that allowed for cleaner code.

In 1.5 they also allowed you to create custom bodies for Enums as well.