问:
Limitations of Polymorphism in statically typed languages
I program mostly in statically typed languages, like C++ and Java.  A common strategy employed in languages like these to handle dealing with collections of objects which are related, but which need to employ specific behaviors, is to use polymorphism and inheritance hierarchies.  But Polymorphism only works when the Base class has a method (virtual function) which can then be overridden by every Derived class.  But there are often cases where a Derived class needs to have a method, and it doesn't make sense to place a method of the same name in the Base class, because it is very specific to the Derived class.

Let me give a concrete example that many of us can probably relate to: the HTML DOM.

Javascript programmers are quite used to doing things like iterating over collections of DOM nodes.  They take for granted the dynamically-typed nature of Javascript when they do something like:

```<code>node = document.getElementById("foo");
for (var i = 0; i < node.childNodes.length; ++i)
    doSomething(node.childNodes[i]);
</code>```

Something like this would be very messy to do in a statically typed language like Java, because inheritance-based polymorphism doesn't lend itself well to situations where Derived classes have methods which don't exist in the Base class.  For example, when iterating over the above HTML Nodes, we might find a DIV node, which has certain methods, and a Text node, which has certain different methods, and a TABLE node, which has its own unique methods - and it wouldn't make much sense for ALL of these various methods to exist in a common Base class "Node", because they are highly specific to each Derived type.  (e.g. a DIV node has no need of a "cells" method, but a TABLE node does.)

So, in a statically typed language, you'd be forced to fall back on something like Type Enums and a lot of messy down-casting to check what type of Node you have.  So basically you end up with messy code like:

```<code>Node node = document.getElementById("foo");
for (int i = 0; i < node.childNodes().length(); ++i)
{
   Node n = node.childNodes().elementAt(i);
   if (n.type() == Node.DIV_NODE) doSomethingWithDiv(((DivNode)(n)));
   else if (n.type() == Node.TABLE_NODE) doSomethingWithTable(((TableNode)(n)));
   /* etc... */
}
</code>```

This is similar to what C programmers do, and it's seemingly the sort of thing virtual functions were designed to avoid.  And yet, when you're faced with a situation where there are various different methods in a Derived class for which it doesn't make any sense to place in a common base class, you have no recourse but to resort to something like Type Enums.

So, how is this problem usually addressed in statically-typed languages?  Is there a better design pattern than Type Enums?

答:
Best fit would probably be Visitor pattern.

And if you need to do things like this, then you should re-think your object model, because having behavior, that works only on specific type should be part of that type.


问:
What non-programming books should a programmer read to help develop programming/thinking skills?
There are a lot of questions about what programming books should be on the programmer's bookshelf. How about non-programming related books that can help you become a better programmer or developer? It would also be interesting to know why they would help.

My first choice would be Sun Tzu's "Art of War" (however cliché), because it made it obvious that the success of any project depends on the strength of its weakest link (and warfare is a big project).

答:
Peopleware: Productive Projects and Teams
Tom DeMarco and Timothy Lister

ContentLicense: CC BY-SA 2.5


问:
What is agile methodology?
Can any one explain about the agile methodology in simple sentences?</p>

答:
To me the most important idea is this:

Requirements changes are going to happen because we are forced to design software at the nadir of knowledge about what is needed (the start of the project) and requirements will only become clearer over the course of the project.

Traditional (Waterfall) approaches try to mitigate this change by locking everyone into a contract at the start of the project by having them sign off on comprehensive specs. This may work as a CYA, but it doesn't make anyone happy to deliver something that doesn't meet the needs of the users especially if their objections are met with "Well you signed off on it!"

Agile Methods are designed to embrace the inevitable changes instead of shielding the development team from them. It does this in a number of ways, chief among them are iterative development and continual involvement by stakeholders in the process. In my experience it leaves everyone involved happier in the end, although it can be more uncomfortable for some management types who are hardcore planners.

Title: What is agile methodology?


答:
That you need this at all is a failure in your design. Subtypes exist to act as a refinement of your base type. If you need specific behaviors, then work with the specific type.

The better pattern is to let the collection supply the collection of specific types you need (ala CSS/jquery selectors).

ContentLicense: CC BY-SA 3.0

Title: Limitations of Polymorphism in statically typed languages

Body:
I program mostly in statically typed languages, like C++ and Java.  A common strategy employed in languages like these to handle dealing with collections of objects which are related, but which need to employ specific behaviors, is to use polymorphism and inheritance hierarchies.  But Polymorphism only works when the Base class has a method (virtual function) which can then be overridden by every Derived class.  But there are often cases where a Derived class needs to have a method, and it doesn't make sense to place a method of the same name in the Base class, because it is very specific to the Derived class.

Let me give a concrete example that many of us can probably relate to: the HTML DOM.

Javascript programmers are quite used to doing things like iterating over collections of DOM nodes.  They take for granted the dynamically-typed nature of Javascript when they do something like:

```<code>node = document.getElementById("foo");
for (var i = 0; i < node.childNodes.length; ++i)
    doSomething(node.childNodes[i]);
</code>```

Something like this would be very messy to do in a statically typed language like Java, because inheritance-based polymorphism doesn't lend itself well to situations where Derived classes have methods which don't exist in the Base class.  For example, when iterating over the above HTML Nodes, we might find a DIV node, which has certain methods, and a Text node, which has certain different methods, and a TABLE node, which has its own unique methods - and it wouldn't make much sense for ALL of these various methods to exist in a common Base class "Node", because they are highly specific to each Derived type.  (e.g. a DIV node has no need of a "cells" method, but a TABLE node does.)

So, in a statically typed language, you'd be forced to fall back on something like Type Enums and a lot of messy down-casting to check what type of Node you have.  So basically you end up with messy code like:

```<code>Node node = document.getElementById("foo");
for (int i = 0; i < node.childNodes().length(); ++i)
{
   Node n = node.childNodes().elementAt(i);
   if (n.type() == Node.DIV_NODE) doSomethingWithDiv(((DivNode)(n)));
   else if (n.type() == Node.TABLE_NODE) doSomethingWithTable(((TableNode)(n)));
   /* etc... */
}
</code>```

This is similar to what C programmers do, and it's seemingly the sort of thing virtual functions were designed to avoid.  And yet, when you're faced with a situation where there are various different methods in a Derived class for which it doesn't make any sense to place in a common base class, you have no recourse but to resort to something like Type Enums.

So, how is this problem usually addressed in statically-typed languages?  Is there a better design pattern than Type Enums?


答: This isn't a limitation in statically typed languages, there exists a solution to this problem which is to declare a common Interface between the various classes for the operations that you care about.  This allows you to do whatever you need to do, while still being type safe.</p>


问:
Why was the percent sign (%) chosen as the format specifier for the printf family of functions?
Everyone knows that, at least in C, you use the printf family of functions to print a formatted string. And these functions use a percent sign (%) to indicate the beginning of a format specifier. For example, %d means to print an int, and %u means to print an unsigned int. If you're unfamiliar with how the printf function and format placeholders work, or simply need a refresher, the Wikipedia article is a good place to start.

My question is, is there a particularly compelling reason why this was originally or should be chosen in the future as the format specifier?

Obviously the decision was made a long time ago (very likely for a predecessor of even the C language), and it's been more or less "standard" ever since then (not only in C, but also in a vast array of other languages that have adopted its syntax to varying degrees), so it's far too late to ever change. But I'm still curious if anyone has any insight on why this choice might have been made in the first place, and whether it still makes sense as the choice if one is designing a new language with similar functionality.

For example, with C# (and the other family of .NET languages), Microsoft made a slightly different decision regarding the operation of the string formatting functions. Although some degree of type safety can be enforced there (unlike with the implementation of printf in C), and therefore it is unnecessary to include an indication of the type of the corresponding parameter, they decided to use zero-indexed pairs of curly braces ({}) as format specifiers, like so:

string output = String.Format("In {0}, the temperature is {1} degrees Celsius.",
                              "Texas", 37);
Console.WriteLine(output);

// Output:
//     In Texas, the temperature is 37 degrees Celsius.
```

The documentation for the String.Format method contains more information, as does this article on composite formatting in general, but the exact details are rather unimportant. The point is simply that they abandoned the long-standing practice of using % to indicate the beginning of a format specifier. The C language could just have easily used {d} and {u}, but it didn't. Anyone have any thoughts on why, whether this decision makes sense in retrospect, and whether new implementations should follow it?

Obviously there's no character that could be chosen that wouldn't have to be escapable so that it could be included in the string itself, but that problem is quite well solved already by just using two of them. What other considerations are relevant?

答:
As @Secure notes, C's printf function is inspired by BCPL's writef function.  And if you look at the wikipedia page for BCPL, it has an example that shows that BCPL writef also used % to introduce a format specifier.

So we can infer that C used % either because BCPL did, or for the same reasons that BCPL did.  My gut feeling is that it was simply that % is one of the least commonly used ASCII characters ... or so the authors thought.  It is also likely that they didn't spend a lot of time in weighing the various alternatives.  At the time, both BCPL and C were obscure languages, and the authors most likely had more important things to deal with.

However, there is a minor spanner in the works.  While C was inspired by BCPL, it is not entirely clear whether the C borrowed BCPL I/O libraries or the other way around.  I dimly recall that BCPL's I/O libraries went through a process of evolution about the time that the infix byte indexing operator was added to the language.  (Actually, I think I know who would know about that.)

OwnerDisplayName: Cody Gray


问:
How to document and peer review design in scrum?
I am a relatively new developer in a small business (a team of 3 developers and an equally small QA branch) working on a medium-sized system.  The current iteration is still under 100k lines of code (server & client combined), but I could imagine that, in the long term, the total size could be 200 kLOC or more.  We are attempting to use Scrum for development, and we are working towards a CMMI level 2 appraisal.

We are adopting peer review methods to verify our software design and source code.  We elicit software requirements during the sprint planning meeting, and we document the software requirements in a master SRS.  This also gives us a start into the software design, but we don't have a formal method for reviewing design concepts, such as OO design, UI design, re-usable design patterns, and more.  For our source code, we are trying new techniques, such as using spreadsheets to document over-the-shoulder reviews and e-mail pass-around reviews, but it can be difficult for the reviewer to understand the design concepts from just looking at the source code.

(Please excuse me if I am misrepresenting concepts; we are attempting a lot of this from scratch.)

We are not averse to using UML to express classes, objects, software interfaces, event patterns, or other design concepts, but we are not sure when or how to peer review our design efforts.  Often, a developer can be 70+% complete with a user story and realize that a fundamental design element needs to be changed (and, subsequently, peer reviewed).

In an attempt to avoid open discussion on the topic and promote concise answers, I'll try to propose two specific questions:

Does anyone know of any good resources (i.e. books, papers, articles) on the best practices of peer reviewing design concepts?

I have read that the code itself is the (implementation of the) design.  Can the peer review of source code be utilized as the peer review of design?

Thank you.

答:
I think there are 3 things that help good design :

Pair programming. This way, you ensure that multiple people know how the design works and how to change it if it is no longer suitable for current requirements.

Unit testing. By doing TDD, you can ensure the design is simple enough to understand and subsequently change.

Time. In iterative development, the design evolves over time. Noone can tell you if the design is good or bad at the moment it is created. Only after the design changed few times can people tell if the design was easy to understand and change.

P.S. Ask yourself what will code review give to you. Agile is about empowering developers to give them freedom to define your own process. If you don't know what to expect from some kind of process, then there is high possibility you don't need that process.


问:
As a professional developer, is it acceptable to not write unit tests?
Just wondering on the pros and cons on TDD/automated unit testing and looking for the community's view on whether it's acceptable for professional developers to write applications without supporting unit tests?</p>

答:
I'm going to go out on a limb here and say it's mostly subjective and depends on your goals. tl;dnr: It's good to do, but being dogmatic about it is just going to lead to more problems.

TDD/Unit tests are going to improve the stability of your code.  They make it easier to make changes without knowing the code base really well, they let you refactor faster, they let you be sure that you're not doing something silly. Unit tests can also be a waste of time. Time that could be spent writing code. It can also let you fool yourself in to thinking your code works when it doesn't if you follow them blindly.

If you're working for a company that supports best practices and gives you the time to do implement them and you want an application that will last, then it's really best for everyone to use and practice unit tests and code reviews.  Having a QA team can be an acceptable substitute if the developers don't abuse it.  If you're writing a prototype (even a production one) it may be faster the just do smoke tests.

If you're working on something where a mess-up isn't going to be end of the world, less coverage is probably fine.  Financial transactions? Lots. If you have a team of strong developers who know the codebase, work well together and there's no turnover, then you probably need less coverage.  Etc.

So it's probably going to be some function of

Team size/turnover

Desired shelf life of the application

The application and how critical failures are

Time provided to implement the best practices relative to the development schedule

Team aptitude (this doesn't mean being a good programmer means you shouldn't write unit tests, but a team without junior developers might be able to fly by the seat of the pants with more success)

There are plenty of situations where not writing unit tests would be acceptable.  TDD is 'in' right now, but it's not a silver bullet.


问:
Have you ever found yourself using a specific tool in favor of another just because it looks better?
I found that this was the case with Eclipse.
When I first started learning Java a lot of people told me to start with NetBeans because it's easier, comes with a lot of predefined functionality and most of the configuration is done by default. Indeed it seemed like an easy IDE but I just hated the way it looked. The UI to me was horrible.

Then I downloaded Eclipse. I was pretty impressed with it. Everything looked shiny, fonts looked awesome and the UI in general was amazing compared to NetBeans'. So I stayed with Eclipse.

Has something like this ever happen to you? Should the UI be of such a relevance to a programmer, is this bad ? The problem of the UI extends to everything for me, not only IDE's (e.g. even on linux I have to customize the WM the way I want before starting working with it).

答:
Yes.  It may be a biased point of view, but I like working with pretty user interfaces, and if the developer has gone to the time and trouble to make his user interface pretty (and intuitive), I assume that he has taken the same care with the rest of his program as well.

As a developer writing programs for others, you should have the same concern about your own UI.

Obviously, where UI doesn't matter (as in command line programs and libraries), UI doesn't matter.


答: There's always type-checking either at compile-time or at run-time you just don't call it so. For example, the JavaScript fragment looks very impressive, but it hides the details about doSomething. Yes, it can accept any object and any object can have very specific set of methods, but this function should access methods and properties so assumes the methods it needs are there, otherwise it will give you run-time error. So you either previously filter objects for passing to be safe for doSomething or it will do this inside. The statically typed languages have luxury (or burden, depending on the POV) to do much of this work at compile-time leaving part to run-time with a little help of RTTI </p>


答:
Theory

There's a common misconception that unit tests are for testing "units".

Unit tests, likewise all other tests, test functionality. There's simply nothing else can be tested.

However, functionality of a complex system often can't be tested effectively.

Say, a user presses a "Delete" button, and nothing happens. Why? An error may be within a database, a connection may be broken, a core logic may malfunction, or even an operation may succeed but the interface did not update properly. Each layer may contain many functions that call one another, and it is not always clear where the error is.

Unit tests are based on a paradigm of separating components and test them individually.

Once again, it does not guarantee the whole system will work, but it simplifies testing.

TDD is not a requirement by itself. It simplifies coding by forcing a developer to answer first, "what am I actually going to code?".

Costs

Many think that by not writing tests, they save their time. Wrong. Thinking strategically, the cost of an error increase exponentially with time since appearance till detection.

Say you make an error in your code and detect and fix it the same day. The cost is $X.

Let's suppose the error remains undetected and goes to weekly internal build. Fortunately, the QA has detected it, raised a bug in bug tracker, the issue was a subject of 5-minute discussion on a meeting of 5 people, etc. Finally, you fix it. The cost is sum of manpower spent by everyone, and it may be $3*X in this case.

What if the error went to beta testing and involve more people? Let's say, $10*X.

If it stays undetected for a long time, went to 1,000 customers (hopefully, not to a million!), 10 of them detected it, they raised a discussion with your support staff, some may called your boss, your teammates attempt to reproduce it, etc, etc. Finally, the bug comes back to you, and you fix it. How much, in total? Well more than $50*X.

As you see, a bug will sooner or later come back to you (or your colleague). The only difference is when it happens and how much it would cost.

Unit tests shorten a lifecycle of bugs and therefore reduce costs.

Pro's

Unit tests let the developer to code better. As simple as that.

They let save your time;

They decrease costs;

Unit tests live together with the code they test. Upon any change request (which happens all time), the tests will adapt.

Con's

I can see a single excuse not to write tests. If you are writing a prototype, e.g. something that will never go to the other people. Or maybe you're writing something for a single use.

Title: As a professional developer, is it acceptable to not write unit tests?

Body: Just wondering on the pros and cons on TDD/automated unit testing and looking for the community's view on whether it's acceptable for professional developers to write applications without supporting unit tests?</p>


答:
Design is nowadays done solely in UX, they have vast resources on how to do design reviews.

There'll be a lot of people in 10 minutes telling you you're not doing Agile right, forget them: you're doing software right, software is not a religion, Agile is. As long as it creates good software quickly enough, it's fine.

Personally, I'd do data flow diagrams or anything which ensures that all the required information is available at any moment of time in the process. Data flow and its friends (flowcharts enriched with input/output handlings, etc) are a great way to capture missing elements.

Collaborative testing of UML is also easy: one of you prepares by drawing it up on paper first, then gathers the team and starts to draw it up on a whiteboard step-by-step, asking if anything is wrong with his train of thoughts.

In this process, make sure to

first, articulate the end-user goal of the given design

evaluate all the requirements, perhaps write them on the whiteboard

do the drawing

denote problematic spots while drawing, bringing emphasis on them.

We had these design sessions nearly every day when I was in a startup comparable on what you have now.

You can also do this on sourcecode, but always remember: a sourcecode is there to explain the problem to a computer. Dependent on language of choice and the problem at hand, the current language might or might not be effective in explaining it to humans as well.

Title: How to document and peer review design in scrum?

Body:
I am a relatively new developer in a small business (a team of 3 developers and an equally small QA branch) working on a medium-sized system.  The current iteration is still under 100k lines of code (server & client combined), but I could imagine that, in the long term, the total size could be 200 kLOC or more.  We are attempting to use Scrum for development, and we are working towards a CMMI level 2 appraisal.

We are adopting peer review methods to verify our software design and source code.  We elicit software requirements during the sprint planning meeting, and we document the software requirements in a master SRS.  This also gives us a start into the software design, but we don't have a formal method for reviewing design concepts, such as OO design, UI design, re-usable design patterns, and more.  For our source code, we are trying new techniques, such as using spreadsheets to document over-the-shoulder reviews and e-mail pass-around reviews, but it can be difficult for the reviewer to understand the design concepts from just looking at the source code.

(Please excuse me if I am misrepresenting concepts; we are attempting a lot of this from scratch.)

We are not averse to using UML to express classes, objects, software interfaces, event patterns, or other design concepts, but we are not sure when or how to peer review our design efforts.  Often, a developer can be 70+% complete with a user story and realize that a fundamental design element needs to be changed (and, subsequently, peer reviewed).

In an attempt to avoid open discussion on the topic and promote concise answers, I'll try to propose two specific questions:

Does anyone know of any good resources (i.e. books, papers, articles) on the best practices of peer reviewing design concepts?

I have read that the code itself is the (implementation of the) design.  Can the peer review of source code be utilized as the peer review of design?

Thank you.


问:
What's the "Memento" class for in the Memento design pattern?
In the Gang of Four's "Memento" design pattern, the Memento class looks like a useless wrapper that doesn't actually provide any value to me.

What is it for? Is there any reason you can't just pass around the String object (in the Wikipedia example)?

答:
The memento class is the one holding the different states you are dealing with in your object - it is what enables the "undo/redo" functionality.

The example you have linked to on Wikipedia is rather simplistic, where the "state" is just a string value. Consider that the state could be a bunch of properties that you may want to restore in "batch" and perhaps have several "undo" points with.


答:
In Java, you can use reflection to determine if an object has a particular method on it.  But it's better to collect your interface methods into an interface, and if you need to see if an object provides that interface, it's just a cast away.

Similarly, while C++ does not provide reflection, it does provide RTTI and dynamic_cast (or, better yet, you're using shared_ptr and dynamic_ptr_cast) which you can use to query a C++ object for an interface (which is a pattern expressed via multiple inheritance, rather than a specific language feature).


答: All statically typed languages have a built-in method which is quite equivalent, such as instanceof or dynamic_cast. DOM elements do have some shared interfaces which you could put in a base class. However, there are statically typed tools which are not inheritance- for example, boost::variant and boost::any which can provide dynamic typing between elements which are not related by inheritance.


问:
Make use of design patterns in C?
Design patterns are useful for object oriented languages.

But how can a non-object-oriented language such as C make of use them?

答:
Design patterns are not limited to certain languages or language families. You could come up with design patterns for any language or paradigm.

If you are referring to the GOF patterns: Have a look at stdout, stderr and stdinin C. That's the strategy pattern which does not seem so OO after all.

BTW:
Object Oriented Programming is not language dependend. Some languages make it easier, some make it harder, but you can program "object oriented" in any universal (as in 'not special purpose' like e.g. SQL) language.

Title: Make use of design patterns in C?


答:
From the wikipedia article on Software design patterns:

a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design

As you can see, there is no mention of object oriented programming here.

Design patterns apply to any computer language and sometimes are higher level (architectural patterns).

One example is for SQL - there is a even a book for SQL Design Patterns.

Title: Make use of design patterns in C?

Body:
Design patterns are useful for object oriented languages.

But how can a non-object-oriented language such as C make of use them?


答:
To reinforce the answers already given, a quote from GOF Design Patterns book itself:

Our patterns assume Smalltalk/C++-level language features, and that choice determines what can and cannot be implemented easily. If we assumed procedural languages, we might have included design patterns called "Inheritance", "Encapsulation" and "Polymorphism".

While the design patterns described there are geared towards object-oriented software, and certainly object-oriented programming languages are a natural fit for it, the concepts they embody are language agnostic. What varies is the work overhead you would have to invest to implement the required OOP feature or a workaround for it.

Title: Make use of design patterns in C?


问:
Best Practises in Android Resources Naming
There are a lot of android resources types: layouts, strings, drawables and so on. I understand that readability of it's names is important but can not create a table of rules how to name them in the best way.

Are there any best practices on that?

答:
I think a good practice is to name the resources uniting the  the activity name (if exists), object type or object name, and property name, using all chars in lower case. I believe that if the resources exists, it'll be used, so I would name my resources like below:

If I have a object used in a Activity:

mainactivity_button_id - using the type of object
mainactivity_button_ok_id - using the name of object

If the object isn't been used in a Activity or is used in various locals:

global_string_messagetext


问:
How much help should I give during technical interviews?
I'm asked to perform or sit in during many technical interviews. We ask logic questions and simple programming problems that the interviewee is expected to be able to solve on paper. (I would rather they have access to a keyboard, but that is a problem for another time.) Sometimes I sense that people do know how to approach a problem, but they are hung up by nervousness or some second-guessing of the question (they aren't intended to be trick questions).

I've never heard my boss give any help or hints. He just thanks the interviewee for the response (no matter how good or bad it is) and moves on to the next question or problem. But I know something about the rabbit hole that defeat and nerves can lead you down, and how it disables your mind, and I can't help wondering if providing a little help now and then would ultimately help us end up with more capable programmers instead of more failed interviews.

Should I provide hints and assistance for befuddled interviewees (and if so, how far should I go while still being fair to the more prepared candidates)?

答:
Depends what kind of programmer you want. An introvert who can write a great 20 lines of code on paper will look good to you boss. A software developer that can work on million line code bases within a team to produce good software efficiently will probably not do very well. I love these kinds of interviews as a candidate - they tell me a lot about how the boss treats his staff and what the work culture is. In a case just like this, as I left the interview, I said  "Thank you - Lets save us both a bit of time, if don't call me, I won't call you." When asked why, I pointed out that I did not want to work for a company who set me up to fail.

You approach is likely to get better selections for software development. You bosses approach would work well for rubbish collectors and the guys who hold the Stop/Go lollipops at road works.

Software development is a team effort, not a solo / mind reading / non interactive game. How many projects fail because the software does what was asked for, not what was wanted.


问:
How to properly design classes for a big project?
If we need to represent classes in a class diagram for a big project that is not completely designed yet, and the classes have to be actual tables in a database, how would we predict and design the classes?

Let's say we have a project that is going to have more than 15 tables, do all these tables need to be classes in the class diagram?

How would classes be designed in this kind of situation? The language that is being used is Java and the class diagram has to prepared in UML. I know how to design them, I just don't know if the tables should represent the classes in this case.

答:
You should start with use case modeling and process modeling, but never with class diagrams.

Processes will tell you how the entities relate to each other.

In fact, you don't need all your persistent classes in one diagram usually - there's no story behind that! It's a nice family picture, perhaps it'd be good to help trace system elements later, but you are usually told, as a rule of thumb that an UML diagram should never contain more than 15 elements, as it makes design errors easy to miss.

Imagine your system as a Rubik's cube. In order to understand how to solve the Rubik's cube, you usually look at one, two, or three sides. You don't flatten the cube out!

Every single diagram should tell a story about your system: perhaps it tells the taxonomy of a family of classes, perhaps it tells how the system is used by the different actors, perhaps it tells how a certain scenario is played, perhaps it tells how a certain set of objects interoperate with each other in order to solve a problem, or how a component is structured internally.

That's why you usually should have a lot of small diagrams: perhaps you could ask a special tool to bring them together, but since you're a human, and most of your workmates are also humans, you'll never be able to grasp the whole system at once.

One of the biggest challenges in software engineering (as opposed to other methodologies, like Agile) is to accept that your own skull is limited. That you can grasp around 10+-5 things, and that's it. You either have to zoom in or out, hiding details, you have to turn the cube, or do something in general.

I'm yet to find an application which was started designed as a single, huge class diagram and didn't contain serious design errors, visible just by looking at the diagram for 10 minutes, or - more usually - looking at the changelogs, where serious changes were had to be made.

I usually tell people to draw the data flows for each of the use cases first: what data comes in, what data goes out, what data is needed in order to get the results. Then ask what kind of pain points there can be for each step.

Shooting a big family portrait of persistent classes - this is rather limited. Of course, you should collect the classes needed to be persisted over these flow diagrams, but perhaps it's better if a tool does it for you.

Design is not about how to solve a particular implementation. Deal with that later. First,find out, what kind of classes you need. An UML class is an abstract construct: it might not even translate for Java classes ever. An UML class is just a saying: "well, we will have things which have these meaningful features from our current viewpoint". A Java class is a way to tell the machine how to allocate memory and for what purpose.

Once UML tells you what you need, then, only then you can start thinking about how to realize this.

And yes, use Domain-Driven Design (the blue book with the same title is quite nice).

(And I know I'll be blamed by the Agile guys that I'm not Agile enough, but let's not deal with this, we're talking about UML. Most of the guys who do Agile never really understood UML, and they don't want to care about this question I hope.)


问:
Licensing for hosted open source and 3rd party libraries
Context:

We have an ASP.NET MVC3 codebase, hosted on CodePlex, currently in the "setup period". This codebase uses several NuGet packages (without changes or additions to the source, just "using" the packages directly), amongst others:

jQuery (MIT or GPL)

Modernizr (MIT or BSD)

log4net (Apache License, version 2.0)

Ninject (Apache License, version 2.0)

NHibernate (GNU Lesser GPL)

NUnit (custom? based on zlib/libpng license)

Moq (BSD 2-Clause License)

From the 10 licenses you're allowed to pick on CodePlex I would like to use a permissive license, probably the Free-BSD one, if possible.

Questions:

Does my choice of license depend on the packages that I use? If yes, in what way?

Can I host my code on CodePlex, including the packages and all? Anything to consider here?

Any other considerations for this type of setup?

Note:

My particular setup (CodePlex, NuGet, the specific packages, etc) mentioned above is meant for context. This question and any answers are probably most useful to others if it's understood as about any OS hosting provider and 3rd party libraries in general (if at all possible).

答:
If your software is a derivate work of any of the packages (this is a bit of a grey area[1]) then you'll have to pick a license that is compatible with that package. That said, permissive licenses, like the Free-BSD license, impose so few restrictions that they're compatible with almost any license.

All of the the packages you listed, except NHibernate, have permissive licenses, so you should be fine with almost any license with them. NHibernate uses the LGPL which explicitly allows software under other licenses to use it as a library, so you should be fine with that as long as you follow the terms of the license if you distribute it.

[1] : The GPL, for instance, claims that programs that link to GPL software is a derivate work. Not everyone agrees with this (the author of CLISP, for instance) and as far as I am aware, it has never been tested in court.


问:
What is the Mars Curiosity Rover's software built in?
The Mars Curiosity rover has landed successfully, and one of the promo videos "7 minutes of terror" brags about there being 500,000 lines of code. It's a complicated problem, no doubt. But that is a lot of code, surely there was a pretty big programming effort behind it. Does anyone know anything about this project? I can only imagine it's some kind of embedded C.</p>

答:
It's running 2.5 million lines of C on a RAD750 processor manufactured by BAE. The JPL has a bit more information but I do suspect many of the details are not publicized. It does appear that the testing scripts were written in Python.

The underlying operating system is Wind River's VxWorks RTOS. The RTOS in question can be programmed in C, C++, Ada or Java. However, only C and C++ are standard to the OS, Ada and Java are supported by extensions. Wind River supplies a tremendous amount of detail as to the hows and whys of VxWorks.

The underlying chipset is almost absurdly robust. Its specs may not seem like much at first but it is allowed to have one and only one "bluescreen" every 15 years. Bear in mind, this is under bombardment from radiation that would kill a human many times over. In space, robustness wins out over speed. Of course, robustness like that comes at a cost. In this case, it's a cool $200,000 to $500,000.

An Erlang programmer talks about the features of the computers and codebase on Curiosity.

ContentLicense: CC BY-SA 4.0


答:
First, if you want something similar to what you'd have written in javascript, the if statements would probably go in the body of the doSomething method rather than outside. It's not cleaner, just closer to your javascript example.

That being said, you can do the exact same thing in a static language using method Overloading. Actually, it's even better : you'd remove all the if statements alltogether!

Let's say both DivNode and TableNode inherit from a Node type.

Then, if ou write the 3 following functions, you don't need any for loop or casting :

```<code>private void doSomething(Node node) {
   throw new RuntimeException ("This method should never be called !");
}

private void doSomething (DivNode divNode) {
   // function body
}

private void doSomething (TableNode tableNode) {
   // function body
}
</code>```

Body:
First, if you want something similar to what you'd have written in javascript, the if statements would probably go in the body of the doSomething method rather than outside. It's not cleaner, just closer to your javascript example.

That being said, you can do the exact same thing in a static language using method Overloading. Actually, it's even better : you'd remove all the if statements alltogether!

Let's say both DivNode and TableNode inherit from a Node type.

Then, if ou write the 3 following functions, you don't need any for loop or casting :

private void doSomething(Node node) {
   throw new RuntimeException ("This method should never be called !");
}

private void doSomething (DivNode divNode) {
   // function body
}

private void doSomething (TableNode tableNode) {
   // function body
}


答:
Yes

I use VIM because it's beautiful.

Aesthetics mean a lot. If the UI is cluttered and ugly it will impact how you use the tool. NetBeans might do everything, but it looks awful and runs slow. I don't see many people using it.

Title: Have you ever found yourself using a specific tool in favor of another just because it looks better?

Body:
I found that this was the case with Eclipse.
When I first started learning Java a lot of people told me to start with NetBeans because it's easier, comes with a lot of predefined functionality and most of the configuration is done by default. Indeed it seemed like an easy IDE but I just hated the way it looked. The UI to me was horrible.

Then I downloaded Eclipse. I was pretty impressed with it. Everything looked shiny, fonts looked awesome and the UI in general was amazing compared to NetBeans'. So I stayed with Eclipse.

Has something like this ever happen to you? Should the UI be of such a relevance to a programmer, is this bad ? The problem of the UI extends to everything for me, not only IDE's (e.g. even on linux I have to customize the WM the way I want before starting working with it).


答:
This is what interfaces are for. You shouldn't be using a base class for this. Base classes signal a relationship of the A is a B kind; interfaces say A can do X.

Using the traditional animal example: a Bee is an Insect, which is an Animal. A Sparrow is a Bird, which is also an Animal. Both bees and sparrows can fly, but not all animals can fly, and what's worse, not even all insects nor birds can fly. So where does the fly() method go? Animal? Or should we restructure our class hierarchy so that Bee and Sparrow have a common ancestor? But if we do that, we cannot have a common ancestor for Penguin and Sparrow that provides a beak without either making penguins fly or equipping bees with beaks (draw the class hierarchies out on paper if you don't get it).

The solution is to have a FlyingAnimal interface, which provides the signature for fly(); whenever you need a collection of flying animals, declare it as Collection<FlyingAnimal>.

Using interface inheritance, you can group interfaces into 'super-interfaces', e.g., you can have an FlyingAndWalkingAnimal which inherits fly() from FlyingAnimal and walk() from WalkingAnimal.


问:
MIT License Question (download somebody else's code and throw it on github)
Sometimes I use plugins and 3rd party libraries, and one thing that drives me crazy is when these libraries are not versioned. So, if I download it, make some mods to it, I am the only person in the world who can benefit from it... well, until I version it myself.

My question is simple: if a library I find online has an MIT License, would it violate the license if I download it, modify it, and put it on github?

I'm not trying to pass it off as my own, I'm just trying to help the community benefit from my work. A lot of libraries are pretty nice, but for some reason they aren't versioned...

Thanks!

答: From my understanding (I am not a lawyer) for the MIT license that would be fine as long as you maintain the license and the original copyright notice.</p>


答:
I think sometimes the mental toll that certain UIs take is very subtle. I will often find myself switching between different UI experiences based on what kind of task I need to perform.

If I need to quickly get in-and-out of a lot of different config files, vim on the terminal is perfect. If I need to do a lot of typing, but don't need code-completion or  debugger, TextMate or MacVim fit the bill. If I'm working heavily on multiple classes at once, and need to run tests or debug, I'll boot up the IDE.

I honestly believe that there is such a thing as too much interface. In my IDE, I will often find myself staring blankly at the project-pane trying to find the next file I need to work in. For me, when my fingers leave the keyboard, I tend to start to lose focus. Anything you that forces you to make a choice that isn't relevant to the problem you're working on is going to steal focus and concentration. Often, IDE are simply too widget-heavy.

We should know by now that in software, aesthetics and function are usually tied together.


答: MIT license is pretty permissive, most things you want to do with the code should be acceptable (IANAL, though).  It would definitely be considered good form to maintain attribution to the original author of the code though, ("Originally written by Freddy Foobar, modifications by Betty Bazquux", for example)</p>

Title: MIT License Question (download somebody else's code and throw it on github)

Body:
Sometimes I use plugins and 3rd party libraries, and one thing that drives me crazy is when these libraries are not versioned. So, if I download it, make some mods to it, I am the only person in the world who can benefit from it... well, until I version it myself.

My question is simple: if a library I find online has an MIT License, would it violate the license if I download it, modify it, and put it on github?

I'm not trying to pass it off as my own, I'm just trying to help the community benefit from my work. A lot of libraries are pretty nice, but for some reason they aren't versioned...

Thanks!


问:
How to make profit from freeware application?
The components that I'm using are restricting me from selling the application. Any ideas how to still make a profit from it? I've seen some freeware apps which set your homepage to some site, I guess they get paid for that.</p>

答: It depends.  If you purely want to make a living from it then it's not a good path to follow.  However, if you wanted to make enough money to cover hosting costs etc, your best bet is to use PayPal's Donation button.  That way you can slowly receive donations for your work.</p>


问:
How valid is ITJobsWatch data?
(I've been wondering all day whether to ask this question here - my biggest concern would be that it would be seen as off-topic, or not relevant. It's not relevant to the US, this is true, but it is VERY relevant the UK market.)

My question is: do hiring managers / IT decision makers in the UK use data from ITJobsWatch in their decision making process, how valid is the data and how accurate do you perceive it to be. (as a secondary, more worldwide question: do people use salary aggregation sites in their decision making/negotiation process)

A couple of disclaimers! I don't work for them, I have nothing to do with them. I invite (genuine) comments from representatives of the site about how they collect the data (I've read the small paragraph on their website already). I also wouldn't consider that I'm pimping the site here - I imagine any UK hiring manager worth his stuff will already know about it!

I've been asked whether the data on the site is valid and relevant, and I'm curious as to the response from the UK market.

答: the answer is yes it is used and yes it is useful. It gives an accurate reflection of how salaies for certain roles are 'trending'. If it 'doesn't make a lot of sense to you' then the site isn't going to be useful, but without being too harsh it seems that that's more a reflection of your lack of understanding that anything else. If you can understand it, then it's useful. The fact is, this table, with info about RECENT salaries, is a more accurate marker of salaries that someones previous salary, which in the fluctuating climate is not particularly useful as a barometer.</p>

Title: How valid is ITJobsWatch data?


问:
What is the best way to learn how to develop drivers?
At some point in my career I would definitely like to get involved in some embedded programming.  I was thinking that starting out with developing some drivers would be a good place to develop my abilities in the regard.  I'm open to doing so on either windows or linux platform (eventually will want to probably attempt both).  What tools would you recommend that I look into to get me started on this project?  Any other resources that you have found to be helpful (i.e. books, websites, programs, etc)?  Any advice/recommendations? Thanks!</p>

答:
I started because my job required it so I started reading hardwards and OS specs.

Seriously though. I need to write a driver. So I learned the hardware API, then the OS driver specs. Got the sample source code of drivers and (in my case it was the Windows NT DDK)  development kit and started coding and learning.

The trick I found  was to actually write one and hone it to do what I wanted which was to link to a 16bit process. It was tough learning process which I beleive would have be harder if I actually didn't have to produce commercial driver.

In your case I'd definitly recommend getting some programmable hardware like the Arduino perhaps the Rasbery PI and start making the hardware obey your command.

Caveat: I'd already done Assembler for years so the machine interface wasn't new to me.


问:
What do you look at first: the code or the design?
If you've just been introduced to a new project, what's the first thing you look for to get an idea of how it works?

Do you look for the design first?  If there is a design, what do you look for in it? Class diagrams or deployment diagrams or sequence diagrams or something else?

Or do you go straight for the code? If so, how do you understand how the different layers interact?

答:
I start by setting up a developers system. I use the documented procedure. This lets the cat out of the bag about how much the documentation is in sync with reality.

It also tells me what the dependencies are. This matters.

Now that I've got a developers setup, ( and I mark up the setup document with corrections as I go) I build a version. I end up asking questions all through this phase.

Now it's been built, I do the introductory exercise from the user manual. This tells me roughly what the system really does.

Now I have a partial clue about the system, I read the design documents, which I now believe in proportion to how wrong the documents have been so far.

Once I get to the actual behavioral documentation I can start looking into the code and seeing what's really there. They never line up, but I now know how much to believe.

Then I look at the IDE output for "todo" and "fixme" comments.
Things like  "fix in version 2.0"  are tip-off's too.

So it's all about learning the veracity, and as people point out, separate design documents are rarely up to date or correct, but it does tell you what people were thinking at a point in time. And of course, those people are probably not around to interrogate.


问:
Software rewriting alternatives
We have a legacy system to bring up-to-date because:

It uses an unpopular (amoung our users) non-sql database (Btrieve)

Provides only a text interface

Is written in Turbo Pascal (but compiled in free pascal) which is hard to recruit/retain developers to maintain it

To give you an idea of the scale, the code base is 15MB over 756 files.

All the studies I've looked in to such as those listed here suggest it is vastly more expensive to rewrite than to adapt what you have.

If I thought we could encapsulate the legacy stuff behind a web service and then design new client(s), that would be fine. But I'm stuck with this legacy database which 90% of those 756 files reference.

We even attempted replacing the low-level DB code with code to convert to SQL, and while it worked fine, it was too slow because the code is still accessing records one at a time generating far too many SQL statements than it would need. Plus this approach does not allow any improvements in the DB design.

When faced with such an upheaval as replacing the DB that is referenced so heavily in code and the other requirements listed, can it still pay to reuse or are we better off treating the new version as a whole new product and just listing the current systems abilities as requirements (bearing in mind no handy requirements doc exists for the current system).

I know it's too hard to give a definitive answer on this, so just any advice would be appreciated especially if you've experienced a similar situation.

答:
Your suggested approach - encapsulate the legacy stuff behind a webservice is a good practice to follow. it will ensure that business logic will stay same as it was, and minimize the development time for better looking application.

Consider some No-Sql databases  currently available in the market.

Currently, we are using  Raven DB for the project needs. Although, it is quit odd to start getting into it. However, it seems quit a good match for a pure DDD approach.

Here is a post explaining strong sides of Raven DB among the No-Sql databases - Why Raven DB?

Title: Software rewriting alternatives


答:
Its true that re-writing is the most radical approach and should be avoided whenever possible.

Try to create an intermediate level between your application and the DB. It needn't be a separate project necessarily, but all DB requests should go through it. If you manage to do this first step, it will be easy to change the DB any time, you'll just need to re-write one single module of your project.

Once this is done, try to divide your project into small logical pieces and re-write ("translate") them one after another (if you really think it can't be avoided). If you have unit-tests, they would be a great help.

Title: Software rewriting alternatives

Body:
We have a legacy system to bring up-to-date because:

It uses an unpopular (amoung our users) non-sql database (Btrieve)

Provides only a text interface

Is written in Turbo Pascal (but compiled in free pascal) which is hard to recruit/retain developers to maintain it

To give you an idea of the scale, the code base is 15MB over 756 files.

All the studies I've looked in to such as those listed here suggest it is vastly more expensive to rewrite than to adapt what you have.

If I thought we could encapsulate the legacy stuff behind a web service and then design new client(s), that would be fine. But I'm stuck with this legacy database which 90% of those 756 files reference.

We even attempted replacing the low-level DB code with code to convert to SQL, and while it worked fine, it was too slow because the code is still accessing records one at a time generating far too many SQL statements than it would need. Plus this approach does not allow any improvements in the DB design.

When faced with such an upheaval as replacing the DB that is referenced so heavily in code and the other requirements listed, can it still pay to reuse or are we better off treating the new version as a whole new product and just listing the current systems abilities as requirements (bearing in mind no handy requirements doc exists for the current system).

I know it's too hard to give a definitive answer on this, so just any advice would be appreciated especially if you've experienced a similar situation.


问:
Lead Programmer definition clarification
I have been working on PHP and MySQL based web application for more than 5 years now. I started my career as an Intern, and worked my way up through Jr Developer and Software Developer to Sr. Software Engineer (Team Lead), and that's what I am nowadays.

I was looking at the link at Wikipedia regarding who is a lead programmer. The link states the following:

A lead programmer is a software engineer in charge of one or more
  software projects. Alternative titles include Development Lead,
  Technical Lead, Senior Software Engineer, Software Design Engineer
  Lead (SDE Lead), Software Manager, or Senior Applications Developer.
  When primarily contributing in a high-level enterprise software design
  role, the title Software Architect (or similar) is often used. All of
  these titles can have different meanings depending on the context.

My current job responsibilities are more or less like a Development Lead and to some extent near Software Architect because I usually design the core structure of new products, and manage 2-3 project simultaneously while assisting other teams regarding the structural design of their projects. I am usually on call with clients along with project managers. I code most of the time when my team is stuck somewhere, has a heavy workload, is integrating some third party API, etc.

Does what I do qualify for a Development Lead title in accordance with my above mentioned job descriptions?

答:
Well, Everybuddy can give their own explainations for definition according to their duties. But I understood one thing "ITS ALL DEPENDS ON ORGANIZATION WISE HIERARCHY LEVEL"

Level 1
Software Trainee

Level 2
Software Engineer/Software Developer

Level 3
Sr. Software Engineer/Sr. Software Developer (lead programmer is here around word)

Level 4
Team Lead

Level 5
Project Manager

There can be more levels in between according to organization. But these main layer normally seen in all organizations.


答: It's quite silly to prefer form over function, in my opinion. That's not to say the two can't be combined, but since the question is whether we prefer a certain program just because it looks better, the answer is no.


答:
Before making any decisions about what approach that you would like to take, I always feel it is important for the development team to always consider the option of a complete rewrite as a possibility, even though many think it is nearly always a bad choice.

Take some time to write up some high level milestones that must be achieved, and make some very high level architectural decisions about what core technologies will comprise the new software.  At this point make a rough estimate of the time you would feel is needed to complete such a project.  It is good no matter what choice you make to at least have a good idea what a rewrite effort will cost you in terms of time and money.

The other very important cost of a rewrite that many neglect to consider can be the exorbitant cost of deployment in both money, time, and man hours.  Users get comfortable with using older flawed systems, they memorize the quirks and bugs, the workarounds become part of their routine, they memorize the hotkeys to quickly perform their favorite tasks, they become surprisingly productive over time.

I have seen rewrites that by all accounts should have been a major success, the development came in under time and under budget, the major issues no longer exist, the newer system was easier and cheaper to find talent to maintain, the learning curve was smaller... the only major problem that had been neglected was user adoption and Agile based user involvement.  When they were told that their text based mainframe system had been replaced with a GUI based desktop client, they were unfamiliar with it and productivity dropped.  User input only came from a single individual who no longer performed these job functions so important key combinations, lack of keyboard support, hot keys, poor tab ordering, and the need for a lot of point and click mouse interaction caused productivity to plummet.  Sure they would have gotten comfortable and productive eventually, and without the major bugs and improved performance they would have been vastly more productive with the new GUI based system once the kinks were worked out.

What unfortunately happened is that there was open revolt against the new system, and despite management buy-in, they could not force the users on the ground to adopt it.  The project failed at deployment.  The hidden costs and risks of deploying and training for a rewrite are important to consider when comparing to the increasing cost of maintaining the legacy system.

Another option to consider is to look into the technologies that are causing the most grief, most expensive to license, hardest to find talent for, inherently buggy, etc.  A good start might be to rewrite small pieces of the application in such a way as to decouple the core components.  Once this is done it is easier to swap and replace components as time becomes available to rewrite them, and this greatly reduces the risk of refactoring in general.

If I were you I would start with replacing just the database.  You can use one that is more popular and that is more easily maintainable by the talent pool.  As you replace the schema you can slowly start seperating database access specific logic into seperate modules, making it easier to decouple the business logic from the database implementation and database access code.  It can be justified in improved performance, decreased cost of maintainability, and quicker turnaround.

Title: Software rewriting alternatives


问:
Database-stored configuration management
Developing database-backed software, often one finds it convenient to store stuff in the database which one might traditionally express in code, but which is useful to store in the database (so that it can be changed without requiring a reload of the application).

For instance, one might have processes which send automated email using a template; it makes sense to store this template in the database, so that the text can be tweaked by the users without having to change the code/redeploy/etc.

However, these templates are "important"- they are required for the correct operation of the system, and for instance, if they become malformed or missing, the underlying functionality would probably stop working. As they live now in the database, they don't outside version control- you might add audit tables to have change history about this information, but revisions/etc. are separate and independent from your main code's revisions.

How do you handle this kind of stuff? Not putting this kind of stuff in the database and make changes go through development/change control/deployment cycles? Or something else?

答:
It is better to keep templates in DB for the reason you listed in your question and also because you might have a huge number of templates which needn't be loaded at once.

An easy way to tie templates with app versions is to tag them. The app should have a static field indicating which version of the template is up-to-date. That field could be a
number, string, date, whatever (number is the best, it is easier to search with in DB).
The Template table in the DB should also have a column for the tag of the same type. So when requesting for a template the app could add another condition specifying the tag.

There could also be a default template (the newest one, for example), if the new version of the app doesn't need an updated template. Or the new version could have the same tag as the previous one.


答:
If I got you right, you have data which may be edited by your users (at least, to some degree), but this data is "required for the correct operation of the system" and "if it becomes malformed or missing, the underlying functionality would probably stop working".

There are some things you can do here:

forbid your end users to manipulate that data. You can store those data in the database, but your program does not offer any functionality to change it. The only one who is allowed to change that data is, for example, an update installer provided by you when a new release of your software gets deployed. Or, you allow your end user copying of that data and let them manipulate the copy, but never the original thing

allow only some special users (admins) to change that data in the database (but beware, admins can make errors, too)

add a functionality in your application (or only for admins) to restore that data to its original state provided it becomes malformed or missing

provide a functionality to check if the data is malformed or missing; run this check after someone changes the data, and (more important): run it whenever your program tries to use that data

separate the parts of the data which can be safely changed by the end user clearly from the parts which cannot (and don't allow users to change the latter)

try to make your updates "intelligent": when you deliver a new release, including an update installer for your database, the installer should expect that data like email templates was manipulated since the initial installation, and act accordingly

It should be obvious that each of these suggestions can be combined with each other.

Title: Database-stored configuration management

Body:
Developing database-backed software, often one finds it convenient to store stuff in the database which one might traditionally express in code, but which is useful to store in the database (so that it can be changed without requiring a reload of the application).

For instance, one might have processes which send automated email using a template; it makes sense to store this template in the database, so that the text can be tweaked by the users without having to change the code/redeploy/etc.

However, these templates are "important"- they are required for the correct operation of the system, and for instance, if they become malformed or missing, the underlying functionality would probably stop working. As they live now in the database, they don't outside version control- you might add audit tables to have change history about this information, but revisions/etc. are separate and independent from your main code's revisions.

How do you handle this kind of stuff? Not putting this kind of stuff in the database and make changes go through development/change control/deployment cycles? Or something else?


问:
What Exactly is a Model Relative to the ModelAndView Class in Spring
What exactly does the "Model" part mean? Is it the same as the domain model? I've read that it's a map, but I'm having a hard time understanding the concept.</p>

答: I've always treated it as a View Model as opposed to a pure Domain Model, the ModelAndView class name lends itself to that distinction as well as the use of a Map to drop various bits of model data in for viewing purposes.


答:
We've actually brought important configuration tables under source control.  We're using Red Gate Data Compare which works great.  But if it's too expensive, it's easy to write a custom tool that exports configuration tables to a text files.  Those text files can then be versioned with source control.

An hourly job checks if there are changes in the database that are not in source control, so we are aware if anything changes outside the regular process.


答:
Create one table ::: Templet Table ( Templet ,ModifiedDate , Version ,UserName  , Published (Y/N) ) .

Published : Read the templet into app only when published=Y ,Version: To maintain the  version of the document .

And create on admin UI to manager the templets .Maintain your admin code in such a way that only one published templet should be there for one templet .


问:
strategies to keep tabs of memory leaks in non memory-managed languages
When it comes to non memory managed languages such as C, C++ or Fortran (my case), it becomes increasingly difficult to keep track of memory allocation/deallocation, especially when ownership must be shared. I implemented refcounting for my objects, but this makes it even more complicated as there's no place where an object gets deallocated. Every reference decrement is a potential deallocation point.

So it's now more and more difficult for me to track down memory leaks. I was wondering about some established techniques to deal with memory management in non-memory managed languages, apart from valgrinding your way around.

Edit: I am more interested in active programming strategies (which are general).

答:
Tooling is important

There are different tools that may help you. Personally i was using Visual Leak Detector 2 years ago, though it can cause large delays when large blocks are leaked (it displays the contents of the entire leaked block).

If you don't want to recompile (as Visual Leak Detector requires) I would recommend WinDbg, which is both powerful and fast (though it's not as easy to use as one could desire).

Here you are some references on memory leaks and memory management in general:

Memory Leak Detection Using Windbg

Memory Leak Detection in MFC

Common WinDbg Commands (Thematically Grouped)

C/C++ Memory Corruption And Memory Leaks

The Memory Management Reference

Using LeakDiag to Debug Unmanaged Memory Leaks

Heap: Pleasures and Pains

Coding standards and patterns

Beside tooling, i would advice to work on coding standards and patterns as well as, peer review of the code between developers of the project. This may help to leverage some common approach in trouble shooting memory leak issues.


答:
You've already covered them.

If shared ownership causes memory management issues, work your design away from shared ownership. Usually this involves designating one part of the code as the owner, and thus responsible for deallocation. Weak pointers (or the equivalent) can help this programmatically. RAII can be more liberally applied when single ownership exists.

If you have refcounting (or another mechanism for auto-deallocation) then you need not care if/where the deallocation occurs. You simply need to test/prove that the structure will correctly deallocate memory when it is supposed to.

A few other things to focus on:

Memory management likes patterns. When your code follows consistent patterns, it will have consistent behavior as far as memory management is concerned. When you do detect memory leaks, you can then focus on the exceptional cases, making them easier to find.

Shrink your scope. If the objects only live within an isolated scope, it's easier to reason about ownership and their lifetimes.

Only allocate what you need. Better than small scopes is no scope. If you don't need to allocate memory (within reason), don't.

Title: strategies to keep tabs of memory leaks in non memory-managed languages

Body:
When it comes to non memory managed languages such as C, C++ or Fortran (my case), it becomes increasingly difficult to keep track of memory allocation/deallocation, especially when ownership must be shared. I implemented refcounting for my objects, but this makes it even more complicated as there's no place where an object gets deallocated. Every reference decrement is a potential deallocation point.

So it's now more and more difficult for me to track down memory leaks. I was wondering about some established techniques to deal with memory management in non-memory managed languages, apart from valgrinding your way around.

Edit: I am more interested in active programming strategies (which are general).


问:
What are the practical ways to implement the SRP?
Simply what are the practical techniques people use to check if a class violates the single responsibility principle?

I know that a class should have only one reason to change, but that sentence is somewhat lacking a practical way to really implement that.

The only way I found is to use the sentence "The ......... should ......... itself." where the first space is the class name and the later is the method (responsibility) name.

However, sometimes it's hard to figure out if a responsibility really violates the SRP.

Are there more ways to check for the SRP?

Note:

The question is not about what the SRP means, but rather a practical methodology or a series of steps to check and implement the SRP.

UPDATE

I have added a sample class that clearly violates the SRP. It would be great if people could use it as an example to explain how they approach the single responsibility principle.

The example is from here.

答:
Single Responsibility Principle is highly coupled with the notion of cohesion. In order to have a highly cohesive class you need to have co-dependence between the class' instance variables and its methods; that is, each of the methods should manipulate as many instance variables as possible. The more variables a methods uses, the more cohesive is to its class; maximum cohesion is usually unachievable.

Also, in order to apply SRP well you understand well the business logic domain; to know what each abstraction should do. Layered architecture is related to SRP also, by having each layer do a specific thing (Data Source Layer should provide data and so on).

Coming back to cohesion even if your methods do not use all the variables, they should be coupled:

```<code>public class MyClass {
    private Type1 var1;
    private Type2 var2;
    private Type3 var3;

    public Type3 method1() {
        //use var1 and var3
    }

    public void method2() {
        //use var1 and var2
    }

    public Type1 method3() {
        //use var2 and var3
    }
}
</code>```

You should not have something like the code bellow, where a part of the instance variables are used in a part of the methods, and the other part of the variables are used in the other part of the methods (here you should have two classes for each part of the variables).

```<code>public class MyClass {
    private Type1 var1;
    private Type2 var2;
    private Type3 var3;
    private TypeA varA;
    private TypeB varB;

    public Type3 method1() {
        //use var1 and var3
    }

    public void method2() {
        //use var1 and var2
    }

    public TypeA methodA() {
        //use varA and varB
    }

    public TypeA methodB() {
        //use varA
    }
}
</code>```

Body:
Single Responsibility Principle is highly coupled with the notion of cohesion. In order to have a highly cohesive class you need to have co-dependence between the class' instance variables and its methods; that is, each of the methods should manipulate as many instance variables as possible. The more variables a methods uses, the more cohesive is to its class; maximum cohesion is usually unachievable.

Also, in order to apply SRP well you understand well the business logic domain; to know what each abstraction should do. Layered architecture is related to SRP also, by having each layer do a specific thing (Data Source Layer should provide data and so on).

Coming back to cohesion even if your methods do not use all the variables, they should be coupled:

public class MyClass {
    private Type1 var1;
    private Type2 var2;
    private Type3 var3;

    public Type3 method1() {
        //use var1 and var3
    }

    public void method2() {
        //use var1 and var2
    }

    public Type1 method3() {
        //use var2 and var3
    }
}

You should not have something like the code bellow, where a part of the instance variables are used in a part of the methods, and the other part of the variables are used in the other part of the methods (here you should have two classes for each part of the variables).

public class MyClass {
    private Type1 var1;
    private Type2 var2;
    private Type3 var3;
    private TypeA varA;
    private TypeB varB;

    public Type3 method1() {
        //use var1 and var3
    }

    public void method2() {
        //use var1 and var2
    }

    public TypeA methodA() {
        //use varA and varB
    }

    public TypeA methodB() {
        //use varA
    }
}


答:
The code is based on that of MER (Spirit and Opportunity), which were based off of their first lander, MPF (Sojourner). It's 3.5 million lines of C (much of it autogenerated), running on an RA50 processor manufactured by BAE and the VxWorks operating system. Over a million lines were hand coded.

The code is implemented as 150 separate modules, each performing a different function. Highly coupled modules are organized into components that abstract the modules they contain, and "specify either a specific function, activity, or behavior." These components are further organized into layers, and there are "no more than 10 top-level components."

Source: Keynote talk by Benjamin Cichy at 2010 Workshop on Spacecraft Flight Software (FSW-10), slides, audio, and video (starts with mission overview, architecture discussion at slide 80).

Someone on Hacker News asked "Not sure what means that most of the C code is auto generated. From what?"

I'm not 100% sure, although there probably is a separate presentation in that year or a different year that describes their auto-generation process. I know that it was a popular topic in general at the FSW-11 conference.

Simulink is a possibility. It's a MATLAB component popular among mechanical engineers, and therefore most navigation & control engineers, and allows them to 'code' and simulate things without thinking they're coding.

Model-based programming is definitely a thing that the industry is slowly becoming aware of, but I don't know how well it's catching on at JPL or if they would have chosen to use it when the project started.

The third and most likely possibility is for the communication code. With all space systems, you need to send commands to the flight software from the ground software, and receive telemetry from the flight software and process it with the ground software. Each command/telemetry packet is a heterogeneous data structure, and is is necessary that both sides are working from the exact same packet definition, and format the packet so it is correctly formatted on the one side, and parsed on the other side. This involves getting a whole lot of things right, including data type, size, and endianness (although the latter is usually a global thing; you could have multiple processors onboard with different endianness).

But that's just the surface. You need lots of repetitive code on both sides to handle things like logging, command/telemetry validation, limit checking, and error handling. And then you can do more sophisticated things. Say you have a command to set a hardware register value, and that value is sent back in telemetry in a particular packet. You could generate ground software that monitors that telemetry point to ensure that when this register value is set, eventually the telemetry changes to reflect the change. And of course, some telemetry points are more important than others (e.g. the main bus current) and are designated to come down in multiple packets, which involves extra copying on the flight side and data de-duplication on the ground side.

With all that, it's much easier (in my opinion) to write one collection of static text files (in XML, CSV, or some DSL/what-have-you), run them through a Perl/Python script, and presto! Code!

I do not work at JPL, so I cannot provide any detail that is not in the video, with one exception. I've heard that the autogenerated C code is written by Python scripts, and the amount of autocoding in a project varies greatly depending on who the FSW lead is.

Title: What is the Mars Curiosity Rover's software built in?

Body: The Mars Curiosity rover has landed successfully, and one of the promo videos "7 minutes of terror" brags about there being 500,000 lines of code. It's a complicated problem, no doubt. But that is a lot of code, surely there was a pretty big programming effort behind it. Does anyone know anything about this project? I can only imagine it's some kind of embedded C.</p>


答:
Memory leaks are really a non-issue once you understand how memory management works.  To deal with them, you need two things:

First, get a debugging memory manager.  I don't know what's available for C, C++ or Fortran, since I'm a Delphi developer, but in Delphi there's a memory manager replacement called FastMM FullDebugMode that will keep track of your allocations and deallocations, and alert you at the end of the program if you've leaked anything.  It provides a stack trace, type information, and other useful debug information for each leak, which makes them very simple to track down and fix.  You ought to have something similar available for other languages.

Second, you need to understand how to structure memory allocation to prevent leaks from happening.  The technique for this can be formally stated as the Single Ownership Principle:

Each variable in your code has one and only one owner, and it’s the
  responsibility of that owner to free the variable’s memory when it is
  no longer needed.

What that single owner is will vary depending on what the variables are and what they're used for.  Primitives, for example, are owned by the stack and will automatically be cleaned up when a function returns.  Most objects, by contrast, are owned by another object.  Those that aren't are generally local variables that should be cleaned up by the routine that created them before it exits.

Objects that are shared by multiple other objects do not have multiple owners; if you think of it that way you're asking for trouble.  Instead, they should have one single owner, either a reference-counting system or a master object that you know will be around longer than any of the others.

When you internalize the Single Ownership Principle, you'll write a lot less code with leaks.  And when you have a debugging memory manager to report on whatever you missed, fixing the few mistakes you do make will stop being a scary prospect.


问:
Have you ever found yourself using a specific tool in favor of another just because it looks better?
I found that this was the case with Eclipse.
When I first started learning Java a lot of people told me to start with NetBeans because it's easier, comes with a lot of predefined functionality and most of the configuration is done by default. Indeed it seemed like an easy IDE but I just hated the way it looked. The UI to me was horrible.

Then I downloaded Eclipse. I was pretty impressed with it. Everything looked shiny, fonts looked awesome and the UI in general was amazing compared to NetBeans'. So I stayed with Eclipse.

Has something like this ever happen to you? Should the UI be of such a relevance to a programmer, is this bad ? The problem of the UI extends to everything for me, not only IDE's (e.g. even on linux I have to customize the WM the way I want before starting working with it).

答:
yes
but i can't remember what programs exactly
although its only when the functionality isn't much different
cause if there is a better functionality in the crappy looking one I'll still take that one

thats why i prefer Firefox over Opera
i like the customization in Firefox
i love the looks in Opera

OwnerDisplayName: Berty


问:
Unwritten rules of rewriting another team member's code
We are practicing collective code ownership. To my understanding this means that any developer can change any line of code to add functionality, to refactor, fix bugs or improve designs.

But what about a complete rewriting of code from a developer who is still in the team? Should I ask him first? What is the best practice?

答:
I think good communication is always the best practice.  Talk to the developer and see if there's a reason why it's coded the way it is.  It may be that they have been meaning to get back and refactor it for ages, it may be that they did it that way for a very good reason, or it may be that you both can learn something from the conversation.

Going in and rewriting without prior communication is a recipe for ill will.


答:
Generally, if you all agree that you are all responsible for the code, then it's ok to rewrite any code if it's an improvement.  Discuss it with the other developer first as a courtesy. There may be valid reasons it's written in a certain way. On a personal level many developers get emotionally invested in what they produce and, as others have said, you want no ill will.

Specifically it depends somewhat on team dynamics.  A senior developer about to rewrite a junior developer's code should probably perform a code review (my site) with them before simply rewriting it.  That way the junior developer can learn from the situation.

Title: Unwritten rules of rewriting another team member's code

Body:
We are practicing collective code ownership. To my understanding this means that any developer can change any line of code to add functionality, to refactor, fix bugs or improve designs.

But what about a complete rewriting of code from a developer who is still in the team? Should I ask him first? What is the best practice?


答:
Why are you editing the code?

Are there bugs or is it a more fundamental design flaw?

In the former case, I'd worry about a rewrite to fix what could just be minor bugs in the code.

In the latter case, while I'd expect a heads-up that "my" code was potentially being rewritten, I'd be perfectly happy for it to happen.

That's the point of collective code ownership - the code you write is there to be modified or even replaced if something better comes along.


答:
What's the scope of it?

If you're reworking a few lines to be more efficient, just do it. Maybe ask if there's some danger of you erasing subtle behavior. Report the change during scrum or via email once it's done, unless it's really trivial (fixing a typo).

If you're reworking a decently sized class, you should probably ask to make sure you understand the design/behavior. Let people know ahead of time so that anyone that might be working in the same area can be aware and coordinate with you.

If you're reworking a larger system, you should definitely work with your team to make them aware of the changes and plan the design.


答:
Some random thoughts:

Big-bang rewrites are prone to big-bang problems, which is why many people suggest an incremental approach to rewriting an application. Ideally, then, you need to Divide and conquer.

If you're going for an incremental approach, the challenges are:

How you divide the existing application into upgradable components

How you upgrade each component

How you integrate new components with the old ones

Look for logical divisions that already exist in the application. Are there separate pieces of hardware? Different technologies? Layers? Does it serve different classes of business user? Or perform different groups of business function?

The better organised your original code, the easier your task will be. As a result, breaking up an application in this way will almost certainly involve some amount of refactoring of the original application. For example, pulling out database calls into a single set of modules / classes. Be aware that you're not trying to improve your old application - your purpose is just to modularise it. Fixing other problems should be easier in the new technology (after all, that is presumably one of the reasons you're migrating in the first place).

The smaller the chunks you're dealing with the easier your task will be. So take things a step at a time. Even if you only manage a few hundred lines of code, at least that is a start.

If you can automate the upgrade process in any way, then do so. For example, you may be able to buy / make a tool to convert program code or database schemas.

Write unit tests for both old and new code.

Title: Software rewriting alternatives


答:
As Matthew Flynn said, it is necessary to talk to the developer first. The initial developer might tell important things about the functionality and explain why this or that solution was given.

But before refactoring or re-writing the code, either make a backup or branch containing that code. If the old code works fine, there will remain a chance that it might be recovered.

If you have a source-control system (which I assume you do have), then, if possible, refactor the whole code and only afterwards, when you're sure it works fine, check that in.

Do not delete the old code, at least before you're sure the new code works fine. But leaving the old code there forever isn't a good thing either. I suggest you delete the code some time later, like in a month after it passed the testing.


问:
What non-programming books should a programmer read to help develop programming/thinking skills?
There are a lot of questions about what programming books should be on the programmer's bookshelf. How about non-programming related books that can help you become a better programmer or developer? It would also be interesting to know why they would help.

My first choice would be Sun Tzu's "Art of War" (however cliché), because it made it obvious that the success of any project depends on the strength of its weakest link (and warfare is a big project).

答:
Getting Things Done

David Allen

Body:
Getting Things Done

David Allen


答:
I'm sure it's a innate human bias to believe the prettier tool works the best, and, in the absence of any real obstructions of use, to choose that tool.

I realised a while ago that, the 'flatter' look a browser has, the more I believe it is a lighter and therefore faster browser. I use Chrome because it 'feels' lighter, although I have no real evidence it is a better browser to Firefox. Whilst I know this may be an illusion, I just like using it more.


问:
Are there open source alternatives to Bitbucket, Github, Kiln, and similar DVCS browsing and management tools?
I am aware of several tools/services that provide DVCS browsing and management such as Bitbucket, Github, Kiln, SCM-Manager and Rhodecode.

However, the use case I am considering is one such that:

Any source code must reside on an employers internal servers.

The solution must be open source.

It should provide a Bitbucket or Github like experience, including a project wiki, repository browsing and management, and social coding aspects such as code review.

The solution should have mercurial support (if not support for other DVCSs).

Of these, only SCM-Manager and RhodeCode come close as they can be installed on your own servers and are open source. However they do not have the Bitbucket or Github experience. There is no issue tracker or wiki and the UI, while functional, is not up to par with Github or Bitbucket.

I can get close with Trac or Redmine with their repository browsers but unfortunately they do not have any repository management capabilities.

Are there other open source tools out there that would provide a similar experience to Bitbucket, Github or Kiln?

答:
Allura http://sf.net/p/allura should fit the bill.  It is the platform for all the new (or upgraded) projects at SourceForge and is open source.  It supports Mercurial and wikis, plus many more tools (Git, SVN, ticket tracker, forums, etc).  It doesn't quite have "code review" but does support forking and merge requests for Mercurial and Git repos.

It's written in Python and uses MongoDB and Solr for data storage.

Allura is also currently in the Apache Incubator:  http://incubator.apache.org/projects/allura.html

I work for SourceForge and help develop Allura.


问:
User Configuration of a Shell Script. Best practices?
I am writing a shell script with a few variables that should be configured by the user. There will be an installer for downloading and configuring the script, possibly by asking a series of question. The script in question is aimed at other developers.

This can be implemented in a number of ways:

Use placeholders in the script itself and use sed to replace them during installation (something like this: https://stackoverflow.com/questions/415677/how-to-replace-placeholders-in-a-text-file)

Pros: All variable definitions are contained within the script. It's easy to download the script manually and configure the variables for users who prefer an editor over the installer.

Cons: It's hard to reconfigure the variables through the installer once they are in place. Unless I create a more complex regexp which would be prone to errors.

Use a config file, basically another shell script with assignments, and use source to include it. (And probably place it in ~/.scriptname? The main script is copied to /usr/local/bin)

Pros: It's easy to reconfigure the script. Could even add a parameter for doing so from the main script (Would probably work in the first solution as well, but editing a script from itself doesn't sound like a very good idea)

Cons: The script is now dependent on two files and the user is required to run the installer for the configuration file to be created. This can be solved by auto generating a config file if none exists. But locating an external configuration file will still be more cumbersome for users who just want to download the script, edit it, and be done with it.

Also, a few options regarding how the configuration should be managed by the user after the installation:

Git like

$ myscript config server.host example.org
$ myscript config server.proxypath /home/johndoe/proxy
$ myscript config server.httppath /home/johndoe/web

Interactive

$ myscript config

Enter the server hostname: example.org

Enter the path to the proxy on the server: /home/johndoe/proxy

Enter the path to the http directory on the server: /home/johndoe/web

getopts with long options

$ myscript --host example.org --proxypath /home/johndoe/proxy --httppath  /home/johndoe/web

Simple

$ myscript config example.org /home/johndoe/proxy /home/johndoe/web

Are there any other ways of doing this that you would consider?

Any best practices, anything elegant?

答:
When I need to write an elaborate script with various configuration options I use Python with the argparse and ConfigParser libraries. Those help with implementation but the process applies to any shell script:

Look for a config file.  If one exists, read any settings it has into a dictionary / lookup table.

Parse named command line arguments.  For each argument provided, override the value loaded from the config file if it exists.  For any argument not passed in the command line and not in the config, use a default.

Execute the script's main function

If the config file doesn't exist, write the passed and/or default values to it.

My preference is for a config file to hold the preferred options when the script is going to be used repeatedly, but let any command line arguments override.  Write the config file using those parameters the first time it's run.  The config file can then be shared and committed to a code repository.

In my most recent case, I also wrote the defaults to the [DEFAULT] section at the top of the config file, then had a section for each "environment" with appropriate overrides for each.  The "environment" is the first unnamed parameter to the script.  So in this case parameters are chosen as built-in default -> config file default -> config file section value -> command-line parameter.  An additional command line parameter gives the option to overwrite the existing config with the latest run's value.  This config file is written into the current directory so it applies per project and can be committed with the rest of the code.  Anyone else checking out the same project will then start with the same configuration.


答:
If your original writers are there, communicate with them.  Not JUST for ettiquette, but for additional information, in case there are cases or circumstances that you aren't aware of.  Sometimes, they'll tell you something valuable.

We have abysmal code control.  I currently have a ton of stuff that needs review and maintenance, and don't even have anyone to do code review with.  The previous writers (aside from moi) did not bother to comment any code.  And, they're gone from the company.  There's no one to ask about the code.

When I re-write, I comment out, with comments that I commented it out, as well as date and name/initials, and why it was being commented out.  I comment new code, with name or initials, date, reason is was added, etc.

Additional comments are made at the package head (er, usually), indicating what functions/procs/SQL/etc. were changed, with date.  It makes it easy to look up sections that have been changed, and those sections have full documentation.

Comments are cheap.  Dates will be an indicator of what changed, and after x-number of (days/revisions/new hires/retires) then the code can be cleaned of old comments and the remaining is the new baseline.


答:
It doesn't really matter if the original developer is on the team or not, or even if you are the original developer.  Complete rewriting of any shared code should be run by your team, for the following reasons:

It takes a significant amount of time.  If someone else is working on a related change, you don't want to waste their time.

Other people have a different perspective.  Even if you've been programming 20 years, someone else might know things about interactions with code you rarely touch.

Other developers are the "customer" of the source code.  Source code is written for other developers to read.  They may have architecture requirements, input on style, or feature requests they have been wanting in that code, but haven't had time.  You don't want to finish a refactor only to find out another developer needs it refactored in a different way.