问:
Good architecture for user information on separate databases?
I need to write an API to connect to an existing SQL database.  The API will be written in ASP.Net MVC3.

The slight problem is that with existing users of the system, they may have a username on multiple databases.

Each company using the product gets a brand new instance of the database, but over the years (the system has been running for 10 years) there are quite a few users (hundreds) who have multiple usernames across multiple "companies" (things got fragmented obviously and sometimes a single Company has 5 "projects" that each have their own database).

Long story short, I need to be able to have a single unified user login that will allow existing users to access their information across all their projects.

The only thing I can think is storing a bunch of connection strings, but that feels like a really bad idea.

I'll have a new Database that will hold the "unified user" information...can anyone suggest a solid system architecture that can handle a setup like this?

答:
Unifying the data

Since the authentication was independent between the five projects, you may encounter several inconsistencies:

Different identifiers. For example if the user identifiers are e-mail addresses, the same person can register with vanessa.kelley@example.com for one project, v.kelley@example.com for another one, and vanessa12345@example.com for a third one. It is practically impossible to solve this issue: you may have an idea through information aggregation¹, but it's not precise enough and may be insufficient in some cases².

Data standards inconsistency. What if both projects need to know where the user is, but the project 1 uses two letters convention, like CA, while the second one uses the full name, like Canada?

Different authentication implementations. For example, the project 1 uses SHA256, while the project 2 uses salt and SHA512 and the project 3 uses PBKDF2? In order to solve this issue, you'll need to store every hash used, which means having a table like this:

```<code>create table [People].[User]
(
    ...
    [Mail] nvarchar(500) not null,
    [Salt] char(16) null, -- Salt used by project 1.
    [Hash] char(128) null, -- Hash used by project 1.
    [AlternateSalt] varchar(12) null, -- Salt used by project 4 and 5.
    [AlternateHash] char(64) null, -- Hash used by project 4 and 5.
    [ThirdHash] char(20) null, -- Hash (no salt) used by project 2.
    ... -- etc.
)
</code>```

and do consecutive checks, until finding a good one.

The good thing is that you may progressively consolidate the passwords for the users once they authenticate. For example, if the user successfully authenticate with the SHA1 used by the fifth project, you may compute and store the PBKDF2 hash and salt and remove the SHA1 hash from the database.

After a year or two, if there are still users who didn't logon for a while, you may send them an e-mail to tell that they must logon if they want to keep their account.

Different passwords. The consolidation may work only if the user is registered at one project, or if she uses the same password for every project. What if the passwords she use for different projects are not the same? You still need to keep the ability to logon with several passwords.

Different data. If Vanessa Kelley told that she lives in Toronto to the project 1, and in Montreal to the project 2, which one is obsolete?

If the inconsistencies are too important, there is a risk that you will never be able to create the unified logon. If there are few or no inconsistencies, than the task will be pretty easy.

Unifying the process

Once you unified the data, you may provide a common process for the five projects. You may want to create a web service which will be accessed by the five projects, or you can modify those projects to access the common database directly. It would be probably much better to use a web service, instead of letting different applications to access the database.

If you can't modify the original projects, too bad. You may sync the data between databases, but it's not easy and not error prone.

Still, you don't want your common logon process to use all the five databases. Not only it costs too much in terms of resources, but it also makes your whole process dependent on five databases. If one of them is down, the logon process would fail.

¹ Example: according to the logs, both logons were made from the same machine, one at 3:00 PM, the second one at 3:15 AM. Moreover, the browser headers were the same, and the first name, last name and birth date are the same.

² Example: if two logons share the same first and last name, it doesn't mean anything at all. Two people can share the same machine or use the same browser too.

Body:
Unifying the data

Since the authentication was independent between the five projects, you may encounter several inconsistencies:

Different identifiers. For example if the user identifiers are e-mail addresses, the same person can register with vanessa.kelley@example.com for one project, v.kelley@example.com for another one, and vanessa12345@example.com for a third one. It is practically impossible to solve this issue: you may have an idea through information aggregation¹, but it's not precise enough and may be insufficient in some cases².

Data standards inconsistency. What if both projects need to know where the user is, but the project 1 uses two letters convention, like CA, while the second one uses the full name, like Canada?

Different authentication implementations. For example, the project 1 uses SHA256, while the project 2 uses salt and SHA512 and the project 3 uses PBKDF2? In order to solve this issue, you'll need to store every hash used, which means having a table like this:

create table [People].[User]
(
    ...
    [Mail] nvarchar(500) not null,
    [Salt] char(16) null, -- Salt used by project 1.
    [Hash] char(128) null, -- Hash used by project 1.
    [AlternateSalt] varchar(12) null, -- Salt used by project 4 and 5.
    [AlternateHash] char(64) null, -- Hash used by project 4 and 5.
    [ThirdHash] char(20) null, -- Hash (no salt) used by project 2.
    ... -- etc.
)

and do consecutive checks, until finding a good one.

The good thing is that you may progressively consolidate the passwords for the users once they authenticate. For example, if the user successfully authenticate with the SHA1 used by the fifth project, you may compute and store the PBKDF2 hash and salt and remove the SHA1 hash from the database.

After a year or two, if there are still users who didn't logon for a while, you may send them an e-mail to tell that they must logon if they want to keep their account.

Different passwords. The consolidation may work only if the user is registered at one project, or if she uses the same password for every project. What if the passwords she use for different projects are not the same? You still need to keep the ability to logon with several passwords.

Different data. If Vanessa Kelley told that she lives in Toronto to the project 1, and in Montreal to the project 2, which one is obsolete?

If the inconsistencies are too important, there is a risk that you will never be able to create the unified logon. If there are few or no inconsistencies, than the task will be pretty easy.

Unifying the process

Once you unified the data, you may provide a common process for the five projects. You may want to create a web service which will be accessed by the five projects, or you can modify those projects to access the common database directly. It would be probably much better to use a web service, instead of letting different applications to access the database.

If you can't modify the original projects, too bad. You may sync the data between databases, but it's not easy and not error prone.

Still, you don't want your common logon process to use all the five databases. Not only it costs too much in terms of resources, but it also makes your whole process dependent on five databases. If one of them is down, the logon process would fail.

¹ Example: according to the logs, both logons were made from the same machine, one at 3:00 PM, the second one at 3:15 AM. Moreover, the browser headers were the same, and the first name, last name and birth date are the same.

² Example: if two logons share the same first and last name, it doesn't mean anything at all. Two people can share the same machine or use the same browser too.


问:
On MVC can several views have the same controller or one view must have one unique controller?
I'm having some questions while designing a architecture for a project around MVC. (It's a C++/Marmalade SDK project, I'm not using any particular MVC framework, I'm making one.)

On several articles (like on the original Steve Burbek article) I keep reading the concept "MVC triad" which bogs me since I took this concept rather literally. When I read it the first time looked like an application is built around "MVC triad" units - one for each UI piece I supposed -, but I find this rather un-flexible and I think that's not how MVC was intended to be used. Then, researching further on the issue, I found several examples of tight coupling of the controller and the view, namely, 1-to-1 relationship - TextEditView has TextEditController.

But when I get back to my project I find that could be useful to have one controller (by 'logical unit', like AddElementController) and several views for that particular controller.

I'm clearly thinking about something like an AddElementController that should have some sort of tab UI. Should I have a AddElementController that has a AddElementTabView and several AddImageView, AddSoundView, etc for the tabs? Or should I have a different 'sub-controller' for each tab view?

In sum, and regarding the MVC pattern (not the X framework particular understanding/implementation of this pattern), is it correct to have several views for a controller or should each view have it's particular controller?

Also, is it correct to keep some state information on the controller or should it be stateless (meaning that the state should be placed on some non-domain state model)?

Thanks to all in advance.

答:
Views does not have Controllers in MVC. Controller is the boss, so a Controller decides which View to be rendered and Views does not / cannot care which Controller requested the View.

You can / will absolutely have multiple Views from a Controller. Just think about creating a model for each view if you want to stick up with MVC pattern.

ContentLicense: CC BY-SA 3.0


答: It depends. There are several variants of MVC, some where only a 1:1 relationship makes sense (like "the humble dialog box"), others where this is not the case. I would recommend to read the "Build Your Own CAB" series of articles, explaining the most important MVC variants.</p>

Title: On MVC can several views have the same controller or one view must have one unique controller?

Body:
I'm having some questions while designing a architecture for a project around MVC. (It's a C++/Marmalade SDK project, I'm not using any particular MVC framework, I'm making one.)

On several articles (like on the original Steve Burbek article) I keep reading the concept "MVC triad" which bogs me since I took this concept rather literally. When I read it the first time looked like an application is built around "MVC triad" units - one for each UI piece I supposed -, but I find this rather un-flexible and I think that's not how MVC was intended to be used. Then, researching further on the issue, I found several examples of tight coupling of the controller and the view, namely, 1-to-1 relationship - TextEditView has TextEditController.

But when I get back to my project I find that could be useful to have one controller (by 'logical unit', like AddElementController) and several views for that particular controller.

I'm clearly thinking about something like an AddElementController that should have some sort of tab UI. Should I have a AddElementController that has a AddElementTabView and several AddImageView, AddSoundView, etc for the tabs? Or should I have a different 'sub-controller' for each tab view?

In sum, and regarding the MVC pattern (not the X framework particular understanding/implementation of this pattern), is it correct to have several views for a controller or should each view have it's particular controller?

Also, is it correct to keep some state information on the controller or should it be stateless (meaning that the state should be placed on some non-domain state model)?

Thanks to all in advance.


问:
Who should register input listeners: the controller or the view? (MVC)
I'm using an (C++) SDK (Marmalade) and building a project around the MVC pattern. On my app, user input listeners may be registered on certain UI elements/widgets/etc providing a proper callback function (according to  MVC should be a method of a controller, right?).

In this scenario, who should register these listeners:

The controller? (must have access to the view UI elements, less decoupling of control from presentation)

Or the view? (direct access to UI elements but must have a reference to the controller, isn't this incorrect in MVC?)

Between the two, I think the latter makes more sense and does better separation of concerns, but I'm afraid that I overlooked some problem with that design.

Thanks in advance.

答:
It depends on the type of MVC you want. I suggest you try the Michael Feather's "humble dialog box", which is also called "model view presenter (MVP)", and probably what you are looking for.

In this variant, the view has a refererence to the controller, and the controller has a reference to an abstract interface of the view. So the view can provide methods for registering listeners, those methods are also available in the interface, and the controller will call these methods without having direct access to the UI.


答:
The point of the controller is to control user interactions with your domain model--that is, it is a level of indirection between what the user sees (the view) and the state of your applications (the model).

When the user makes a request, it is directed to a controller.  The controller decides how to relay that request to the application, usually through some sort of service class.  It then interprets the response from that service class and decides what view to send back to the user.

A controller may always return the same view (1:1) if there's only one sort of request the user can make of the controller, and it always requires the same sort of response.  For example, the HelloWorldController will always return a HelloWorldView displaying "Hello, World!"

On the other hand, a controller often has to decide on different views, depending on what the model tells it.  The TeamRosterController might return a RugbyTeamRosterView or a FootbalTeamRosterView, depending on the type of the team requested.

It is generally preferable for controllers to be stateless, although some access to the state of the user session may be necessary or desirable.  You should manage access to that state separately if possible.

I'd highly recommend looking at an actual MVC framework to see what it does and how it works.  You don't have to use it, but you would definitely gain a better understanding before building your own.


答: If I understand the question correctly, and I kind of doubt I do, the answer is none of the above.  Registering event listeners with their sources should generally be the responsibility of a third part, a builder of some sort that constructs the system and starts it off.</p>

Title: Who should register input listeners: the controller or the view? (MVC)

Body:
I'm using an (C++) SDK (Marmalade) and building a project around the MVC pattern. On my app, user input listeners may be registered on certain UI elements/widgets/etc providing a proper callback function (according to  MVC should be a method of a controller, right?).

In this scenario, who should register these listeners:

The controller? (must have access to the view UI elements, less decoupling of control from presentation)

Or the view? (direct access to UI elements but must have a reference to the controller, isn't this incorrect in MVC?)

Between the two, I think the latter makes more sense and does better separation of concerns, but I'm afraid that I overlooked some problem with that design.

Thanks in advance.


问:
How best do you represent a bi-directional sync in a REST api?
Assuming a system where there's a Web Application with a resource, and a reference to a remote application with another similar resource, how do you represent a bi-directional sync action which synchronizes the 'local' resource with the 'remote' resource?

Example:

I have an API that represents a todo list.

GET/POST/PUT/DELETE /todos/, etc.

That API can reference remote TODO services.

GET/POST/PUT/DELETE /todo_services/, etc.

I can manipulate todos from the remote service through my API as a proxy via

GET/POST/PUT/DELETE /todo_services/abc123/, etc.

I want the ability to do a bi-directional sync between a local set of todos and the remote set of TODOS.

In a rpc sort of way, one could do

POST /todo_services/abc123/sync/

But, in the "verbs are bad" idea, is there a better way to represent this action?

答:
I would consider a synchronization operation as a resource that can be accessed (GET) or created (POST). With that in mind, the API URL could be:

```<code>/todo_services/abc123/synchronization
</code>```

(Calling it "synchronization", not "sync" to make it clear it's not a verb)

Then do:

```<code>POST /todo_services/abc123/synchronization
</code>```

To initiate a synchronization. Since a synchronization operation is a resource, this call could potentially return an ID that can then be used to check the status of the operation:

```<code>GET /todo_services/abc123/synchronization?id=12345
</code>```

Body:
I would consider a synchronization operation as a resource that can be accessed (GET) or created (POST). With that in mind, the API URL could be:

/todo_services/abc123/synchronization

(Calling it "synchronization", not "sync" to make it clear it's not a verb)

Then do:

POST /todo_services/abc123/synchronization

To initiate a synchronization. Since a synchronization operation is a resource, this call could potentially return an ID that can then be used to check the status of the operation:

GET /todo_services/abc123/synchronization?id=12345


答:
The problem is that the MVC pattern was designed in a system that doesn't really exist anymore.  It was invented in Smalltalk at a time when UI libraries did not exist.  To make a window dialog you drew all the boxes, highlighted the appropriate squares, made sure that the text you were drawing ended up in the right spot...etc...

Imagine what it would be like to write a dialog app using nothing but one large canvas.  That's the world the MVC comes from.

A "view" in this system was a text box and it was a class that was responsible for drawing the box, the text, drawing selected areas, responding to changes in the text, etc...

A "controller" was another class that took mouse events that occured within this box like mouse moving, key down, key up, clicks, etc...and it would decide what happened.  Should we change the text?  Should we change the selection?  Stuff like that.

A "model" was yet another class that represented the basic data and state of the component.  A text box model would have the text of course, the font, selection, etc...

As you can see, in a situation like this the three components are very entangled in the representation of a single idea.  It makes sense in this context to speak of a "triad".

Today, if you're working on creating a UI library and using raw drawing commands you might do something similar.  But the application of the "MVC" pattern has spread beyond its initial purpose.  Now days you have a "view" that may actually be a complete dialog, and a controller that's responding to events like "textChanged" or "buttonClicked".  The model in today's MVC is normally something fairly disconnected from the system (but generally linked to the view by providing an observer interface of some sort) and there may be many views associated with the one model.

In a system I recently architected for example we had around 10+ views all observing a single document "holder" and its active document.  A main drawing interface interacted with the layout of the document, various property views that observed the selected item and provided a record interface, and a smaller scale representation of the main view that showed the entire document instead of just the visible window.  Some of these views had controllers of varying complexity that turned GUI events into changes to the document, which would in turn notify its various views.

Can you still call such a relationship a "triad"?  Perhaps, but I think it implies too much of the former, older application of MVC.

Could you share controllers with different views?  Depends on how similar the views are.  I've found that generally speaking this type of object has behavior to specific to the view it's controlling AND the model it is manipulating to be very reusable...but there's always exceptions.


问:
Naming classes, methods, functions and variables
There are 3 important naming conventions:

with_underscores

PascalCased

camelCased

Other variants are not important because they are not commonly used.

For variables it seems that the one with underscores is the most used by developers so I'll stick with that. I think it's the same for functions.

But what about class, and method names? Which of these 3 is the most used by developers for such constructs? (personally, it's 3. for methods and 2. for classes)

Please do not post things like "use what you feel is right", because the code I'm writing is API for other developers, and I'd like to adopt the most popular coding style :)

答:
We have this weird system where everything has it's own convention:

ClassesAreLikeThis.

variablesAndFunctionsLikeThis

UNLESS_THEY_ARE_CONSTANTS

andMemberVariablesEndWith_


问:
Why isn't rich code formatting more common?
I was reading Code Complete and in the chapter on layout and style, he was predicting that code editors would use some sort of rich text formatting. That means, instead of code looking like this

```<code>Procedure ResolveCollisions
{ Performs a posteriori collision resolution through spatial partitioning algoritm }
(
  CurrentMap : SpriteContext,
  PotentialColliders: SpriteList
)
var Collider  : Sprite,
    Collidee  : Sprite,
    Collision : SpriteCollision
begin
  DoStuff();
end.
</code>```

it could look something like this:

Procedure ResolveCollisions

Performs a posteriori collision resolution through spatial partitioning algorithm

Parameters

CurrentMap : SpriteContext

PotentialColliders : SpriteList

Local Variables

Collider  : Sprite

Collidee  : Sprite

Collision : SpriteCollision

```<code>    DoStuff();
</code>```

I've seen syntax coloring and highlighting and even parentheses coloring, but nothing that looked like this in actual code. I was wondering if this sort of thing actually ever existed, or perhaps if it was decided that it didn't have enough benefit or that it was an entirely bad idea.

Have any of you seen richly-formatted code like this before, or know if the idea was ever considered and eventually rejected?

答: I think this is because nobody yet separated code reading and code writing. At least it doesn't become mainstream. Sometimes you have to read code you touched long ago or code created by other developers. You will probably have to spend much time until ready for changing a single byte in this source. This could be "read" mode that can do whatever is needed for easier understanding (font size, reformatting, sub-script, super-script etc). When you're ready, the editor can switch to "write" mode and be less restrictive and more obeying "the rule of least surprise"</p>


问:
How do you map members and their responsibilities to an organization?
I'm working on a Django project that tracks arts-related activities, and I'm stuck on the human-resources part of things.

(code below) I have a class Ensemble that subclasses Organization. Organization only has one important field, name. Ensemble has another field, players (a many to many relationship). A player is a Performer which has two foreign key fields, individual and instrument. The idea is that a performer is any individual on a particular instrument--so, e.g., I can be one individual that can be two performers: one on guitar, the other on bass.

The problem is that not all organizations are as clean as this. Some Organizations will have dancers, for instance (a dance troup), plus any number of generic Individuals who do any number of specific tasks not tracked as a specific class (like Performer). So at first I was thinking it would be best to just map Individuals to the Organization through a many to many relationship, create a Job class mapping Individuals to a JobCode class (which might include a row with something like 'performer'), but that doesn't work well if for instance you want to keep track of which instrument a performer plays for that particular ensemble, or if they play multiple instruments, I would like to be able to make that explicit. That's why the Ensemble::players relationship made sense to me.

So it seems I have an Organization class that will never truly be more than abstract, but I still need to be able to track what type of job an individual does for an Organization. Ensemble only makes sense for mapping Performers to an Organization, but what about Teachers in a School? Again, I would like to be able to make it explicit that a bassoon player is teaching bassoon at the school, and not clarinet (even though they might play both). So I can't just map the Individual to the School organization, right?

Also, this seems like it would be a common problem. Is there a conventional way of dealing with these kinds of relationships? What is the most effective?

Code:

```<code>class Individual(models.Model):
    surname = models.CharField(max_length=255)
    name = models.CharField(max_length=255)
    prefix = models.ForeignKey(Prefix, blank=True, null=True)
    suffix = models.ManyToManyField(Suffix, blank=True)
    date_of_birth = models.DateField(null=True, blank=True)
    phone_numbers = models.ManyToManyField(PhoneNumber, blank=True)
    addresses = models.ManyToManyField(Address, blank=True)
    user = models.OneToOneField(User, blank=True, null=True)

class Performer(models.Model):
    individual = models.ForeignKey(Individual)
    instrument = models.ForeignKey(Instrument)

class Organization(models.Model):
    name = models.CharField(max_length=255)
    founded = models.DateField()
    tags = TaggableManager(blank=True)
    media = models.ManyToManyField(Upload, blank=True)

class Ensemble(Organization):
    players = models.ManyToManyField(Performer)
</code>```

答:
As always with business analysis patterns: check out Martin Fowler: http://martinfowler.com/ , more specifically his catalog of Patterns of Enterprise Application Architecture: http://martinfowler.com/eaaCatalog/ and his further development of those: http://martinfowler.com/eaaDev/

For dealing with roles he has a dedicated pdf around (probably taken from his book Analysis Design Patterns). IIRC in the book his examples were centered around hospitals, physicians and contracts (or rights to practice in a hospital), but you can get a lot of inspiration from his writings. PDF: http://martinfowler.com/apsupp/roles.pdf (It may take some time to load, the site seems very slow at the moment I write this).


问:
What's the difference between Entry Level/Jr/Sr developers?
Other than title and pay, what is the difference?

What different responsibilities do they have.

How knowledgeable/experienced are they?

What is the basic measure to determine where a developer fits into this basic structure?

答:
As most have said, it varies from company to company, and job to job.

For instance, I once worked at a company that considered anybody who worked there for more than 5 years a "Senior Software Engineer".  At the other extreme, another place I worked had very stringent definitions (and associated pay scales).

Some places may consider "entry level" and "junior" to mean the same thing.

It can vary based on years of experience, general knowledge, specific knowledge (i.e. knowing the features of a certain language), managerial and/or leadership experience, all combinations thereof, and certainly much more.

ContentLicense: CC BY-SA 2.5


问:
how to nicely use constant std::string in c++
In my current code project, there is an awful lot of constant strings I use to print out error messages.

Hardcoding such strings is generally considered to be bad practice.
Now I'm searching for a "clean way" to include these strings in my program. Therefore I've written a "constants.h" and "constants.cpp" which looks something like

```<code>#ifndef CONSTANTS_H_
#define CONSTANTS_H_

extern std::string error_message_1;

#endif
</code>```

and the constants.cpp:

```<code>#include "constants.h"

std::string error_message_1 = "this is just a sample, not my actual naming convention. move on the the question ;-)"
</code>```

So you might see the problem I have with this: due to a lot of error messages, the variable name itself is fairly long. The error message is even longer, so it crashes the standard 80 characters in one line of code.

Obviously I want my code nice and clean. I don't like going far beyond the 80 charactes per line of code. I don't like somthing like the following either:

```<code>std::string error_message_1 = "this is just a sample about how to"
                              " have one string across many lines"
                              " in the source code. this is not "
                              "very pretty too..";
std::string msg = "and suddenly there's one line which is good..";
std::string error_message_with_longer_name = "and it's even "
                                             "uglier with not "
                                             "equally long "
                                             "variable names";
</code>```

Storing the strings in an external file which one would read in at the start of the program does not seem to be optimal too since the compiler cannot warn about missing strings. Basically this would be a mess to maintain.

So what do you do about it? Is there such a nice thing as "Resources", which I know of Android (or is it Java in general?) development?

Note: Please do NOT tell me that my naming convention is bad. The above is just an example. It's not what it looks like ;-)

答:
Hardcoding such strings is generally considered to be bad practice

Do you realize that having a file that contains literals is still hardcoding? It seems you're confusing hardcoding with magic numbers. Strings, in general, aren't magical and so you don't need to give them a name. Moving them to a constant is only necessary to avoid duplication. If you're only using a string once (as in the case of most error messages) then it's pointless to move them into another file, unless for some reason you're doing it as compile-time configure file.

If it's crucial for the user to be able to change the error messages then move them to a configuration file (not a .hpp).

If you need it for translation then use something like gettext which allows you to provide translation files and still keep your source clean.

Also, don't use std::string for string constant expressions - use const char[] instead.


问:
How to deal with over-complication?
I often catch myself doing code unnecessarily complicated (sad but true). Is there any set of rules, discipline, etc to help avoid that? (excluding the KISS principle, because I know it but often forget when it comes to the real code :)</p>

答:
I generally do these things to avoid over-complication

Before you start to code, make a plan and design an interface for your code. Always think about what your code is actually going to do and what it probably isn't. Be realistic about that, but don't use any quirky solutions. Each function in the interface should do exactly one thing, if possible what it does should only depend on its arguments.

A good measure to see whether your code is overcomplicated is deepness of nesting. Once my code is nested five or so levels deep, I know that something went wrong. Try to split your code into functions that express several steps of what you want to do. Expect the compiler to generate efficient code for you. Compilers are smart.

Split your code into modules that represent functional units of your program. Each module should contain a set of functions that are likely to be used together. Neither throw unrelated things into one module nor write a group of modules that are always used together.

Don't implement functionality you won't need, but keep in mind that one might want to expand your program

Title: How to deal with over-complication?


答:
As Antoine de St-Exupéry says: "A designer knows that he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away."

This is a difficult and common problem, but it's something you can address over the course of the next few years. Recognizing it's a problem is the most important step, and once you have learnt to correct the kinds of complications you tend to add, you'll start designing without them.

When I realized I had this problem early in my career, I found it helpful to analyze and reanalyze every class, function, member variable, local variable, and nested function calls to see if things could be consolidated or eliminated while still meeting the given requirements. Basically, code golf.

Title: How to deal with over-complication?

Body: I often catch myself doing code unnecessarily complicated (sad but true). Is there any set of rules, discipline, etc to help avoid that? (excluding the KISS principle, because I know it but often forget when it comes to the real code :)</p>


问:
Should you fix preexisting defects while working on something else?
Conundrum:  During the course of working on a new feature or fixing a defect, you find a legacy problem in code.  What should you do?  Fix it and risk altering the behavior of the code. It has either been working up until now by some fluke, or else the defect has not been detected or worth anyone's time to report.  Should you leave it alone and allow the problem to make the code harder to work with later?  Fixing the problem will only add to the time of your original task and force you to regression test. Few will appreciate the work. Fixing it, however, seems right somehow. Code with fewer problems is easier to refactor and build upon.

I've been finding myself in this situation time and time again as we work to modernize a web application. I can't tell if I'm being obsessive or honorable when I go off-tangent working on these old bugs.  How do you handle these situations?

Thanks,
Corey

答:
It depends, if its a small bug where you are certain that your fix has low impact then personally i would fix it as part of the other work and then let the PM know.

If it has any risk to client, users or company bring it up with the Project Manager and discuss a course forward. Its their job to evaluate risk so bring it to their attention and the case for fixing it. Then honour their decision.


答: Maybe you should have a look at some literature about extreme programming. Those guys are very much trying to avoid unnecessary complexities. A common source for complexities is trying to generalize even if there is only one application of the generalized whatever. I think Kent Beck recommended to only generalize something if you have already implemented it in three different ways. For the first tries you should "do the simplest thing that could possibly work".</p>

Title: How to deal with over-complication?


答:
I'd like to think that I am pretty good at keeping things simple, at least when using C#, even though stack exchange is full of people who are better than me. You get better with experience. I personally do not like to plan ahead too much, particularly for small tools because I do not really know which exact direction I will move in until I sink my teeth into the project. So, I have to have something semi-working first. Once it does and I see no more potential hard spots, then I start trying to simplify things. Now, the easiest way to simplify things is to keep the UI and features simple to begin with. I have been making prototypes recently so sometimes it is easy for me to decide what goes in and what does not. If you have to give estimates and the code goes right into the core and will be highly scrutinized by QA, then you probably cannot afford the time to make everything perfect because of deadlines plus the quality better be good. In this situations you WANT to keep things simple in order to avoid/minimize the stress of missed deadlines.

If you have more freedom, and you want to delight the users while not taking a year to do it, then ask people for specific feedback. Do a random hall usability testing to make sure that other people can use the tool. Consult with more experienced colleagues on what a good approach might be. Implement something that works and post pieces on the code review site to see how others can solve the same problem better.

If you are about to decide between library A, library B or rolling your own - ask on Stack Overflow for advice. If you still are learning something such as CSS or SQL or XAML - ask on Stack Overflow.

You want to be breaking a problem up into pieces, find a good solution for each sub-problem and then put it all together.

Along the way you should utilize tools for re-factoring, style checking, TDD, etc.

For C# I would recommend Resharper, StyleCop. Try to find something for your language. Basically, you want to use your time efficiently so that you will have time for "post-mortem", refactoring, creating a library that

Once you are in the simplification/perfection stage, you are never quite done. This sucks if you have to move onto another project and not ever touch this code again unless fixing a bug. If the stakes are not as high, then you can go back to the older project and remove lines and lines of code once you discover generics, some library, etc. Did I mention that Stack Overflow is a great resource? Just do not be a http://slash7.com/2006/12/22/vampires/.

You can learn a lot from re-factoring old code, so that you will avoid making the same mistakes in the future. I hope this helps.

Title: How to deal with over-complication?


问:
Voting System like Stack Exchange
I am trying to create a voting system like Stack Exchange. Should I create a table and insert values like following and then sum up the "vote" or there are some better ways to do this?

Table name:  vote

```<code>id  userid   article_id  vote
 1    1001      12       1
 2    1002      12      -1
 3    1003      12       1
 4    1002      10      -1
</code>```

Table name: articles

```<code> article_id     article_title   article_content  article_author
   12              something       something       something
   10              something       something       something
</code>```

From the example above the total vote for the article 12 is 1+(-1)+1 = 1

答:
"Like Stack Exchange" is a summary requirement that implies a number of details.  One of those details is the ability for users to change their votes.  Thus you certainly do need a table like vote, with a mechanism to replace the vote.vote value.  Another implied detail is a high-performance web interface, which leads to caching and/or denormalization of certain infrequently-changed data, such as the vote total for an article (as Alex suggests).  Ensuring those cached/denormalized values are accurate can be difficult.  Caching systems are notoriously complex if you always need accurate data, but you might consider invalidating the cached article on every insert/update to the vote table.  Similarly, you might want to use a database trigger to apply voting deltas to the articles table on every insert/update to the vote table.

A few unrelated observations:

Having columns with the same names as their tables is a code smell, often indicating a lack of data-model planning.

You don't need an id column in the vote table.  Id columns should only exist in tables where there is no other primary key.  The primary key of the vote table should be a composite of userid and article_id.

You don't show database constraints, but vote should require the combination of userid and article_id to be unique.  You don't want multiple votes from a single user on the same article.

Title: Voting System like Stack Exchange


答:
I work on a very small team, so it kind of depends on what the change is:

If its a small, obvious bug fix, I definitely go for it.  I also throw in extra comments if I have to work through someone else's code and other little improvements that fall under the "boyscout rule" to me.

If the code is so entwined that you have to ask "Will changing this break something and require testing" then no, you shouldn't change it.  Bring it up in your bug tracking system if it worries you.

This, incidentally, is why I try to code smaller methods with more obvious type-signatures as well.  If you know there aren't side-effects and can make the ins and outs match, you can fix, rearrange, or tweak any of the interior code without risk.

But don't feel like lack of appreciation is a reason not to fix bugs you find or to improve the code base for any reason.  If nothing else, you're being kind to the future you who will assuredly be back in there to fix something else.

EDIT:
You also need to watch your time on the project.  Obviously under tight deadlines, you need to focus on getting the main work done, but if you're just under "normal load" then I think a little cleaning up here and there makes everyone happier in the long run.

Title: Should you fix preexisting defects while working on something else?

Body:
Conundrum:  During the course of working on a new feature or fixing a defect, you find a legacy problem in code.  What should you do?  Fix it and risk altering the behavior of the code. It has either been working up until now by some fluke, or else the defect has not been detected or worth anyone's time to report.  Should you leave it alone and allow the problem to make the code harder to work with later?  Fixing the problem will only add to the time of your original task and force you to regression test. Few will appreciate the work. Fixing it, however, seems right somehow. Code with fewer problems is easier to refactor and build upon.

I've been finding myself in this situation time and time again as we work to modernize a web application. I can't tell if I'm being obsessive or honorable when I go off-tangent working on these old bugs.  How do you handle these situations?

Thanks,
Corey


问:
Wildcard user in select statement on indexed varcharcolumn
This question is based on some testing I've done recently in order to better understand SQL indexing system.

Table with 500k entries, InnoDB engine

This is a simple select query on a varchar field. The name column is not indexed.

After indexing these are the results:

All good until this point. When I'm trying to place a wildcard at the beginning of the search key, even though the column is indexed, the result time is the one from the non-index case:

I'm wondering why is this happening? Is it because the index cannot be used any more? Is this solvable in any way? can I achieve a better search time even though I'm using % both at the beginning and at the end of the search string?

Thank you!

答:
If you want to see what indicies mysql is using, try using explain:

http://dev.mysql.com/doc/refman/5.5/en/explain.html

As for how indicies are used, when you have a wildcard at the start and end of the like expression, e.g. '%something%', then no, the index is not used, as per this reference:

The following SELECT statements do not use indexes:

```<code>SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE other_col;
</code>```

In the first statement, the LIKE value begins with a wildcard character. In the second statement, the LIKE value is not a constant.

http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

Body:
If you want to see what indicies mysql is using, try using explain:

http://dev.mysql.com/doc/refman/5.5/en/explain.html

As for how indicies are used, when you have a wildcard at the start and end of the like expression, e.g. '%something%', then no, the index is not used, as per this reference:

The following SELECT statements do not use indexes:

SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE other_col;

In the first statement, the LIKE value begins with a wildcard character. In the second statement, the LIKE value is not a constant.

http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html


问:
Mac Developer Library Download
I'm not sure which SE site this belonged on, so I figured I'd try this one.

Whenever I browser the Mac Developer Library at developer.apple.com, on the top right of the window, there's a link for a PDF version.

Has anyone ever downloaded them all and combined them into one file? I want to download the Mac Developer Library for my Kindle, and  I figure there's no .mobi versions, so I'm trying to look for a PDF version.

Thanks in advance and sorry if its not the correct site.

答:
If you want to look at the documentation on an iPhone/iPad I recommend the docset app (on the app store or github).

For the Kindle, there's a python script to parse the documentation (downloaded by Xcode) into .mobi file.
However as it isn't really updated, it may not work for docsets for Lion or iOS >=5.0

The docset from Xcode (4) are located here:

~/Library/Developer/Shared/Documentation/DocSets/*.docset

Title: Mac Developer Library Download


答:
Even when I think I'm doing a good job of writing a program, chances are it can be simplified a lot.

I find the most useful thing to do is ask "Regardless of how it does it, what is this program supposed to accomplish?"
i.e. If it's a compiler, it is supposed to read a file of code and write something that can execute. As such, if it's doing nothing unnecessary, it will be I/O bound.

I've also found that performance tuning leads to simplifying, as in this example, so if you get pretty good at diagnosing performance and recoding to improve it, that alone will teach you what you may be doing that is needlessly complicated, so you learn not to do it.
(Often it is what you've been taught to do.)

Title: How to deal with over-complication?


问:
Testing thread safety
Say you have a function f that is or contains a critical section.  How would you unit test that only one thread can run it at once, that it doesn't have race conditions, and that it doesn't cause a deadlock, etc...?

答: Add sleeps around operations within f and add a parameter to let you control their length. You can then unit test as normal, but with different scheduling patterns.

Title: Testing thread safety


问:
Should I refactor single letter variables for constructs like pointer/structure names?
And No, i am not referring to single variables in loops or exceptions. Lets say pointer/struct names in large c ,c++ programs . Are there any languages where this type of naming is acceptable or is the norm. Or any constructs in c/c++ ( not iterators,loops) where it is implicit.

what is the general practice in handling such naming conventions ?  would you change it? if so how would you change it?

If you are a team-project lead and some one raises an issue with regards to the naming convention how would you view it?

答:
This is going to be unpopular opinion, but

Please keep your single-letter variable names. They're necessary. For-loops should never have anything else for index variables.

If your class names are single-letter names, you might need to reconsider them.

Use the length of the identifier as documentation of how commonly the variable can be found from the code. If it is common, it needs short name. If it's rare, it needs longer name.

Short name can be considerably more descriptive than long name. Think of math. Large amount of accuracy is needed in math, but still they're always using single-letter names for everything. The description of what each variable or constant is doing is actually not helping at all whenever the math is applicable in many situations -- it's a sign of abstraction when you can generalize it. Short name is more generic than long name.


答: Our testers hate this. Unless it is very trivial we log it in the bug database, then allocate it to a release and write regression tests. If the developers are just going to making changes that are not on the schedule how can you ever keep a deadline?</p>


答:
I don't think I believe in the KISS principle anymore.  First of all, they were overrated...

Consider this function

```<code>void process_payment(payment const& p) {

    account * a = get_account();
    if (!a) {
       std::cout << "No account information.\n";
       return;
    }
    ...
}
</code>```

That's as simple as it gets.  If we follow the KISS principle then we might do something like this.  The function is NOT simple to test since now we have to redirect standard output to something the tests can process.  You fix this by adding complexity to the function's interface by taking the output handle as a parameter.  This is not as simple as can be done and I've run into KISS adherents that really freak out over stuff like this...especially if they're fighting with their superiors about whether unit testing should be done.

Furthermore, what is "simple" is in the eye of the beholder.  Just the other day I caught shit for using a buffer object that grows as needed rather than malloc+memset+memcpy to copy a string handed to me by a network API.  In my opinion using a buffer object is simpler because it's already there, does what I need (albeit it will do more), etc...  In the other guy's opinion doing it by hand is simpler because the buffer is overkill.  He's of course right because he's the boss.

Yet more, when faced with the decision to use a global variable to allow access by many functions vs. passing this variable around as a parameter it is quite obvious that the former is much "simpler".  It's also rather obvious that in most cases it is the bad choice.  Adherents to KISS though pick the former and their code turns into this untested knot of spaghetti that isn't even possible to conceptualize since modularity and decoupling have all gone out the window in an effort to keep things "simple"...and yes, by an obvious and possibly naive measure of simple it is much simpler to reach out and grab touch global than it is to call a function existing only to hide this global or pass around a parameter.

Consider also this code:

```<code>void somethingAboutStrings(char* in) {
    char buffer[128];
    strcpy(buffer, in);
    ...
}
</code>```

Very simple, that.  I've seen way too many KISS adherents writing C code that looks like that, including the one I've currently got hammering on everything I do as "complicated".  They assume so damn much and get way simpler than is safe to.  Anyone who knows the language knows that the function above is incredibly unsafe and WILL someday result in bugs that take hours and hours to resolve.  It's code like the above that give C and C++ bad names in fact and the industry is riddled with shit like this from basic apps to the financial industry and others...it's terrifying to me.  But this is "simple" and why would you write a bunch of error detection and buffer protection code when you know that the input is always going to be shorter than X?

The answer to that question is of course that someone isn't going to know that you have this internal and arbitrary size limit and will exceed it...or some bug up the line will--which is what happened.

After catching crap for the last 8 months from this KISS adherent I've become rather cynical of the idea and think it probably leads to more problems than catches them.  Writing reusable code is a good thing.  Writing tested code is a good thing.  Decoupling is a VERY good thing...and I would assert that in the end they make things easier to manage, easier to read, etc..  They are not, however "simple"; at least not in the way I've seen that word used of late.

Title: How to deal with over-complication?

Body:
I don't think I believe in the KISS principle anymore.  First of all, they were overrated...

Consider this function

void process_payment(payment const& p) {

    account * a = get_account();
    if (!a) {
       std::cout << "No account information.\n";
       return;
    }
    ...
}

That's as simple as it gets.  If we follow the KISS principle then we might do something like this.  The function is NOT simple to test since now we have to redirect standard output to something the tests can process.  You fix this by adding complexity to the function's interface by taking the output handle as a parameter.  This is not as simple as can be done and I've run into KISS adherents that really freak out over stuff like this...especially if they're fighting with their superiors about whether unit testing should be done.

Furthermore, what is "simple" is in the eye of the beholder.  Just the other day I caught shit for using a buffer object that grows as needed rather than malloc+memset+memcpy to copy a string handed to me by a network API.  In my opinion using a buffer object is simpler because it's already there, does what I need (albeit it will do more), etc...  In the other guy's opinion doing it by hand is simpler because the buffer is overkill.  He's of course right because he's the boss.

Yet more, when faced with the decision to use a global variable to allow access by many functions vs. passing this variable around as a parameter it is quite obvious that the former is much "simpler".  It's also rather obvious that in most cases it is the bad choice.  Adherents to KISS though pick the former and their code turns into this untested knot of spaghetti that isn't even possible to conceptualize since modularity and decoupling have all gone out the window in an effort to keep things "simple"...and yes, by an obvious and possibly naive measure of simple it is much simpler to reach out and grab touch global than it is to call a function existing only to hide this global or pass around a parameter.

Consider also this code:

void somethingAboutStrings(char* in) {
    char buffer[128];
    strcpy(buffer, in);
    ...
}

Very simple, that.  I've seen way too many KISS adherents writing C code that looks like that, including the one I've currently got hammering on everything I do as "complicated".  They assume so damn much and get way simpler than is safe to.  Anyone who knows the language knows that the function above is incredibly unsafe and WILL someday result in bugs that take hours and hours to resolve.  It's code like the above that give C and C++ bad names in fact and the industry is riddled with shit like this from basic apps to the financial industry and others...it's terrifying to me.  But this is "simple" and why would you write a bunch of error detection and buffer protection code when you know that the input is always going to be shorter than X?

The answer to that question is of course that someone isn't going to know that you have this internal and arbitrary size limit and will exceed it...or some bug up the line will--which is what happened.

After catching crap for the last 8 months from this KISS adherent I've become rather cynical of the idea and think it probably leads to more problems than catches them.  Writing reusable code is a good thing.  Writing tested code is a good thing.  Decoupling is a VERY good thing...and I would assert that in the end they make things easier to manage, easier to read, etc..  They are not, however "simple"; at least not in the way I've seen that word used of late.


答:
Hardcoding such strings is generally considered to be bad practice.

Not sure I agree with that.

String literals are easy to read rather than the name of a string. If you want the same text for multiple locations then encapsulate the text into a function and call the single function to display the message.

If you want to centralize the text into a single file. Then what you are looking for is: strings as resources not manually moving all your string literals to string variables.

Checkout the following packages (normally used in localization but will work here).

```<code>* gettext
</code>```

Basically what this package does is allow you to leave the 'English' version of the message in the code. But it will use the 'English' text as a key into a resource table to get the corrct version of the string for a particular local.

So code that looked like this:

```<code>printf ("and suddenly there's one line which is good..");

// Now looks like this:

printf (gettext ("and suddenly there's one line which is good.."));
</code>```

You do not need to go through the hassel of extracting all your constant strings into another package.

See here for full details. http://www.gnu.org/software/gettext/

Personally I use the above in combination with boost format libraries for localization.

```<code>std::cout << boost::formt("The time is %1 in %2.") % time % country;

becomes:

std::cout << boost::formt(gettext("The time is %1 in %2.")) % time % country;

English Resource File:      "The time is %1 in %2."
Azerbaijani Resource File:  "Saat %2 saat %1 deyil."
</code>```

Title: how to nicely use constant std::string in c++

Body:
In my current code project, there is an awful lot of constant strings I use to print out error messages.

Hardcoding such strings is generally considered to be bad practice.
Now I'm searching for a "clean way" to include these strings in my program. Therefore I've written a "constants.h" and "constants.cpp" which looks something like

```<code>#ifndef CONSTANTS_H_
#define CONSTANTS_H_

extern std::string error_message_1;

#endif
</code>```

and the constants.cpp:

```<code>#include "constants.h"

std::string error_message_1 = "this is just a sample, not my actual naming convention. move on the the question ;-)"
</code>```

So you might see the problem I have with this: due to a lot of error messages, the variable name itself is fairly long. The error message is even longer, so it crashes the standard 80 characters in one line of code.

Obviously I want my code nice and clean. I don't like going far beyond the 80 charactes per line of code. I don't like somthing like the following either:

```<code>std::string error_message_1 = "this is just a sample about how to"
                              " have one string across many lines"
                              " in the source code. this is not "
                              "very pretty too..";
std::string msg = "and suddenly there's one line which is good..";
std::string error_message_with_longer_name = "and it's even "
                                             "uglier with not "
                                             "equally long "
                                             "variable names";
</code>```

Storing the strings in an external file which one would read in at the start of the program does not seem to be optimal too since the compiler cannot warn about missing strings. Basically this would be a mess to maintain.

So what do you do about it? Is there such a nice thing as "Resources", which I know of Android (or is it Java in general?) development?

Note: Please do NOT tell me that my naming convention is bad. The above is just an example. It's not what it looks like ;-)

Body:
Hardcoding such strings is generally considered to be bad practice.

Not sure I agree with that.

String literals are easy to read rather than the name of a string. If you want the same text for multiple locations then encapsulate the text into a function and call the single function to display the message.

If you want to centralize the text into a single file. Then what you are looking for is: strings as resources not manually moving all your string literals to string variables.

Checkout the following packages (normally used in localization but will work here).

* gettext

Basically what this package does is allow you to leave the 'English' version of the message in the code. But it will use the 'English' text as a key into a resource table to get the corrct version of the string for a particular local.

So code that looked like this:

printf ("and suddenly there's one line which is good..");

// Now looks like this:

printf (gettext ("and suddenly there's one line which is good.."));

You do not need to go through the hassel of extracting all your constant strings into another package.

See here for full details. http://www.gnu.org/software/gettext/

Personally I use the above in combination with boost format libraries for localization.

std::cout << boost::formt("The time is %1 in %2.") % time % country;

becomes:

std::cout << boost::formt(gettext("The time is %1 in %2.")) % time % country;

English Resource File:      "The time is %1 in %2."
Azerbaijani Resource File:  "Saat %2 saat %1 deyil."


答: I've been on teams where non-critical defects or standard-violations are submitted as a "Weak Code" defect.  I would say that the person who finds a critical defect has a responsibility to throw some kind of flag</p>


问:
Is there a more modern program than lex or yacc, which does not require JVM?
Is there a "modern" bison and flex equivalent which does not require the JVM or .NET or similar "heavy" runtimes?

By modern, I mean for example Antlr and another one in Java I saw but forgot the name of. (I know that for instance Antlr has a C target, but I am toying with the idea of embedding the compiler generator inside my own program and Java would be very impractical for me.)

答:
I recommend using the Lemon parser generator for parsing. Like Bison, it produces a parser in C. However, its grammar is less error-prone, the parsing interface is reentrant without global variables, and works by you giving tokens to the parser (instead of the parser calling you back to get tokens).

You don't really need a lexer generator (e.g. lex). It's usually easier to write it by hand.

You can check out some of my code to get an idea of how to parse a language using Lemon: language, lexer, grammar, parser.


问:
Documentation utility for OpenEdge ABL
I have a large system in OpenEdge ABL that could use some documentation-love. Currently a team member is working on a utility that can find methods and functions and make some "Javadoc-esque" html pages out of it. It's pretty rough around the edges. Okay, it's like sawblades around the edges.

I'm trying to find something like Javadoc or Doxygen that is capable of parsing OpenEdge ABL to generate some kind of API documentation. I know the market for OpenEdge isn't the best, but there is a lot of stuff that's passed along by word of mouth. It's difficult to search for because it used to be called "Progress" which throws off your search queries with non-relevant information.

I'm also open to a system that lets you define the regex's to look for to define your own syntax. Then it parses and gives you an output based on that.

答: We've had the same issue with an undocumented (and large) legacy codebase. We're planning to give RoboDoc a try, since it only seems to care about comments (Progress's c-style comments are supported).</p>

Title: Documentation utility for OpenEdge ABL


答:
it depends on the bug. the main concern is introducing new bugs.  Better to deal with a known issue rather then an unknown one.  If its simple, say a text change, or a simple logic error, we fix it, otherwise leave it alone.

One thing to note, tho, we are a small shop of 4 devs and an intern and the bug i fix is probably the bug i created.


问:
How to prevent piracy on software which is sold online?
When selling software online what's the most suitable/secure way to provide activation in order to get rid of pirates copies of the software? Is there any well-known software for this purpose?</p>

答: License keys by far.  There are some open source license key generators - Google lists a few right not top for that search.  Which you choose depends on what language you are using.</p>


答:
If the code is obviously wrong, the fix is fairly straightforward and you believe the risk of impacting the users is low, then go for it. It comes down to professional judgement.

You have to remember though that if you've found it then presumably the users haven't, or else they'd have reported it. Rather than spending time fixing an issue that may never be encountered by a user, you might be better off spending that time fixing issues that are causing your users problems now.


问:
Is it safe to use CamelCased file names?
I'm developing a simple CMS which I'd like to make it open source.

For the file structure, do you think it's safe to use names like:

```<code>AppData
FileUploads
</code>```

instead of

```<code>app-data
file-uploads
</code>```

?

Because I heard some servers have problems with the camelCase.

答:
Anytime you use mixed case in file names on *nix systems you are asking for human error to slip in. All lower case is easier to type in and not make mistakes. It also causes subtle errors and undefined type behaviors on Case Preserving but Case Insensitive file systems the default modes of NTFS and HFS+.

I would be more concerned about using the - character in file names than mixed case. - is a command line switch and I have have experienced some extremely subtle issues with shells and command line programs where this will need to be escaped, this was a long while ago and related to PowerShell parsing command line args to other command line programs, but still I wouldn't do it just to avoid tracing down silly things like that.

Traditionally _ is the preferred word separator in file and directory names.

There is actually a specification for Unicode Word Boundaries.


问:
Excellent knowledge of C++
I recently saw a recruiting page for a software company where one of the requirements was "Excellent knowledge of C++."

Now, I know this somehow implies as expert knowledge of C++, but where exactly does expert knowledge fit into. Is it the knowledge and experience of (let's say) eight years of programming in the language, having and knowing the ins and outs of a specific domain. Or, is it a more brush-up, surface approach to one or more domains and a at the same time a more detailed understanding of the whole language?

For example, you cannot be an expert at writing system drivers and game engines at the same time. So, where does this excellent or expert knowledge fit into?

答: I would expect such person to be current with the C++ standard, the newly added concepts, constructs and keywords. For example, he should at least know what an rvalue reference is and why it can be useful.</p>

Title: Excellent knowledge of C++


答:
If they say "Excellent knowledge" then you should be able to identify and use all of the language's features correctly- including those from the latest C++11 Standard which are currently universally supported (unfortunately, meaning Visual Studio is the lowest common denominator here). A person with Excellent C++ knowledge can author their own type traits or expression templates; they can build their own containers, algorithms, and allocators. They know when to use inheritance and when to use templates and when to use neither. They know how to use RAII to manage all their cleanup-requiring state.

Also, they can cope with interacting with C style garbage, as that is unfortunately still a part of the language.

Title: Excellent knowledge of C++

Body:
I recently saw a recruiting page for a software company where one of the requirements was "Excellent knowledge of C++."

Now, I know this somehow implies as expert knowledge of C++, but where exactly does expert knowledge fit into. Is it the knowledge and experience of (let's say) eight years of programming in the language, having and knowing the ins and outs of a specific domain. Or, is it a more brush-up, surface approach to one or more domains and a at the same time a more detailed understanding of the whole language?

For example, you cannot be an expert at writing system drivers and game engines at the same time. So, where does this excellent or expert knowledge fit into?


问:
Good continuous-integration solutions for Haskell projects
I am looking for a good CI solution for a haskell project. Ideally something that will work with git. Really basic need (so far) build and run tests after each check in. Some basic reporting would be great too, but it does not need to be anything real fancy. It should also support running javascript tests in a browser. (via Selenium or the like)

What have people been using for this?

答:
I was looking for good CI solutions for Haskell similarly and found no really easy to use ones, so I went on to create a plugin for a CI server called TeamCity. I've imaginatively called it 'Cabal TeamCity build runner'.

Find out more at the plugin's project webpage and at my blog post about it.


问:
How do professional software development teams deal with design complexity in non-trivial projects?
First, I realize this question may by somewhat long and vague and I apologize for this. This is probably a basic problem with a short name to anybody who's "got it", but as I find myself lacking in this regard, please bear with me in describing the problem.

I've been doing programming in this way or the other since I was about 11 years old. This means that I've been mostly teaching myself everything from the start. I received a technical education, but not strictly in Computer Science (I graduated with a degree in Photonic Engineering). We had programming courses of course, but this was mostly basic stuff for me and I didn't learn much new things. I've kept educating myself along the way for the joy of it and always knew I would pursue a career in programming, but all my projects were quite small at that time. I had no trouble keeping them in my mind and maintaining them.

Now, I find myself the lead on a team, but not in a corporate environment - I work for the university developing scientific software (in C++) for engineering applications. Suddenly the project is growing (relatively) big and I've trouble wrapping my mind around it most of the time. I'm losing a lot of time and effort on two things mostly:

When I have to  return to a section of code I've not worked on for a while, I have difficulty remembering how it worked. I spend a lot of time reviewing the header files for the relevant classes and reading the comments I placed along the way in the source files. I wish there was some form of "schematic" I could glimpse at and regain the picture more easily;

When I introduce changes, sometimes I realize half-way that what I'm trying to do will break things somewhere else (or worse, it shows up only at runtime as a surprise). I revert and start doing it differently, only to find out I neglected the influence on some other component. I wish there was some "architecture diagram" where I could see how things get done, how what I'm trying to do will influence other components and a way for me to plan in detail before I start implementing changes.

Most of the people I work with have similar stories as my own - strong technical orientation and sometimes great skills, but with no way of organizing their work. However, their projects are usually much smaller than mine so they cope somehow. Anyway, what that means for me is that I'm on my own and I have nobody to learn the good practices from.

I took up a postgraduate course in managing IT and while I find it quite satisfying, it's mostly targeted at non-programmers, teaching about project management methodologies, budget/schedule estimations, enterprise architecture etc. - not software design and planning as such. That's OK, I'm trying to learn that stuff too. Of course, some tools (like UML) and the types of sofware development processes (cascade, iterative, agile...) were introduced, but obviously not in great detail and I've a hard time deciding what I should pick and use (and to what extent).

I've been reading many questions and answers about software design on SO - there are many about doing it using this or that particular tool or methodology, and if I was convinced that UML documentation would solve my problems - I'd pick it up and start using it. But some people swear by it, others say it's useless. I'm looking for an answer on a higher level of abstraction - are there ways to solve the two problems I'm having, and how do you personally do it? What should I learn to be able to do it, possibly without being bound to one particular tool? These come and go out of style from time to time, and I expect their applicability varies depending on the type of the project.

Thanks a lot for reading, I was unable to say what I mean more briefly (lacking in software design experience and vocabulary).

答:
I have only been a professional developer for a short period of time, and struggled a lot with how to do this when I first started.  I was primarily self educated, even through University. Fortunately for me the people I worked with have a lot of experience and were able to educate me on the ways to manage and work on large projects.

One of the first things that had me do was to sit down and read clean code. Which is a fantastic book that helped me to understand how to write code that I could understand when I went back to it or that someone else could understand.

The second thing was to write good quality tests, Unit, Integration, Acceptance.  If your code is well tested you'll quickly know when you've broken something and quickly be able to diagnose the problem.  There are plenty of good testing resources out there on the internet, and I'm not sure which are the best to suggest to you.

My key points are Testing and Clean Code.


答:
The answer is software engineering.

That is for large projects you follow a set sequence of requirements gathering, process definition, specification, etc. long before any actual coding is done.

There are various methodologies used depending on the environment and culture. Enterprise type business tend to follow "Rational Unified Process" or similar, tech start ups usually go for some variation on Agile, government departments some overworked Waterfall methodoligy.

In all cases the process helps you define exactly what you are doing, and, towards the end of the project lets you prove you have done it.

Title: How do professional software development teams deal with design complexity in non-trivial projects?

Body:
First, I realize this question may by somewhat long and vague and I apologize for this. This is probably a basic problem with a short name to anybody who's "got it", but as I find myself lacking in this regard, please bear with me in describing the problem.

I've been doing programming in this way or the other since I was about 11 years old. This means that I've been mostly teaching myself everything from the start. I received a technical education, but not strictly in Computer Science (I graduated with a degree in Photonic Engineering). We had programming courses of course, but this was mostly basic stuff for me and I didn't learn much new things. I've kept educating myself along the way for the joy of it and always knew I would pursue a career in programming, but all my projects were quite small at that time. I had no trouble keeping them in my mind and maintaining them.

Now, I find myself the lead on a team, but not in a corporate environment - I work for the university developing scientific software (in C++) for engineering applications. Suddenly the project is growing (relatively) big and I've trouble wrapping my mind around it most of the time. I'm losing a lot of time and effort on two things mostly:

When I have to  return to a section of code I've not worked on for a while, I have difficulty remembering how it worked. I spend a lot of time reviewing the header files for the relevant classes and reading the comments I placed along the way in the source files. I wish there was some form of "schematic" I could glimpse at and regain the picture more easily;

When I introduce changes, sometimes I realize half-way that what I'm trying to do will break things somewhere else (or worse, it shows up only at runtime as a surprise). I revert and start doing it differently, only to find out I neglected the influence on some other component. I wish there was some "architecture diagram" where I could see how things get done, how what I'm trying to do will influence other components and a way for me to plan in detail before I start implementing changes.

Most of the people I work with have similar stories as my own - strong technical orientation and sometimes great skills, but with no way of organizing their work. However, their projects are usually much smaller than mine so they cope somehow. Anyway, what that means for me is that I'm on my own and I have nobody to learn the good practices from.

I took up a postgraduate course in managing IT and while I find it quite satisfying, it's mostly targeted at non-programmers, teaching about project management methodologies, budget/schedule estimations, enterprise architecture etc. - not software design and planning as such. That's OK, I'm trying to learn that stuff too. Of course, some tools (like UML) and the types of sofware development processes (cascade, iterative, agile...) were introduced, but obviously not in great detail and I've a hard time deciding what I should pick and use (and to what extent).

I've been reading many questions and answers about software design on SO - there are many about doing it using this or that particular tool or methodology, and if I was convinced that UML documentation would solve my problems - I'd pick it up and start using it. But some people swear by it, others say it's useless. I'm looking for an answer on a higher level of abstraction - are there ways to solve the two problems I'm having, and how do you personally do it? What should I learn to be able to do it, possibly without being bound to one particular tool? These come and go out of style from time to time, and I expect their applicability varies depending on the type of the project.

Thanks a lot for reading, I was unable to say what I mean more briefly (lacking in software design experience and vocabulary).


答:
When I have to return to a section of code I've not worked on for a
  while, I have difficulty remembering how it worked. I spend a lot of
  time reviewing the header files for the relevant classes and reading
  the comments I placed along the way in the source files.

Imagine how the poor guy who comes after you is going to feel -- he doesn't even have the benefit of having once known how your code works. Instead of trying to decipher your code, you should be reviewing the documentation that you wrote for the module in question. That documentation should offer a reasonably accurate view of what the module does any why. It's not "the module starts by initializing three arrays using a triple for loop...", but instead: "this module retrieves the data collected by the Fabulotron's main sensor, rearranges it into standard Neopolitan (chocolate, vanilla, strawberry) format, and delivers it to the Analysis module."

In a perfect world, you'd have a design document that sets out the various modules in the system and describes their respective responsibilities, and each of your modules could just refer back to that document to explain what they do: "This module provides the Fabulotron data collection service as detailed in section 4.8 of the design document: http://fabulotron.org/design/section4-8.html." If you don't have something like that, start writing down an overview of each module as you work on it. You don't need to write a book -- a few paragraphs are often enough to get you oriented.

When I introduce changes, sometimes I realize half-way that what I'm
  trying to do will break things somewhere else (or worse, it shows up
  only at runtime as a surprise). I revert and start doing it
  differently, only to find out I neglected the influence on some other
  component.

That might be an indication that your modules are too interconnected. The more independent you can make your modules/classes/units, the less likely it will be that you'll run into this kind of problem. Try to make the interfaces between modules as explicit as possible, and try to limit them to just what needs to be there. An interface is a contract -- if you know that some module lives up to its obligations as specified in the interface, you don't need to know anything else about it. That prevents changes in the module you're working on from affecting other modules.

I wish there was some "architecture diagram" where I could see how things get done

Using standard parts can help in this respect. C++ provides standard parts in the form of the Standard Template Library, and using those parts where appropriate lets you work at a higher level of abstraction. If you've written your own code to manage data structures like lists, you and those that follow you will constantly have to read the source to figure out what's going on. If you instead use standard parts provided by the STL, any C++ programmer will quickly be able to tell what your code is doing without digging into your data management routines.

Another kind of standard part comes from design patterns. They're standard concepts that can be used as a shorthand to explain how the relationship between two objects works.


答:
Face it: you will be unable to get rid of all pirated copies of your software.

Any anti-piracy system can be worked around. A sufficiently interested warez person/group could write a crack which bypasses the activation-related parts in your software. You could write a counterattack to this, and then it becomes a catch: pirates vs. your implementations of anti-piracy methods.

The most common systems uses license keys + validating them against a remote server, which provides little hassle to legitimate users. This can also be used to add value: only legitimate users will have access to some features - pirated copies can go into a crippled mode.

However, even this has its problems: what if your license servers go down for any reason, or your company goes bankrupt? So you will have to understand and learn to live with those limitations.

Since you're selling your software online, you could also use a license file which is encrypted and validated against a server. Optionally, adding some sort of machine identification (e.g. by hardware characteristics), to avoid people copying the same license file to different machines.

This Stack Overflow question can be interesting reading: I've found my software as cracked download on Internet, what to do?, and this Slashdot post: Ask Slashdot: Copy Protection Advice For ~$10k Software? is relevant too.

Title: How to prevent piracy on software which is sold online?

Body: When selling software online what's the most suitable/secure way to provide activation in order to get rid of pirates copies of the software? Is there any well-known software for this purpose?</p>


答:
Here are some high-level ideas for organizing large software systems. Most of my experience is in internet systems, but I think these ideas apply to engineering software.

Separate functionality into relatively isolated modular blocks. For example, you might have a module for each family of calculations your software provides.

Apply the MVC design pattern for the user interface, if there is one. Keep the interface and the model separated with well-defined boundaries.

Consider using layers to group modules. In an application that uses abstraction layers, each layer depends only on the layer below it.

When writing documentation, assume you will forget all of the implementation details. You will write a lot of documentation under this assumption - maybe as much as half of your code will be comments, but you'll be much less confused later.

Automated unit, integration and acceptance tests are great in some spaces, but C++ developers seem to have mixed feelings about them.

Draw heavily on design patterns. Besides being generally good ideas, design patterns provide a common vocabulary in software engineering. Calling a class a WidgetFactory is a concise way to communicate that it is a class that exists to make widgets.

It's been a long time since I worked with engineering software, so your mileage may vary on these suggestions. Good luck!


答:
You pretty much can't. Any pirate group who wants to crack your software will, for fun, and then give it to everyone else and there is nothing you can do. Microsoft can't keep Windows off torrent sites, and the UK government can't stop people visiting The Pirate Bay.

There's a reason that the new wisdom in many creative circles is to accept piracy and use it for free marketing- for example, release your old books for free to generate hype for a new one, which Neil Gaiman did to great success, and it's because there are no technical solutions to the problem of piracy.

Services like Steam which offer high-quality services are growing at a massive rate and still raking in embarassing amounts of money, long after everyone else said the PC market was dead due to piracy. Now it's the most vibrant market of games there is.

Piracy is not a technical problem, and there's no code you can write to solve it. It's a service problem. Those industries which offer strong digital services like games and books are doing fine, regardless of piracy. Those which are stuck in the 70s, like films, are not.

For example, can you download a film in full HD, watch and take it where and whenever you want, and re-download it to view whenever you want? That's service, but the MPAA don't offer it. So is it really a surprise that would-be filmgoers turn to torrent sites instead?


问:
Should I use a relational datamodel or Cassandra with ColumnFamily based indexes?
Currently we are working on some storage problems for log data from various servers and communication message logs (HTTP(S), XMPP). There will be many write operations and for read operations we will use search queries with filters.

Should we stick with the classic relation database schema solution or concentrate on Cassandra with ColumnFamily based indexes?

答:
Hadoop plays nice with NoSQL stores like Cassandra. I'm doing development on a side project that uses Cassandra and Hadoop. It was a bit of a pain to get set up, as there are some extra jars needed in the Hadoop installation to support Cassandra and not much documentation about how to do it. The Thrift API is a little awkward but still manageable once you're writing map-reduce code.

I think the decision comes down to the queries you need to run and the volume of processed data you're looking to store. Complex queries on small volumes of data push more toward MySQL. Simple queries or larger volumes of data push more toward Cassandra or HBase.


问:
How do companies keep websites hidden when in development?
I am new to this and also a new 19 year old PHP developer that just got hired so I am  unsure as to how this works.  Many companies when developing their websites keep their sites hidden from being indexed.  What are some ways html5/css and then php/mysql work is hidden from search engines? If I am not wrong, these are the techniques:

Offline development: using local storage to render html/css; not sure how PHP/mysql would work with that.

Using .htaccess to prevent access

Using VPN to prevent access.

答: Search engines work using spiders: scripts that crawl the web from one link to another.  If your site is new and no links to it exist from elsewhere, nothing's going to find you.  That, plus a robots.txt file configured to keep any spider that does somehow wander across your site from perusing it, should be enough.


答:
For polite crawlers (ie. any major search engine), you can offer a /robots.txt file with:

```
User-agent: *
Disallow: /
```

Of course that is only advisory, and won't disallow people from actually visiting the site if they know the URL. A better approach is to put the site behind a login of some kind if you need access from the internet at large, or simply host the server on an internal web server.

Title: How do companies keep websites hidden when in development?

Body:
I am new to this and also a new 19 year old PHP developer that just got hired so I am  unsure as to how this works.  Many companies when developing their websites keep their sites hidden from being indexed.  What are some ways html5/css and then php/mysql work is hidden from search engines? If I am not wrong, these are the techniques:

Offline development: using local storage to render html/css; not sure how PHP/mysql would work with that.

Using .htaccess to prevent access

Using VPN to prevent access.

Body:
For polite crawlers (ie. any major search engine), you can offer a /robots.txt file with:

User-agent: *
Disallow: /

Of course that is only advisory, and won't disallow people from actually visiting the site if they know the URL. A better approach is to put the site behind a login of some kind if you need access from the internet at large, or simply host the server on an internal web server.


答:
The best practice is to have an approximation of the production stack on your local developer machine. This typically includes the database, web server and your customized code. Do all of your development there. Never edit code on a production server.

When your business stakeholders are ready for the functionality to go live, push your code from your local machine to the production server. You might use a test server so internal stakeholders can preview your changes before you go live.

You should be sure to use a version control system to manage your code. Git and Mercurial are solid options.


问:
Methods to encourage good behaviour when using shared servers?
This question was prompted by a comment left on another question pointing to this article.

What Is Clean Code?

I was thinking about how that sentiment can be applied to shared resources (servers, etc).

What are some of the ways you've found that work to ensure that when others use a shared server they clean up after themselves?

Delete files / folders after one time use (after a fix or upgrade)

Leave the desktop clean of crap

Don't install software that they can use on their desktop

Don't create filesystem shares not needed for the solution

Yes, this applies mostly to a windows server environment, in a team of developers + support staff of about 25.

I know there are a few ways to tackle the problem, so what have you found that works?

答:
The problem is very similar to "dirty toilet" problem. The classic approach is a shield "please leave the cabin in a condition in which you would like to find it" (forgive me my poor English).

Combining this with a simple monitoring/mailing scripts should work fairly well.


答:
I'd highly recommend getting your hands on Enterprise Architect, which while not free, does offer academic pricing.  It's an excellent tool for diagramming out projects both at a macro and micro level.  It can also reverse engineer your source files into class diagrams, which would probably be a good start for you in documenting and reorganizing how your application goes together.

I'd also second @Klee's recommendations.  Don't be put off by supposed "agile" tools, as they are really just best practice items that are also handy (if not mandatory) if you are following an agile process.  But continuous integration (for example) is valuable no matter what your methodology.  Moreover, unit tests (cppUnit?) are your friends.  Unit tests should be very doable if you test the logic classes that are called by your UI, rather than testing the UI directly. There are also tools that could help you automate UI testing, but I'd try to get the back end stuff together first.

Good luck!


问:
What units are story points estimated in?
I am reading about a case study about a team that estimates tasks or "story points" as they call them based on the effort needed to complete them.

What the units are these "story points" estimated in? I believe this notion of "story points" stems from a process called "agile development."

答:
User stories are used in some Agile methodologies, but are not necessarily an "Agile" notion.

Stories are measured in "story points".  A "story point" is the unit.

Story points measure relative complexity of a story.  If one story is 2 points and another is 4 points, the latter is believed to be twice as complex/time consuming as the former.

If you do iterative development, you should be able to get a grip on how much you can complete in an iteration.  If you take the ratio of story points associated with what you complete and the duration of the iteration, you have what is called project velocity:  story points/iteration

Take a look at Mike Cohn's User Stories Applied for the most complete explanation of how this all works.


答:
I don't think there's one widely accepted definition of what constitutes "excellent" knowledge of C++.

It tends to be difficult to come up with a clean answer to what would constitute "good", "excellent", "superb", (etc.) knowledge of any language, framework, platform, or what have you. In many cases it's particularly difficult to draw a clean line between knowledge that's really useful, and basically knowing a lot of trivia.

This is particularly true in the case of something like C++ that's been around to decades, applied in many different ways and written in many different styles over that time. There's an almost frightening amount somebody could learn about the language that's almost entirely unrelated to using it to solve problems well. Knowing all the rules of things like overload resolution or partial ordering of function templates is only likely to be useful if you're trying to hire somebody to work on a compiler (or something very similar). I've used C++ since it first became reasonably widely available, and have yet to use (or even want) partial order of function templates in real code.

Though not technically responsive to the question asked, I hasten to advise anybody who includes such requirement in job ads to try to keep some balance in mind. I think excessive emphasis is often placed on programming languages, at the expense of things like problem solving ability and general algorithms. Knowing a programming language well helps one to express solutions well, but is usually of minimal help (at best) in designing the solution itself. A great solution poorly expressed will virtually always beat a mediocre solution, not matter how well it's expressed.

Title: Excellent knowledge of C++


答:
I believe that your problem has three dimensions

Programmer-Oriented

Program-Oriented

Program Maintenance - Oriented

Regarding the first problem, you might have programmers who don't understand the concept of what the program does (this often happens in corporate setups). But going by your question and the domain you are in, it seems that you and your team are in control of what the program does but just cannot translate it into a working program in quick time (To quote an example, I have heard about people having post doctoral degrees in Physics having trouble understanding pointers in programming and I am sure that Physics is much more difficult than C++). If that's the case, then your problem is mostly Program-centric (You must feel lucky enough that people around you can understand what your program is doing and can appreciate it).

In case of program-centric problems, one of my outrageous suggestions would be to move to a higher level of abstraction than C++ such as learning a new language as Python or Haskell (Python is quite easy to learn and if you are having good mathematicians, Haskell is just great). Moving to a higher level of abstraction would keep your code size down, easy to understand and maintain in the long run and effect changes swiftly. So you can have 10 lines of code in place of the original 50 lines of code. Also, having someone with expertise in computer programming would definitely help. Being in an university, you may also take the engage a few students in GUI and interfaces so that you could concentrate more on functionality. I also recommend the book Large-Scale C++ Software Design by John Lakos (Its quite a big book, you can become a proficient Python Programmer in the time you may took to read the book)

If you sort out of the first 2 dimensions of your problem, the third gets automatically solved. Since I believe you are working on a single large project, any decent project management software you get you through. Upfront planning is necessary. If you start coding straight away, you may get too much involved in the program that you would forget the big picture. Keeping things in mind wouldn't work for a big project. Put everything in paper (or in the computer). Use a wiki to share information. Regarding methodologies, I prefer the agile methodology (Simply, agile is a stylish name for incremental software development). I also suggest hiring someone with expertise in this area so that he takes care of these so that you could concentrate on your core program. The bottom-line here is that all project management methodologies are just a way to ensure the success of the program; so you can pick anyone that suits you and your team instead of selecting something that someone recommends the best. Also, the following software may also help you

Free Mind - Mind mapping software

Trac - Quick and easy software bug program and a wiki

MoinMoin - Quick wiki to enable knowledge sharing about the program

Though the above tips would take some learning curve its worth it in the long run. And finally, programming is easier than Photonic Engineering (though not C++ Programming)