答:
One of the best ways that I've found to increase compile time is to not do the compile in visual studio and instead use msbuild.  Using msbuild our ERP system (160 projects) takes under a minute to compile.  A sample command line would be:

```<code>cd c:\Solution\
c:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild ERP.sln /m:4 /v:m /property:Configuration=Release;ToolsVersion=2.0;CacheVersion=2.0 /fileLogger /fileLoggerParameters:Logfile=C:\ERP.log;Verbosity=minimal
</code>```

where /m: is the # of cpu cores in your computer, and /v: is the verbosity of the output displayed to the screen (flags are: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]).

Another optimization technique we use is to use multiple solutions.  Our main ERP solution contains all the projects for the system.  We then have individual solutions for each project area, ie accounting, inventory, logistics, etc.  The big solution is only used when doing a full compile of the system (via msbuild).  When working in visual studio we only open the sub-solutions which contain a limited subset of projects making the compiles much faster.

Title: How can I organize fast and comfortable solution compilation in VS 2010?

Body:
Most of programmers who are involved into development of more or less large project(s) know how annoying the process of compilation can be. There are some other things which are dependent on compilation, for example unit tests. TDD requires tests to execute fast, otherwise developers tend to run them rarely.

The process of compilation of whole solution my team is working with takes about 5 minutes.  Our Visual Studio solution consists of many projects, so we usually don't have to recompile all of them. Normally, this 'partial' compilation requires about 2 minutes. It's easy to calculate that compiling the solution 10 times we lose 20+ minutes! The situation is even worse when we have to rebuild whole solution often. For this reason I unload a lot of projects manually very often but it scarcely helps.

1. How can we accelerate the process of compilation?

2. Can you recommend any Visual Studio [2010] extension which allows continuous background solution compilation?

Body:
One of the best ways that I've found to increase compile time is to not do the compile in visual studio and instead use msbuild.  Using msbuild our ERP system (160 projects) takes under a minute to compile.  A sample command line would be:

cd c:\Solution\
c:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild ERP.sln /m:4 /v:m /property:Configuration=Release;ToolsVersion=2.0;CacheVersion=2.0 /fileLogger /fileLoggerParameters:Logfile=C:\ERP.log;Verbosity=minimal

where /m: is the # of cpu cores in your computer, and /v: is the verbosity of the output displayed to the screen (flags are: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]).

Another optimization technique we use is to use multiple solutions.  Our main ERP solution contains all the projects for the system.  We then have individual solutions for each project area, ie accounting, inventory, logistics, etc.  The big solution is only used when doing a full compile of the system (via msbuild).  When working in visual studio we only open the sub-solutions which contain a limited subset of projects making the compiles much faster.


问:
Tips for debugging with very little info?
I've inherited a project with a fairly large codebase, and the original developer rarely, if ever, replies to emails. There's a ton of different ways to do some things in it, and I don't know all of them. A lot of duplicated code along these paths (rather than functions included by, say, 5 pages that do relatively the same thing, it's code copied across 5 pages), and some subtle issues in the database (we've all heard of spaghetti code, but have you ever heard of a spaghetti database?)

All of this I can deal with most of the time no problem.

The issue is when a client finds a bug somewhere. They'll usually send a screenshot of the ending issue, and say, "Could you take a look at this?" while highlighting the specific thing on the page that's wrong, and sometimes what was expected. Very little more information is given, and trying to talk to them and get more (such as what they did to get the result) is like pulling teeth.

Basically, it boils down to this:

Large and complex code base I'm not 100% familiar with

Many many ways things can go wrong

Very little information on how a bug came to be

Does anybody have any tips, tricks, suggestions, etc. on how to debug this sort of thing?

答:
A good start might be this book.

I am using the definition below as it sounds like the developer isn't around to support it anymore.

Legacy code is source code that relates to a no-longer supported.

ContentLicense: CC BY-SA 2.5


问:
Do We Have a Responsiblity to Improve Old Code?
I was looking over some old code that I wrote.  It works, but it's not great code.  I know more now than I did at the time, so I could improve it.  It's not a current project, but it's current, working, production code.  Do we have a responsibility to go back and improve code that we've written in the past, or is the correct attitude "if it ain't broke, don't fix it"?  My company sponsored a code review class a few years ago and one of the major takeaways was that sometimes it's just good enough; move on.

So, at some point should you just call it good enough and move on, or should you try to push projects to improve old code when you think it could be better?

答:
It depends.

If the code in question is truly broken, such that it contains bugs that will inevitably surface at one point (e.g., some counter that will at some point overflow and cause nasty problems), then fixing those may be worth the effort - but if you do, put all possible safeguards in place first to avoid introducing new bugs: make sure you have meaningful unit tests covering everything you touch, have all your changes reviewed by someone competent, insist on testing thoroughly, make sure you can revert back to the old version at any time, back up any data before going into production, deploy to an acceptance environment first and have it tested by actual users, etc. You'll also want to get approval before going ahead: if the bug is truly a time bomb, and your manager is somewhat competent, you will be able to convince him/her to let you fix it (and if you don't get approval, then maybe that's a sign that you're wrong).

OTOH, if your complaint is mere lack of code elegance, then don't you dare touch it. It's been doing faithful service in production for quite a while now, changing the code would only satisfy you, but not add any value, and like every change, there is a risk that you break something. Even if you don't, your time is valuable (literally: you're getting paid for what you do, so every minute of your time costs money), and since you're not adding any actual value, such a change would be a net loss for the company and the project.

ContentLicense: CC BY-SA 3.0


问:
Separating data access in ASP.NET MVC
I want to make sure I'm following industry standards and best practices with my first real crack at MVC.  In this case, it's ASP.NET MVC, using C#.

I will be using Entity Framework 4.1 for my model, with code-first objects (the database already exists), so there will be a DBContext object for retrieving data from the database.

In the demos I've gone through on the asp.net website, controllers have data access code in them.  This doesn't seem right to me, especially when following the DRY (don't repeat yourself) practices.

For example, let's say I am writing a web application to be used in a public library, and I have a controller for creating, updating, and deleting books in a catalog.

Several of the actions may take an ISBN and need want to return a "Book" object (note this is probably not 100% valid code):

```<code>public class BookController : Controller
{
    LibraryDBContext _db = new LibraryDBContext();

    public ActionResult Details(String ISBNtoGet)
    {
        Book currentBook = _db.Books.Single(b => b.ISBN == ISBNtoGet);
        return View(currentBook);
    }

    public ActionResult Edit(String ISBNtoGet)
    {
        Book currentBook = _db.Books.Single(b => b.ISBN == ISBNtoGet);
        return View(currentBook);
    }
}
</code>```

Instead, should I actually have a method in my db context object to return one Book?  That seems like it is a better separation to me, and helps promote DRY, because I might need to get a Book object by ISBN somewhere else in my web application.

```<code>public partial class LibraryDBContext: DBContext
{
    public Book GetBookByISBN(String ISBNtoGet)
    {
        return Books.Single(b => b.ISBN == ISBNtoGet);
    }
}

public class BookController : Controller
{
    LibraryDBContext _db = new LibraryDBContext();

    public ActionResult Details(String ISBNtoGet)
    {
        return View(_db.GetBookByISBN(ISBNtoGet));
    }

    public ActionResult Edit(ByVal ISBNtoGet as String)
    {
        return View(_db.GetBookByISBN(ISBNtoGet));
    }
}
</code>```

Is this a valid set of rules to follow in the coding of my application?

Or, I guess a more subjective question would be:  "is this the right way to do it?"

答:
This is the way I've been doing it, although I'm injecting the data provider as a generic data service interface so that I can swap out implementations.

As far as I know, the controller is intended to be where you get data, perform any actions, and pass data to the view.

Title: Separating data access in ASP.NET MVC


问:
Organizing MVC entities communication
I have the following situation. Imagine you have a MainWindow object who is layouting two different widgets, ListWidget and DisplayWidget. ListWidget is populated with data from the disk. DisplayWidget shows the details of the selection the user performs in the ListWidget.

I am planning to do the following: in MainWindow I have the following objects:

ListWidget

ListView

ListModel

ListController

ListView is initialized passing the ListWidget. ListViewController is initialized passing the View and the Model.

Same happens for the DisplayWidget:

DisplayWidget

DisplayView

DisplayModel

DisplayController

I initialize the DisplayView with the widget, and initialize the Model with the ListController. I do this because the DisplayModel wraps the ListController to get the information about the current selection, and the data to be displayed in the DisplayView.

I am very rusty with MVC, being out of UI programming since a while. Is this the expected interaction layout for having different MVC triplets communicate ? In other words, MVC focus on the interaction of three objects. How do you put this interaction as a whole into a larger context of communication with other similar entities, MVC or not ?

答:
I will start by providing you with great resources for MVC design. The first is the WWDC 2010 Session 116 Model-View-Controller for iPhone OS (really just iOS), it is slightly tailored to the iOS classes, but gives a lot of generally useful information too. You have to register to be an Apple developer (free) to get access to it. The second is the publicly available Stanford iOS course, again it will be tailored to iOS, but his introduction class focused on MVC in the general sense.

Ok, so what you get from those resources are rules such as Views don't own the data they display.

Straight from the Stanford course:

Model: What your application is (but not how it's displayed)

  Controller: How your model is presented to the user (UI Logic)

  View: Your controller's minions

Communication

Controllers: direct communication to models and views.

Views: "blind" communication to controllers (target-actions and delegation). No   communication to models.

Models: broadcast communication to controllers (Notification and KVO). No communication to views.

Organization

For your specific case, I'm not sure I understand what you're describing 100%, I'm not sure what those "widgets" are (at least for Android, a widget is a bundle of MVC(s) that provide some functionality like a search bar widget). But if you mean that the ListModel is something like a title and implicit index, and the DisplayModel is a matching description for the given index, then I might have a MainController (for the main view that is containing these two subviews or fragments). The user selects an item in the ListView triggering some sort of onSelection function on the MainController (now the MainController knows what item they selected). The MainController passes that along to the DisplayController (now the DisplayController knows what item they selected). Finally, the DisplayController can use the DisplayModel to find what needs to be displayed now and then tell the DisplayView to display it.

Alternatively the DisplayController can respond to the onSelection function triggered by the selection in the ListController directly, but that connects components that probably shouldn't be connected. Because you said they were their own Views that means it could be possible to have a set up (possibly for smaller screens) that had the ListView on the full screen, a selection is made, then the DisplayView takes over the screen showing the description of the selection made. For that reason I would leave the views separate.

Edit

So, let's start by saying MVC is just a guide to producing nicely structured code, as far as I know it isn't strictly enforced. Next, for the "non-canonical" refer to what each component is suppose to do.

Essentially everything that isn't written to display something or interact with the display is part of a model. Models are the algorithms that perform tasks. Views are only to surface a UI, and provide ways for the program to interact with the UI (as in the target-action connections and delegation). This leaves the Controllers to be the delegates and targets for the Views. Think of the as kind of the gears under the views I guess. They should be the link between actions on the screen and functions and data in the Model. They should make sure the Views display the content you want to be displaying.

Here are pictures taken from the Stanford course (the first class) that show how and how not to set up multiple MVCs. (unfortunately I can post a maximum of 2 hyperlinks and no images)

MVC done correctly

MVC done incorrectly

Title: Organizing MVC entities communication


问:
Does programming in general become easier to read, write and understand as you gain experience?
I'm a beginner in programming and I've been reading books, studying, reading articles, and whatnot. I'm getting great results since I've started learning programming, and when I was a beginner I used to think I knew everything about programming, but as I learned more I realized how difficult this field is (In fact all fields are difficult, but that's not the point).

Nowadays, I've written functional software and I've learned the BASICS of 3 languages and I'm intermediate in just one language. When I look at advanced things like MYSQL, or OpenGL programming, or even visual studio C++ code it gives me headaches, and even when visualising HTML source code of many websites (Most source codes on websites, seen by google chrome seem very messy and unorganized) it makes me confused to the very limit of my brain. It all seems simple at first, yet when looking at these advanced things it just makes me wonder how can one learn so much.

The question, in a nutshell, is if these things become clearer to a programmer as he advances in his career. Do complicated topics as the ones listed above (OpenGL, MySQL, advanced html sites) become easier to read, write and understand as you learn more, or does it just get more complicated as you go by? How can you combat this feeling that you're an ant in the programming world and this stuff is the foot about to squash you?

答:
Short answer, Yes.

Given time and exposure these things become easier to comprehend.

Remember when you are looking at sites from the dev tools in your browser they are often generated by a framework. Let that be any number of things...ASP.NET, JSP, RoR, Django,...who knows. Some of these frameworks produce cleaner code than others.

In closing...exposure leads to proficiency. There is no way to quash that feeling. Just experience and learning. It takes time to move in, gain domain knowledge, and learn the skills your environment uses.


答:
When I get something like that, I usually demand more information.  Not sure how it is where you work, but here if I don't have enough information to reproduce the problem locally, I can send the ticket back marked Cannot Reproduce, with a request for more information, and they know that nothing's getting fixed until I'm able to break it on my end.

If your clients are having trouble with describing steps, ask them for a screencap video.  There are a few free products that can create them, such as Jing.  It makes it a lot easier when you can watch exactly what they were doing.

EDIT:  Jing was a good idea when I wrote this a few years ago.  Since then, they've modified their installer to load your system up with "bonus" crapware that you never asked for, so I can no longer recommend it.  There are plenty of decent screen recorders around, though.

Title: Tips for debugging with very little info?

Body:
I've inherited a project with a fairly large codebase, and the original developer rarely, if ever, replies to emails. There's a ton of different ways to do some things in it, and I don't know all of them. A lot of duplicated code along these paths (rather than functions included by, say, 5 pages that do relatively the same thing, it's code copied across 5 pages), and some subtle issues in the database (we've all heard of spaghetti code, but have you ever heard of a spaghetti database?)

All of this I can deal with most of the time no problem.

The issue is when a client finds a bug somewhere. They'll usually send a screenshot of the ending issue, and say, "Could you take a look at this?" while highlighting the specific thing on the page that's wrong, and sometimes what was expected. Very little more information is given, and trying to talk to them and get more (such as what they did to get the result) is like pulling teeth.

Basically, it boils down to this:

Large and complex code base I'm not 100% familiar with

Many many ways things can go wrong

Very little information on how a bug came to be

Does anybody have any tips, tricks, suggestions, etc. on how to debug this sort of thing?


问:
Using PHP's ternary operator with only two arguments
I was recently reviewing some of my code and noticed that in a fit of absent-mindedness, I'd left a structure like the following:

```<code>$guid = empty($subscription->guid) ?  : $subscription->guid;
</code>```

Now, this wasn't doing what it's supposed to and is wrong, but since that property is always set now it was working fine, and there's no syntax error since 5.3 because of the following change:

Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.

I wasn't aware of this change, and now I'm curious if I should be using it or not. This is something I was sorely missing from languages like ruby where you can do eg, a = b || c to get either b or c rather than a 'real' boolean. However, the syntax they've chosen for the ternary operator seems a little counter intuitive to me. Should I be using this in production code? It definitely threw myself when I saw it by accident.

答:
Well, PHP has a boolean type and the || operator returns a boolen, so in PHP the result of $a || $b is a boolean, this is consistent with && as with && it makes little sense to return one or the other but makes sense to return true/false. Having all boolean operators return bools sounds quite logical, too.

Additionally this is no invention from PHP but following C, where many design elements of "classic" PHP are coming from. Quoting from §6.5.14 of the C99 standard:

The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.

And, well, whehter you should use ?: or not can't be answered in the general form, but mind: Best way to language is to use the constructs it provides and use the paradigms it suggests. There is little sense in writing Java code like C code, or the other way round ;-)


问:
Why is it so difficult to make C less prone to buffer overflows?
I'm doing a course in college, where one of the labs is to perform buffer overflow exploits on code they give us. This ranges from simple exploits like changing the return address for a function on a stack to return to a different function, all the way up to code that changes a programs register/memory state but then returns to the function that you called, meaning that the function you called is completely oblivious to the exploit.

I did some research into this, and these kinds of exploits are used pretty much everywhere even now, in things like running homebrew on the Wii, and the untethered jailbreak for iOS 4.3.1

My question is why is this problem so difficult to fix? It's obvious this is one major exploit used to hack hundreds of things, but seems like it would be pretty easy to fix by simply
truncating any input past the allowed length, and simply sanitizing all input that you take.

EDIT: Another perspective that I'd like answers to consider - why do the creators of C not fix these issues by reimplementing the libraries?

答:
It's not really inaccurate to say that C is actually "error-prone" by design.  Aside from some grievous mistakes like gets, the C language can't really be any other way without losing the primary feature that draws people to C in the first place.

C was designed as a systems language to act as a sort of "portable assembly."  A major feature of the C language is that unlike higher-level languages, C code often maps very closely to the actual machine code.  In other words, ++i is usually just an inc instruction, and you can often get a general idea of what the processor will be doing at run-time by looking at the C code.

But adding in implicit bounds checking adds a lot of extra overhead - overhead which the programmer didn't ask for and might not want.  This overhead goes way beyond the extra storage required to store the length of each array, or the extra instructions to check array bounds on every array access.  What about pointer arithmetic?  Or what if you have a function that takes in a pointer?  The runtime environment has no way of knowing if that pointer falls within the bounds of a legitimately allocated memory block.  In order to keep track of this, you'd need some serious runtime architecture that can check each pointer against a table of currently allocated memory blocks, at which point we're already getting into Java/C#-style managed runtime territory.


答:
Short answer: no.

Long answer:

Reading code of other people becomes easier, yes. But only reading. As you gain experience and skills, your personal requirements as a developer grow.

You don't want to just write code. You want to write beautiful code.

You don't assume your code runs in ideal conditions. You start to think about all bad things which may happen when running your code, handle exceptions, think about hardware problems, network latency, and the problem grows as your skills grow.

You don't read and write code in the only language you know. As a skillful developer, you know that to solve this specific problem you have right now, functional programming is a much better alternative, so you must now read and write code in functional programming language.

You don't limit yourself to a small set of libraries you know. If you code in C#, you want to know and use the full power of many libraries of .NET Framework.

You don't use notepad any longer. You need your powerful IDE, and you want to know how to unit test code, what are code metrics about, and what is the meaning of hundreds of options and windows your IDE can show to you.

You don't want to modestly limit yourself to a basic set of tools the language gives you. In C#, you want to use generics, code contracts, reflection, event-driven development, functional aspects with LINQ, Reactive extensions, and a ton of other stuff you learned, all in a single project, if those things help you to write better code.

You don't start writing code. You spend 80 to 90% of your time gathering requirements, creating the architecture of your application, writing unit tests, writing documentation, etc., and only 10 to 20% of your time writing actual code.

You care about security. You know the legal issues which may arise with the data manipulated by your applications. You know what is ITIL. You know some ISO standards and you apply them daily in your work.

Yes, you gain experience and skills, and it becomes easier to solve a given problem with all the knowledge and intellectual abilities you gained. But problems you must solve grow too, and you're just not excited at solving the problems of the level of those I've solved when you started programming.

While gaining skills, you also gain an insight on the complexity of the software development, learn the aspects you couldn't even imagine when started to learn programming, and you want and need to apply all the stuff you learn daily.

In short:

The first day you start to learn to program, the task of listing all numbers from 1 to 100 divisible by two is very complex: you just learned how to make loops and display numbers on the screen, but you have no idea how to find if the number is divisible by two.

Ten years later, the same exercise appears to be extremely simple. But also, ten years later, you're writing applications which must use transactions, are hosted on several servers and must handle session state properly between servers, and is storing bank account details of your customers, with all the resulting security and legal aspects.

... And you are wondering yourself "How could I possibly do that?" in the exact same way you did ten years ago when you had to display numbers to a screen with a loop.

When everything becomes easy to you in a domain, it means that either you achieved perfection in this domain, or you just don't care any longer.

Achieving perfection in a domain as vast as software development is impossible, no matter how smart you are.

Title: Does programming in general become easier to read, write and understand as you gain experience?

Body:
I'm a beginner in programming and I've been reading books, studying, reading articles, and whatnot. I'm getting great results since I've started learning programming, and when I was a beginner I used to think I knew everything about programming, but as I learned more I realized how difficult this field is (In fact all fields are difficult, but that's not the point).

Nowadays, I've written functional software and I've learned the BASICS of 3 languages and I'm intermediate in just one language. When I look at advanced things like MYSQL, or OpenGL programming, or even visual studio C++ code it gives me headaches, and even when visualising HTML source code of many websites (Most source codes on websites, seen by google chrome seem very messy and unorganized) it makes me confused to the very limit of my brain. It all seems simple at first, yet when looking at these advanced things it just makes me wonder how can one learn so much.

The question, in a nutshell, is if these things become clearer to a programmer as he advances in his career. Do complicated topics as the ones listed above (OpenGL, MySQL, advanced html sites) become easier to read, write and understand as you learn more, or does it just get more complicated as you go by? How can you combat this feeling that you're an ant in the programming world and this stuff is the foot about to squash you?

ContentLicense: CC BY-SA 4.0


问:
What is the advantage of implementing a composite design pattern?
Apparently, a composite design pattern represents individual entities and collective entities in the same manner.

What is the advantage to this? For instance, if I subclass a class, why would I want to treat objects of both classes in the same way?

For instance, if 'tuna' is a subclass of 'fish', why would I want to have the same implementations for methods of objects in both classes?

答: The relationship being described in composite design patterns isn't a subclass relationship, it's a collection relationship.  In other words, it's about treating a tuna the same as a school of tuna.  That way for operations like translating, rotating, scaling, drawing, etc. the caller doesn't need to care if it is acting on one object or an entire collection.</p>


问:
When business rules affect presentation in MVC
The MVC design pattern is supposed to led itself to separating business rules from presentation.

But sometimes business rules AFFECT presentation.  What is the best way to deal with this?  Is that when a ViewModel should be used?

For example, going back to my non-existent Library application, a librarian is scanning returned books.  The system indicates that a book is late, and applies a fine to that patron.

Certain employees may have security to override that fine based on certain conditions.

The presentation layer of my library application will need to let the employee set the fine to 0, or click a button to override the fine.

But employees who do NOT have security to do this should see the fee as either a disabled input or maybe read only.

Note that security may not be the only business rule.  This is just an example.  For example, my application may have configuration information set up somewhere that causes a field on a screen to become unnecessary, etc.

While the code could just let anyone change the fine and then show a validation message, that's not a good user experience.

What is a good practice to accomplish this?  The options I can think of (using ASP.NET MVC) are:

Have the view itself check the business rule and disable or enable the field.

Use a HTMLHelper function that implements the presentation for the fine field, and have that helper function check the business rule.

Have the controller check the business rule and use a different view.

Have the controller check the business rule and set a property in the ViewBag that indicates whether the field is enabled.

Use a ViewModel checks the business rule and set information indicating that the field is enabled.

Options 1 & 2 cause the presentation layer to have to do business rule validation, and that muddles things.

Option 3 will cause duplication of effort in that now you have two views defined.

Option 4 & 5 requires the presentation layer to know that the field COULD be enabled or disabled, but not WHY.  I think I like 4 or 5 best.

Our there other options I'm not thinking of?

答:
I think your option number 5 is best, but with some slight tweaking:

Your ViewModel should have a property that indicates whether the data can be updated, or not. Perhaps a "CanOverrideLateFine" boolean property.

Whatever is creating the ViewModel (your Controller, or more likely a business service that your Controller delegates to) is responsible for evaluating the business rules and setting that property. Not the ViewModel itself.

The View will then inspect the "CanOverride" property and determine how to properly render for the user. It may be as simple as enabling or disabling a form field, but it may be something completely different (maybe not even rendering the field, or supplying a completely different visual element).


答:
Do complicated topics as the ones listed above (OpenGL, MySQL, advanced html sites) become easier to read, write and understand as you learn more, or does it just get more complicated as you go by? How can you combat this feeling that
  you're an ant in the programming world and this stuff is the foot
  about to squash you?

When any progress is made, we unlearn and learn anew what we thought we knew before.
 - Henry David Thoreau

There is a story of the Zen master and the Overflowing Teacup.

Sometimes, we need to let go of our preconceived notions and opinions from the past so we can allow ourselves to learn new concepts.

Remember: If you are feeling overwhelmed by a new concept, you need to look for many teachers.

Recently, when given an assignment of updating some internal company software that used a scripting language I was unfamiliar with.  In the beginning it was very stressful.  However, after I changed my attitude, I began to find resources that explained the syntax and basic concepts.  I completed the project and now utilize this scripting language as one of my tools to get more things done.

Your attitude makes all the difference.


答:
As a child, you learn to speak and then to read your native language.  The plain mechanics of it are a struggle at first, but at some point it comes fluently.  However, you still have an infinite supply of books you haven't read, and on some topics you have to increase your vocabulary first just to be able to understand the book.

The same goes for computer programming.  At some point the language itself stops feeling like a foreign language, but there's still a lot of stuff written in that language that you don't know yet.  But everything is accessible to you with some effort.

Some programming jobs are very repetitious, basically re-implementing very similar software for different customers.  In those jobs you might feel like you hit a plateau of learning.  Other jobs you are doing something new and unique all the time, and never stop learning new things.


答:
Generally, you want your Controllers to do only a few things:

Handle the incoming request

Delegate the processing to some business object

Pass the result of the business processing to the appropriate view for rendering

There shouldn't be any data access or complex business logic in the controller.

[In the simplest of apps, you can probably get away with basic data CRUD actions in your controller, but once you start adding in more than simple Get and Update calls, you are going to want to break out your processing into a separate class.]

Your controllers will usually depend on a 'Service' to do the actual processing work. In your service class you may work directly with your data source (in your case, the DbContext), but once again, if you find yourself writing a lot of business rules in addition to the data access, you will probably want to separate your business logic from your data access.

At that point, you will probably have a class that does nothing but the data access. Sometimes this is called a Repository, but it doesn't really matter what the name is. The point is that all of the code for getting data into and out of the database is in one place.

For every MVC project I've worked on, I've always ended up with a structure like:

Controller

```<code>public class BookController : Controller
{
    ILibraryService _libraryService;

    public BookController(ILibraryService libraryService)
    {
        _libraryService = libraryService;
    }

    public ActionResult Details(String isbn)
    {
        Book currentBook = _libraryService.RetrieveBookByISBN(isbn);
        return View(ConvertToBookViewModel(currentBook));
    }

    public ActionResult DoSomethingComplexWithBook(ComplexBookActionRequest request)
    {
        var responseViewModel = _libraryService.ProcessTheComplexStuff(request);
        return View(responseViewModel);
    }
}
</code>```

Business Service

```<code>public class LibraryService : ILibraryService
{
     IBookRepository _bookRepository;
     ICustomerRepository _customerRepository;

     public LibraryService(IBookRepository bookRepository,
                           ICustomerRepository _customerRepository )
     {
          _bookRepository = bookRepository;
          _customerRepository = customerRepository;
     }

     public Book RetrieveBookByISBN(string isbn)
     {
          return _bookRepository.GetBookByISBN(isbn);
     }

     public ComplexBookActionResult ProcessTheComplexStuff(ComplexBookActionRequest request)
     {
          // Possibly some business logic here

          Book book = _bookRepository.GetBookByISBN(request.Isbn);
          Customer customer = _customerRepository.GetCustomerById(request.CustomerId);

          // Probably more business logic here

          _libraryRepository.Save(book);

          return complexBusinessActionResult;

     }
}
</code>```

Repository

```<code>public class BookRepository : IBookRepository
{
     LibraryDBContext _db = new LibraryDBContext();

     public Book GetBookByIsbn(string isbn)
     {
         return _db.Books.Single(b => b.ISBN == isbn);
     }

     // And the rest of the data access
}
</code>```

Title: Separating data access in ASP.NET MVC

Body:
I want to make sure I'm following industry standards and best practices with my first real crack at MVC.  In this case, it's ASP.NET MVC, using C#.

I will be using Entity Framework 4.1 for my model, with code-first objects (the database already exists), so there will be a DBContext object for retrieving data from the database.

In the demos I've gone through on the asp.net website, controllers have data access code in them.  This doesn't seem right to me, especially when following the DRY (don't repeat yourself) practices.

For example, let's say I am writing a web application to be used in a public library, and I have a controller for creating, updating, and deleting books in a catalog.

Several of the actions may take an ISBN and need want to return a "Book" object (note this is probably not 100% valid code):

```<code>public class BookController : Controller
{
    LibraryDBContext _db = new LibraryDBContext();

    public ActionResult Details(String ISBNtoGet)
    {
        Book currentBook = _db.Books.Single(b => b.ISBN == ISBNtoGet);
        return View(currentBook);
    }

    public ActionResult Edit(String ISBNtoGet)
    {
        Book currentBook = _db.Books.Single(b => b.ISBN == ISBNtoGet);
        return View(currentBook);
    }
}
</code>```

Instead, should I actually have a method in my db context object to return one Book?  That seems like it is a better separation to me, and helps promote DRY, because I might need to get a Book object by ISBN somewhere else in my web application.

```<code>public partial class LibraryDBContext: DBContext
{
    public Book GetBookByISBN(String ISBNtoGet)
    {
        return Books.Single(b => b.ISBN == ISBNtoGet);
    }
}

public class BookController : Controller
{
    LibraryDBContext _db = new LibraryDBContext();

    public ActionResult Details(String ISBNtoGet)
    {
        return View(_db.GetBookByISBN(ISBNtoGet));
    }

    public ActionResult Edit(ByVal ISBNtoGet as String)
    {
        return View(_db.GetBookByISBN(ISBNtoGet));
    }
}
</code>```

Is this a valid set of rules to follow in the coding of my application?

Or, I guess a more subjective question would be:  "is this the right way to do it?"

Body:
Generally, you want your Controllers to do only a few things:

Handle the incoming request

Delegate the processing to some business object

Pass the result of the business processing to the appropriate view for rendering

There shouldn't be any data access or complex business logic in the controller.

[In the simplest of apps, you can probably get away with basic data CRUD actions in your controller, but once you start adding in more than simple Get and Update calls, you are going to want to break out your processing into a separate class.]

Your controllers will usually depend on a 'Service' to do the actual processing work. In your service class you may work directly with your data source (in your case, the DbContext), but once again, if you find yourself writing a lot of business rules in addition to the data access, you will probably want to separate your business logic from your data access.

At that point, you will probably have a class that does nothing but the data access. Sometimes this is called a Repository, but it doesn't really matter what the name is. The point is that all of the code for getting data into and out of the database is in one place.

For every MVC project I've worked on, I've always ended up with a structure like:

Controller

public class BookController : Controller
{
    ILibraryService _libraryService;

    public BookController(ILibraryService libraryService)
    {
        _libraryService = libraryService;
    }

    public ActionResult Details(String isbn)
    {
        Book currentBook = _libraryService.RetrieveBookByISBN(isbn);
        return View(ConvertToBookViewModel(currentBook));
    }

    public ActionResult DoSomethingComplexWithBook(ComplexBookActionRequest request)
    {
        var responseViewModel = _libraryService.ProcessTheComplexStuff(request);
        return View(responseViewModel);
    }
}

Business Service

public class LibraryService : ILibraryService
{
     IBookRepository _bookRepository;
     ICustomerRepository _customerRepository;

     public LibraryService(IBookRepository bookRepository,
                           ICustomerRepository _customerRepository )
     {
          _bookRepository = bookRepository;
          _customerRepository = customerRepository;
     }

     public Book RetrieveBookByISBN(string isbn)
     {
          return _bookRepository.GetBookByISBN(isbn);
     }

     public ComplexBookActionResult ProcessTheComplexStuff(ComplexBookActionRequest request)
     {
          // Possibly some business logic here

          Book book = _bookRepository.GetBookByISBN(request.Isbn);
          Customer customer = _customerRepository.GetCustomerById(request.CustomerId);

          // Probably more business logic here

          _libraryRepository.Save(book);

          return complexBusinessActionResult;

     }
}

Repository

public class BookRepository : IBookRepository
{
     LibraryDBContext _db = new LibraryDBContext();

     public Book GetBookByIsbn(string isbn)
     {
         return _db.Books.Single(b => b.ISBN == isbn);
     }

     // And the rest of the data access
}


问:
How to answer "When will it be done?"
We all have it, problems that prove difficult to fix and working out a fix through obscure code and bizarre unexpected functionality. Slowly, logically working your way through trying to find patterns, errors, mistakes. This process takes time and the issues are often not easily understood by the client.

How does one answer when asked the question "When will it be done?", especially when the client may not understand the inherent complexities of software development?

答:
Developers approach a complex problem by decomposing it into smaller ones and solving them separately.

In an ideal world, solving an issue would be a complex problem A and you would be able, in a given time, to decompose it into a short list of small problems A1 to An, for each evaluating the time is straightforward, given that the time required to solve the initial complex problem would be:

with D being the process of decomposition itself.

In real world, the only problem is that t (D ) would actually be bigger than the time you spend resolving the small problems. In other words, in order to get to this level of decomposition of the problem, you practically need to solve the problem itself.

You can still:

Separate the given task (solving the issue) into smaller chunks, each chunk being still a complex problem,

Evaluate the expected time for each chunk and the corresponding risk.

For example, the task 1 requires approx. 5 hours, but the risk to being blocked doing it is high, so give 12 hours as your expectation to the customer.

Evaluate the dependencies and how they affect the time.

For example, the task 19 requires 2 hours, and the risk is so low that you can say it's 2 hours for sure. Not 1. Not 3. But task 19 relies on task 24: the task 24 may affect the task 19 in a way that you would require to completely rewrite the code of the task 19 using a different approach.

Give all those details to your customer. Don't give the sum.

The last point is important. If you give the sum, let's say 192 hours, the customer believes that it's a very precise metric, and the time you will spend is from, say, 189 to 195 hours.

If, instead, you give the details,

The customer who cares will understand that it's not 192 hours. It's 192 hours if everything goes wrong given the risk determined during the assessment. It's also 238 hours if everything goes even worse. It's also 85 hours if everything is ok.

As for the customer who doesn't care, he will not read your answer in all cases. All he want is a number, to be able to blame you later. By giving a very detailed answer he will never read, you know that he can't ask you for the time it will take again: you already answered that. He also can't blame you later, since he didn't read the answer in order to calculate the sum.

OwnerDisplayName: Emdiesse

Title: How to answer "When will it be done?"


问:
Is there any proprietary PHP MVC framework?
I was doing a small list of PHP MVC framework (like Zend, CakePHP, Yii etc...) and I noticed that all of them are open source.

Then I tried to find some proprietary framework, but my research was unsuccessful.

Is there any  proprietary PHP MVC framework? Why they are so few(if there is any)?

答:
The reason you're not finding anything is probably quite simply a matter of economics - existing open source frameworks are pretty decent these days, and they can be used (and extended) free of charge by the very nature of open source software. Any proprietary competition would have to offer significant extra value to make up for the cost and added inconvenience (no access to the source code, possibly license enforcement, legalities, etc.).

That's not to say no such frameworks exist, but they probably cater to quite specific niches.


问:
Is specializing beneficial in IT industry?
For the past few years I started wondering if it makes sense to learn advanced techniques in some fields of IT, or is it better to be just good at everything, and use the simplest code possible everywhere.

I will use C++ as a language for comparisons, since I'm a C++ developer.

As a C++ developer you can write truly interesting code, ranging from code that looks like C with simple functions all around, to template meta-programming stuff, sometimes intermixed with pure abstract classes.

I've started noticing that I'm leaning towards the later lately.

The problem is, that with larger solutions programmers are rarely working alone, and most likely skills don't overlap that much either. So some parts of code I write might be confusing to other team members, and the other way around.

I might like STL and templates, while other people might prefer pure abstract classes everywhere, others will rely on dynamic_casting, or code generated by VC wizards. While some just enjoy everything written in a very simple, C like manner.

This also backfires with the fact that people who haven't worked with, say, with virtual classes, might not even know why the new class they've derived is broken because of simple missing virtual destructor. So the code you write paves a way toward memory leak if some other people decide to reuse your code later on.

Do you have experience working in environments with multiple developers with different skill-sets? Do you try to find a common dominator in your environments? Does using the skill-sets of every person even works in larger projects?

答:
In 1985 I was highly specialized for one PC. My progs were studied by users and the factory that made these PC provided my progs to all users. The PC extincted three years later. The language was very specific, OS too. All this soft became useless. My knowledges too.

Now I would never put all egs into one basket.


答:
I would say a good team should have a common denominator of knowledge and skills shared by all developers. All competent C++ programmers should have at least a basic understanding of e.g. templates, and know whom to turn to if they see something above their limit. They also should share some more or less common idea of how "good code" is supposed to look. And they should have a more or less realistic picture of their own current skill level, compared both to others in the team and to the "ideal", e.g. the top guns on SO.

Of course, not everyone may be senior even in a good team - it is perfectly OK to have juniors. However, everyone (including themselves) should be clear about the fact that they are juniors (even if only regarding their C++ skills), and they need mentoring plus supervision of the more experienced team members to learn the best practices and apply them correctly.

Now, of course, such teams are rare in real life. However, we should strive towards this ideal. If it turns out that some code you wrote was confusing or unintelligible for another developer and this caused a bug / memory leak / ..., you can bring this up on the team retrospective, and brainstorm ways to avoid such problems in the future. You may decide to establish common coding conventions, to train members lacking specific knowledge / skills, to have workshop(s) discussing the pros and cons of specific coding idioms / patterns / techniques, etc.

The all-important issue here is communication. It is no accident that agile methods focus so much on this. E.g. XP includes pair programming, which makes it naturally easy to spread knowledge and information around within the team, and for new team members to learn the local culture, coding idioms and best practices. Pair programming is not always possible, but communication and discussion within the team should be encouraged and suppported by any means.

Another issue lying behind your examples is code ownership. That different team members use completely different, or even opposing, idioms can easily happen in a project where everyone has his/her own fiefdom, exclusively "owning" some part of the code. However, it happens significantly less often in projects where everyone may touch any piece of code, and where people are - to a greater or lesser extent - regularly rotated between different modules and code parts. This helps share knowledge, increase the "bus factor" and also helps the team forge working, common practices and coding idioms.

Title: Is specializing beneficial in IT industry?

Body:
For the past few years I started wondering if it makes sense to learn advanced techniques in some fields of IT, or is it better to be just good at everything, and use the simplest code possible everywhere.

I will use C++ as a language for comparisons, since I'm a C++ developer.

As a C++ developer you can write truly interesting code, ranging from code that looks like C with simple functions all around, to template meta-programming stuff, sometimes intermixed with pure abstract classes.

I've started noticing that I'm leaning towards the later lately.

The problem is, that with larger solutions programmers are rarely working alone, and most likely skills don't overlap that much either. So some parts of code I write might be confusing to other team members, and the other way around.

I might like STL and templates, while other people might prefer pure abstract classes everywhere, others will rely on dynamic_casting, or code generated by VC wizards. While some just enjoy everything written in a very simple, C like manner.

This also backfires with the fact that people who haven't worked with, say, with virtual classes, might not even know why the new class they've derived is broken because of simple missing virtual destructor. So the code you write paves a way toward memory leak if some other people decide to reuse your code later on.

Do you have experience working in environments with multiple developers with different skill-sets? Do you try to find a common dominator in your environments? Does using the skill-sets of every person even works in larger projects?


答:
To add to tdammers' answer...

There are a huge number of companies who insist to build everything from scratch.  By doing so, it's likely to be kept private since they consider it their own valuable IP.  They pay for all of the development on their internal code-base.  There are pros and cons to this.

Open source on the other hand, which may even start out as proprietary, typically has a larger contributor base. This results in a pile of benefits for users, assuming the project is successful:

More resources have worked on it (more testing, planning, development, support, documentation, etc.)

Larger talent pool / ecosystem (consider hiring)

Less training for new hires

Less maintenance

Effectively you can delegate a large portion of your code-base to the free community, which, if the community works, is a lot more powerful than your own small team.  It also adds the risks of too many eyes (more vulnerabilities found - which can be seen as good or bad).

It doesn't make sense to have commercial frameworks in PHP.  PHP is open source by nature, so any commercial projects always seem a little foreign and it adds too much barrier to entry.   A commercial framework may be good, but it's very high risk for anyone to use without some serious backing.  The size of a project's community usually comes across as security or longevity.  Additionally, without a large community backing, the company releasing it will likely gain very little.

Hope this helps.

Body:
I was doing a small list of PHP MVC framework (like Zend, CakePHP, Yii etc...) and I noticed that all of them are open source.

Then I tried to find some proprietary framework, but my research was unsuccessful.

Is there any  proprietary PHP MVC framework? Why they are so few(if there is any)?


答:
is it better to be just good at everything

No. You can't be good at everything. Be good at what gets you hired for the longest time if you are doing programming for living, that is do what the market wants (some will say do what you want but its up-to you!).

The problem is, that with larger solutions programmers are rarely working alone, and most likely skills don't overlap that much either. So some parts of code I write might be confusing to other team members, and the other way around.

This is not how it usually goes. In a project with 10 people, you are likely to find 1 DBA, 2 people for testing, 1 graphics designer and the rest are all developers. Other developers with your area of expertise need to understand your code. But the DBA does not. Hence you talk to pears. It is not common to be the sole C++ developer in a project unless the project core language is Java and you are brought in for integration or because you know a legacy application that uses C++ or the likes.
In any case you should learn to write readable code by others and you shoul learn to read other people's code.
In good projects, there are coding standards, most developers follow them and that makes code more or less have the same flavor. If you don't get something, just ask, you are supposed to be a part of a team and everyone should help everyone else - This is team work, part of that is to share knowledge with your team. If you have a better way to do things you demo that to the rest. If they like it, fine, if not, go with the flow - It is that simple!


答:
I agree with some of the answers already given but I think they're also an underlying point not being discussed about reading code. When I first started looking at some open source code it seemed overwhelming and huge. But guess what? it's always going to be huge. At some point you realize you get better at extracting what you specifically want to know and moving on.

One example you gave was looking at a bunch of HTML code, however:

Why are you looking at HTML code? Probably not because you want to learn the HTML of the entire site. There's probably a specific trick you are hoping to pick up. In that case, just find the relevant HTML with a tool like firebug.

If you really want to learn how the whole site is made, you realized rendered HTML is not the way to do it. You would be better off looking at an open source project using similar technology. However, trying to learn an entire project's code is not as worthwhile as it sounds. It's boring, time consuming, easy to forget what you learned, and you have nothing to show for it at the end. You will learn less from reading other peoples' code endlessly and much more by using specific, interesting pieces of it to write plugins, feature additions, or as scaffolds and advice for your own projects.

Try to learn the absolute minimum to get something of your own working. Only go back to your reference points when you get stuck or want to learn a specific new thing. This goes against some conventional wisdom that you have to understand everything or else you're programming in the dark. But eventually you realize that goal is impossible and you learn to balance the goals of knowing everything and the goal of actually finishing what you're working on.


答:
The short answer is YES but a lot of it depends on how you define experience.

I think there are at least 3 parts to development. As you get better at each segment, certain things become clearer.

Understanding the BUSINESS requirements.
This gives you a better bird's eye view of the application. The better you can understand why the business rules are what they are, the quicker you pick up on why certain things are done in a certain way.
E.g. Your customers need to comply to government regulation X, which is why they need to prepare document Y, which is why they need this seemingly useless information stored.

Understanding the TECHNICAL requirements.
This is like #1 except its more about understanding why on a technical level. Some tools and technologies have their own quirks, until you have dealt with them before it's hard to understand why things are done in a certain way. This is more apparent when you deal with legacy systems.
E.g. The application uses a particular service bus that only takes XML.

Understanding the LANGUAGE requirements.
Like others have mentioned, the more experienced you are with a language, the quicker you can read what the original coder was trying to achieve. Yet without #1 and #2, you will find that this increased ability peaks pretty quickly.

Try to be involved in multiple aspects of development because it really doesn't become easier until you have done all the areas at least a few times.

Remember that perfection (and purpose) in someone else's code is always relative to #1 and #2. These are the primary drivers of why the code is in the state it is in. Frequent changes in those two areas are the biggest reason why we get spaghetti code all the time. So unless you are adept at reading the business and technical requirements, the task of reading code will always be a royal PITA.


答:
Typically I use a modified formula from CPM/PERT. It's something like this:

```<code>Mn + Mx + C(T) / 2 + C, where
Mn is the minimum number of hours you think it will take,
Mx is the maximum number of hours you think it will take,
T is the typical number of hours it takes,
and C is a confidence factor from 1 - 3 based on how much you've done similar things.
</code>```

(I'm not sure how to do all the fancy math formatting; if someone wants to edit this for that, then feel free.)

```<code>So, if you think:
Mn = 60  hours
Mx = 180 hours
T  = 100 hours
C  = 2
Then: 60 + 180 + 2(100) / 4 = 110 hours.
</code>```

I'd emphasize that it could vary significantly, depending on how the project goes. If you reevaluate your project every few days, you could even supply a weekly update. It goes a long way towards satisfying irritable clients. :)

Title: How to answer "When will it be done?"

Body:
We all have it, problems that prove difficult to fix and working out a fix through obscure code and bizarre unexpected functionality. Slowly, logically working your way through trying to find patterns, errors, mistakes. This process takes time and the issues are often not easily understood by the client.

How does one answer when asked the question "When will it be done?", especially when the client may not understand the inherent complexities of software development?

Body:
Typically I use a modified formula from CPM/PERT. It's something like this:

Mn + Mx + C(T) / 2 + C, where
Mn is the minimum number of hours you think it will take,
Mx is the maximum number of hours you think it will take,
T is the typical number of hours it takes,
and C is a confidence factor from 1 - 3 based on how much you've done similar things.

(I'm not sure how to do all the fancy math formatting; if someone wants to edit this for that, then feel free.)

So, if you think:
Mn = 60  hours
Mx = 180 hours
T  = 100 hours
C  = 2
Then: 60 + 180 + 2(100) / 4 = 110 hours.

I'd emphasize that it could vary significantly, depending on how the project goes. If you reevaluate your project every few days, you could even supply a weekly update. It goes a long way towards satisfying irritable clients. :)


答:
The question, in a nutshell, is if these things become clearer to a programmer as he advances in his career. Do complicated topics as the ones listed above (OpenGL, MySQL, advanced html sites) become easier to read, write and understand as you learn more, or does it just get more complicated as you go by? How can you combat this feeling that you're an ant in the programming world and this stuff is the foot about to squash you?

I'm going to take a slightly different tack than the other respondents; I believe that reading and writing code does in fact get easier as you do it more, and I'll demonstrate it with a simple analogy.

Think of when you first started playing sports. At the very beginning with the first sport you learned, basic coordination for the simple tasks of a single sport probably seemed really hard. As you got a little more experienced, you started mastering the simple tasks so that you didn't have to think about them any more, and you noticed that there were more complex tasks that you could pay attention to (like watching other players to predict their behavior).

Then, when you tried your hand at another sport, you probably found you weren't so far behind when you started out. Catching a basketball is much different than catching a baseball, but somebody who's mastered one of them will have a much easier time picking up the other than a person who's never done either one before. With your experience practicing a second sport, you discovered that the first sport gave you both specific and generic skills. Specific skills (catching a basketball) are useful only in their domain, but generic skills (tracking a fast-moving object approaching in three-dimensional space and developing a plan to deal with it) make you better at all related domains.

What does this have to do with programming? The first line of code you read exposes you to a world built on certain rules. You learned those rules (that language's syntax and idioms) as specific skills, but you also learned some valuable generic skills: understanding how computers operate internally, and how to express your intentions in a way a computer can understand. Each new language you learn gives you some new specific skills, but it also strengthens your generic skills and helps you see the patterns shot through all computer languages like mineral deposits layered along a canyon wall. Once you get really familiar with a few different languages, you start being able to recognize the "shape" of most any code, if you'll pardon the vagueness, even if you don't know anything about the language it's written in.

For instance, all three languages you mentioned (MYSQL, OpenGL, C++) have some common features:

It's possible to compute small parts of an algorithm separately and compose them into a complete solution later on

The computer usually requires some amount of general preparation before you can start working on your specific problem (creating a table, initializing a canvas, or perhaps loading common libraries)

Earlier statements take precedence and affect later statements, i.e. the computer starts at the top of the code and works its way down

The more programming you do, the more you'll realize that no matter what the ball is shaped like, it's still just a ball coming towards you, and you know what to do with it without having to think too much about it. All programming is about attempting to express your intentions in a way the computer can understand; learn enough and you'll start to be able to read the intentions instead of the code.

P.S.- Each and every time, when you finally start feeling like you know your way around, you'll run into something that absolutely breaks your brain and makes you feel like a rank beginner. That's what we love about this job, there's always something new to learn.


问:
Static functions vs classes
Let's say that I want to build some utility functions to do some basic maths with the BigDecimals, for example I want to have a function that computes the average of a List<BigDecimal>.

What is the best approach? A static function or a utility class?

```<code>public static BigDecimal computeAverage(List<BigDecimal> numbers)
</code>```

or

```<code>public class BigDecimalUtil

public computeAverage(List<BigDecimal> numbers)
</code>```

答:
If you want to do utility functions, connected by some theme, make a class for them, make them static in that class and make a constructor of that class private, to eliminate the possibility of accidental giving out an instance. So, use the second variant, but hide the constructor.

```<code>public class BigDecimalUtil

public computeAverage(List<BigDecimal> numbers)

private BigDecimalUtil(){super();}
</code>```

There is one more possibility - to make no constructor and make this class abstract. But on this way you can't use instance of the class not only outside, but also inside it. So, I think, this second variant is too strict for you. Choose yourself.

Title: Static functions vs classes

Body:
If you want to do utility functions, connected by some theme, make a class for them, make them static in that class and make a constructor of that class private, to eliminate the possibility of accidental giving out an instance. So, use the second variant, but hide the constructor.

public class BigDecimalUtil

public computeAverage(List<BigDecimal> numbers)

private BigDecimalUtil(){super();}

There is one more possibility - to make no constructor and make this class abstract. But on this way you can't use instance of the class not only outside, but also inside it. So, I think, this second variant is too strict for you. Choose yourself.

OwnerDisplayName: Gangnus


问:
How clean should new code be?
I'm the lead designer in our team, which means I'm responsible for the quality of the code; functionality, maintainability and readability.

How clean should I require my team members' code to be if we are not short on time?

In my view, we should clean up old code we modify; adding a line to a method means you clean up that method.

But what about new code?

We could make it sparkling clean, so that if another coder comes along tomorrow and makes a small modification, she doesn't have to clean it up at all. But that means if no-one ever reads that piece of code again, we've wasted time making it sparkling clean.

Should we aim for "almost clean" and then clean it up further on future visits? But that would mean not getting the full value for the understanding we had when we wrote it in the first place.

Right now, I'm going for "sparkling clean"; partly as a tutorial for my colleagues who are not as picky as I.

答:
From Refactoring: Improving the Design of Existing Code, p58;

The first time you do something, you just do it.

The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway.

The third time you do something similar, you refactor.

Title: How clean should new code be?


答:
I agree with @Gangnus that a static "wrapper" class makes sense if individual class methods will always be used in isolation, and this is often going to be a good answer.

However, there might be some value in a non-static class, with non-static methods, if you have related calculations likely to be used together. For example, construct a ListStatsUtil object with List<BigDecimal> passed into constructor, it might be convenient to access getStandardDeviation, getVariance, and getAverage in sequence without passing back in the object. This may be more elegant, but might also perform better, especially if computationally expensive operations are involved that can be optimized across operations by sharing private state within the object.

```<code>public ListStatsUtil {
    private final List<BigDecimal> numbers;
    public ListStatsUtil(List<BigDecimal> numbers) {
        this.numbers = numbers;
    }
    public BigDecimal getAverage() {
        // return average of this.numbers
    }
    public BigDecimal getStandardDeviation() {
        // return std dev of this.numbers
    }
    public BigDecimal getVariance() {
        // return variance of this.numbers
    }
    public BigDecimal getMax() {
        // return max of this.numbers
    }
    public BigDecimal getMin() {
        // return min of this.numbers
    }
}
</code>```

Title: Static functions vs classes

Body:
Let's say that I want to build some utility functions to do some basic maths with the BigDecimals, for example I want to have a function that computes the average of a List<BigDecimal>.

What is the best approach? A static function or a utility class?

```<code>public static BigDecimal computeAverage(List<BigDecimal> numbers)
</code>```

or

```<code>public class BigDecimalUtil

public computeAverage(List<BigDecimal> numbers)
</code>```

Body:
I agree with @Gangnus that a static "wrapper" class makes sense if individual class methods will always be used in isolation, and this is often going to be a good answer.

However, there might be some value in a non-static class, with non-static methods, if you have related calculations likely to be used together. For example, construct a ListStatsUtil object with List<BigDecimal> passed into constructor, it might be convenient to access getStandardDeviation, getVariance, and getAverage in sequence without passing back in the object. This may be more elegant, but might also perform better, especially if computationally expensive operations are involved that can be optimized across operations by sharing private state within the object.

public ListStatsUtil {
    private final List<BigDecimal> numbers;
    public ListStatsUtil(List<BigDecimal> numbers) {
        this.numbers = numbers;
    }
    public BigDecimal getAverage() {
        // return average of this.numbers
    }
    public BigDecimal getStandardDeviation() {
        // return std dev of this.numbers
    }
    public BigDecimal getVariance() {
        // return variance of this.numbers
    }
    public BigDecimal getMax() {
        // return max of this.numbers
    }
    public BigDecimal getMin() {
        // return min of this.numbers
    }
}


答: I'm probably going to give away my C# leanings in the worst possible way, but I'd always recommend static methods within utility classes. This gives you the best of both worlds. The organizational benefits of the class with the usability of methods accessed without needing to instantiate an object to use them. If your utility class has a reason to occasionally vary its behaviour, then you are already well positioned to do so by introducing inheritance/interfaces later should you need to. If you wish your design to be a little more portable, then you'll find the paradigm will more easily transfer to other OO languages.</p>

Title: Static functions vs classes


问:
What is the proper way to write a setter?
I am am trying to learn JAVA on my own.  In one book I am reading the author says there is no convention for writing a correct setter.  His example would go something like this:

```<code>public void setUnitCost(double inUnitCost) {
     unitCost = inUnitCost;
}
</code>```

However, when using Eclipse, and tell it to create getters and setters it does this:

```<code>public void setUnitCost (double unitCost){
     this.unitCost = unitCost;
}
</code>```

My question is which way is better?  Does it make a difference in the programming world?  What exactly is the difference between the two?

答:
There is no significant difference between the two.

The difference (aside from the whitespace) is that one explicitly uses this to set the new value. As far as I know, there isn't any advantage or disadvantage to doing that.


答:
As an automatic code generation tool, the Eclipse generator is not necessarily beholden to the same rules which govern what's worth the effort for human programmers. Don't forget that.

The two are entirely equivalent in this case, however.

Title: What is the proper way to write a setter?

Body:
I am am trying to learn JAVA on my own.  In one book I am reading the author says there is no convention for writing a correct setter.  His example would go something like this:

```<code>public void setUnitCost(double inUnitCost) {
     unitCost = inUnitCost;
}
</code>```

However, when using Eclipse, and tell it to create getters and setters it does this:

```<code>public void setUnitCost (double unitCost){
     this.unitCost = unitCost;
}
</code>```

My question is which way is better?  Does it make a difference in the programming world?  What exactly is the difference between the two?


问:
WCF and Service Registry
I am about to build some WCF Services. Those services need to communicate to each others too, in some scenarios.

I've done some "Google-ing" about Service Registry but can't figure out how to implement service registry with WCF; is there any other alternate?

Is there any Microsoft technology available for Service Registry?

I'm new to SOA and I will really appreciate any help or guidance (what and where should I exactly look for registry services).

答:
Please describe what you think a Service Registry is. If it is the same as a UDDI registry, I recommend you NOT do this, certainly not at first, possibly not ever. The reasons to NOT use include (a) complexity, (b) low value, and (c) lack of industry support.

If you are trying to figure out how your services will be found and accessed, focus on WSDL and good old documentation. You may also want to read about some SOA principles to guide your design, and also think about whether you want REST services or SOAP services.

(Sigh... I do not have sufficient permissions on this site to post more than two links, so I deleted the REST and SOAP links. You can find descriptions on Wikipedia.)

REST services are more common over the public internet, whereas SOAP services are more common within a company. There are more tools for SOAP. REST is lighter weight, but a little more programming.

Good luck! -Bill

Title: WCF and Service Registry


问:
WCF service which takes XML file
I have a client requirement where I need to expose  a web service which takes XML. Client will consume my web service and send XML .

This web service need to be async.

Could you please suggest any good proven approach ? with advantage / disadvantage

答:
Are you sure the actual payload is XML, or just that the serialization format is XML?

Usually when people use WCF Services they define an object (in C#, for example) to pass across the wire. A good style is to pass a single C# object as the parameter to your service (FooRequest) and have the service return a single object (FooResponse). These objects will contain all the data you need to move. Of course, they can reference other objects, etc. You don't want to pass over any data structures that are .NET-specific (like a Dictionary object or a DataSet); ideally you will pass generic objects that make sense in any platform.

You will need to ensure your objects are serializable, but that is usually not hard.

It just so happens that WCF chooses to serialize this to XML while it travels across the wire, but you don't need to do that work explicitly. You don't necessarily even need to know this. There are other possible formats too, like JSON.

Just go through virtually any WCF tutorial (such as this one) to see what I mean. Focus on clean interfaces, clear logic, good names - not on the wire format. You may want to read about SOA principles.

[edit] Regarding ASync - if you import the WSDL with Visual Studio, a client-side proxy will be generated. This is how you access the service from client code. This will include methods that allow you to call the service asynchronously. See the tuturial link mentioned earlier.

Even if on the off chance your requirement is to include some arbitrary XML, you can still use this approach. Simply place the XML as a string into a string member in your request/response objects.

Good luck! -Bill

Title: WCF service which takes XML file


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

Example:

I have an API that represents a todo list.

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

That API can reference remote TODO services.

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

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

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

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

In a rpc sort of way, one could do

POST /todo_services/abc123/sync/

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

答:
This is a hard problem. I do not believe REST is an appropriate level to implement sync. A robust sync would essentially need to be a distributed transaction. REST is not the tool for that job.

(Assumption: by "sync" you are implying that either resource can change independently of the other at any time, and you want the ability to realign them without losing updates.)

You may want to consider making one the "master" and the other the "slave" so that you can confidently clobber the slave periodically with data from the master.

You may also wish to consider the Microsoft Sync Framework if you absolutely need to support independently changing data stores. This would not work through REST, but behind the scenes.


答: It's just a style choice.  Some programmers get annoyed by having to come up with stupid names like inUnitCost or newUnitCost for the function parameters.  Some get annoyed by having to notice the unitCost symbol from the function parameter overrides the unitCost symbol for the object member.  You should stick with whatever consensus you reach with your colleagues.


答:
There is no significant difference. They both produce the same result.

I personally prefer the Eclipse version, as I find:

It is more elegant for the name in the parameter list to be the same as the field used internally in the object.

Having the unitCost parameter name looks and works better in code completion than inUnitCost or similar (since you are also likely to use the name unitCost in calling code).

It is nice to be explicit about the fact that you are setting a field with the this. My code pattern recognition here immediately says "ah... this line is setting a field in the current object".

But that's ultimately just a style choice.


问:
How is oData different from a REST service?
I am looking into writing a web service API and I am thinking of creating a REST service. What does OData means in this context? Can you please explain the difference between OData and REST? </p>

答:
I agree with both @jkohlhepp and @Tom Squires, though will add a couple of details.

OData is an open standard (championed by Microsoft, but adopted beyond Microsoft, and available for many platforms, including iOS and Android).

OData payloads are based on Atom (read) and AtomPub (update) format. (As an aside, Atom is also the basis for a popular RSS feed format.) Atom is extensible, and OData has taken advantage of this to create well-known extensions. For example, with an OData service there are URI Conventions with many capabilities, such as filtering (filter by date, or customer name) and sorting and so forth. Using these special conventions in a standard (OData-defined) way makes OData powerful since they act similar and we can build tools to work against them and such.

There are some well-known OData sources available, such as by Netflix (all their movie data is there - can be fun to play with!).

Read all about OData at odata.org.

Good luck! -Bill


问:
How can I bootstrap a software development community at my school?
I'm a student at the University of South Florida who's frustrated with the educational environment in the Computer Science program. Right now, I'm taking "Program Design." I should be learning how to organize my source code into functions and modules in order to make my programs readable and maintainable; instead, I'm learning about arrays and recursion in C. Next semester, I have to take "Object-Oriented Design," which is taught through C++ (shudder.)

Two years ago, I fell in love with programming, and I've been learning as much as I could since then. The prospect of taking another C++ class bores me almost to tears. For that reason, I thought I would start a programming club in order to meet similarly ambitious students, learn new languages, discuss software development topics, and work with other students developers.

However, I'm beginning to realize that there may not be any other students who share my software development experience. It's not because of a lack of motivation but a lack of opportunity: I know of only one other programming class ("Programming Languages") and no classes on real-world software development. Everybody else only has experience writing trivial scripts in C and C++.

I've realized that if I want to work with other student software developers, I'm going to have to train them myself. Now, I'm planning to make the club a software development bootcamp, teaching members how to develop software with modern tools and languages. Obviously, starting an unofficial software development course is a monumental task with many possible approaches. My question to you, dear reader, is

What's my plan of attack?

Should I

lecture the club myself, trying to balance club work with homework?

ask the CS faculty to teach on topics within their expertise which may be less than relevant to members?

try to find a sympathetic, experienced developer inside or outside the school who can share my workload?

show video lectures (from MIT OpenCourseWare, Google Tech Talks, etc)?

hold hands-on programming workshops?

assign homework?

do something else?

答:
You're right that you need some structure; you want to force yourself and the others to learn, and not just sit around gabbing about software/bitching about the lousy course selection.  But I'm not sure treating this as a class with you as its teacher is the way to go; you're not an expert yet, and you're in this to learn something, too.

How about organizing the club around software projects?  Not some toy homework programs, but something you think you might actually find useful.  (Note that "marginally useful" still qualifies as "useful"; you're trying to learn-by-doing, not found a startup.  :-)  )  If the club has enough people for multiple teams, form multiple teams.  The team decides what language it wants to use, what the specs are, how labor is to be divided, etc., etc., and works on it individually in their own time.  Then at your weekly club meeting, you discuss how it's going face to face, where the roadblocks are, neat stuff you've learned, etc.

I also really like the idea of bringing in guest lecturers, be they faculty, professionals, or videos that you or somebody else thinks are worth sharing.  So, you could organize a nightly meeting like this:

Guest lecture on some software topic from somebody who knows it well.

Q&A/gab session on the lecture (hopefully with the lecturer participating, but just amongst yourselves for videos).

Divide into project teams, do project stuff.

That'll take up an evening and stuff it full of knowledge-enhancing goodness.  Hopefully.

Regardless, I wish you luck with this project.  When you get it off the ground, I hope you'll come back here and tell us how it's working out.


问:
Designing authentication for REST API
I'm working up an API for a REST service that I'm going to both be producing and consuming. I've spent the past few days trying to figure out how to handle authentication nicely, and think I've finally come up with something.

I'm coming up with this based on the following facts about the application stack:

Client & Server are in .NET4 (Client part in Client Profile)

Server exposes using WCF REST

I really don't want to keep the user name and password in memory in the app

From 3, I wanted to use a form of token authentication, so that after the credentials are verified by the server, the client gets a token back to use throughout the rest of the app (this will allow me to do other things, such as timing out users, being able to move users seamlessly between the web and desktop versions, etc). After figuring out how to make the calls replay and tamper resistant, I've come up with the following:

Before the client attempts to authenticate, it generates a Diffie-Hellman key pair using the ECDiffieHellmanCng class.

It sends the public part of the key pair over the wire along with the user name and password (Over HTTPS of course).

Server authenticates the username/password combination, if successful, it then does the following:

Creates a unique session token

Generates its own DH key pair, and calculate the shared secret from the public key provided by the client

Makes note of the session token, the shared secret, the user, and the "last action" time (used for a rolling expiration window) in its database

Returns the session token, its public DH key, and an authentication success message

Client takes the DH key from the response, calculates the shared secret, and store both token and secret in memory.

From this point on, the session token/secret combination works like most other REST APIs, with the request being fingerprinted and timestamped, and then have some sort of HMAC generated. Whenever a client performs an action against the server, it checks the token/secret pair, and allows the action if it is valid and not expired, and updates the last action record in the session.

I don't see any obvious flaws, and is probably over-engineered for this, but I need to learn how to do this at some point. The HMAC prevents replay attacks, the DH negotiation helps prevent MITM attacks (I can't think of a workable attack off the top of my head between HMAC/DH).

Any holes anyone can poke in this?

答:
I agree 100% with @S.Lott that you don't want to roll your own. I suggest looking at another alternative: the Windows Azure Access Control Service (ACS). ACS is costs money, but it is very cheap (10,000 transactions for $0.01) and a good deal of infrastructure is handled. WIF is leveraged on the client.

This is also a standards-based / claims-based solution - which is all the rage.
Check out this article on using WCF and REST and ACS together.

If you are thinking of the future, this is also a mechanism that can grow with you - as you have mobile apps outside the firewall, partners, and so forth. Even if you don't want to use it since it adds a dependency outside of your firewall, you may want to check it out for ideas. Very slick.

Good luck! -Bill

Title: Designing authentication for REST API


答:
Explaining vague timelines to non technical users is tough.  This is true both in creative phases of a project, and when tracking down a pesky bug.  In both cases the traditional "decompose the work to smaller pieces" doesn't work as well.

The original task focuses on the latter case so let's dwell on that.  If you can't give a timeline, tell the user what you will try and when you will get back to them.  When you reach the halfway point on the self imposed timeline give a short and honest email update.  At least an hour before the deadline give your formal response.  Now you have credibility.  If the problem isn't solved at least you are shining some light.  It may seem like a waste of time, but it isn't.

Title: How to answer "When will it be done?"


问:
How do you maximise the knowledge that you gain from a programming book?
Not because I care how long it takes someone to read a book, but more because I'm interested in how people get the knowledge from a book (or I guess other sources) into their brains in the best, most efficient way.

Personally I take a multi-pass approach (from my answer to the original question):

Skim through contents, dip in and read anything with an interesting looking heading and finally gawp at any nice diagrams and illustrations. I won't take much in at this stage, but it gives me a mental view of the book (an hour or so at most)

First pass through the book, generally I'll read the opening chapters thoroughly for a book that is either very heavy going or introduces something completely new. For books that cover a subject I already know about I'll skim or skip bits that seem trivial. The remainder of the book I'll go through reasonably quickly but not so quickly that I'm just page flipping. (about a week)

Not all books that I read make it this far, but if I find a book interesting or useful enough I'll then study it properly. I will go through the book at a slower pace and do some or all of the examples, try out code, etc. I will often skip entire chapters here unless the book is really good (1-3 weeks depending on the book).

Finally when I've finished reading it and am reading other books I will often dip into it again and again to cross-reference, compare, look things up, browse, etc - so many of my favourite books don't just end up gathering dust on the bookshelf.

I rarely take notes when reading (although I may do some planning on paper if I'm working through something like a code sample). I've also considered starting to use a personal kanban for organising my progress, but have never quite got around to using that technique. Mindmaps are another thing I like the idea of but rarely do.

What other methods to people have? How successful do you find them? Are there any commonly recommended techniques that you feel are a waste of time?

答: Go over it with a friend. Better yet consider reading the book an exercise like Pair Programming, where you both try to explain it to each other. (And of course do the exercises as was said above)</p>


问:
Synchronizing local and remote cache in distributed caching
With a distributed cache, a subset of the cache is kept locally while the rest is held remotely.

In a get operation, if the entry is not available locally, the remote cache will be used and and the entry is added to local cache.

In a put operation, both the local cache and remote cache are updated. Other nodes in the cluster also need to be notified to invalidate their local cache as well.

What's a simplest way to achieve this if you implemented it yourself, assuming that nodes are not aware of each other.

Edit
My current implementation goes like this:

Each cache entry contains a time stamp.

Put operation will update local cache and remote cache

Get operation will try local cache then remote cache

A background thread on each node will check remote cache periodically for each entry in local cache. If the timestamp on remote is newer overwrite the local.  If entry is not found in remote, delete it from local.

答:
Unfortunately I think unless there's a single synchronization point, you can't guarantee the cache to have the most fresh data.

However, if you create the single point, you'd end up with performance issue because everything has to go there first and if it is a distributed system it will be a network call and performance bottleneck.

A better way around this is to push back to the analysts stating that if they have a requirement to have the latest data possible when the data can change then caching is not an option.  Instead faster network and hardware is needed, this is many factors cheaper than getting a developers to code some custom caching solution that does not really work anyway.


答:
Since you can't account for the unknown roadblocks and unforeseen surprises, it can be challenging to estimate with confidence. Ideas:

Try a range - "I am sure it will take at least N days (e.g. 3), but might take as many as 4N."

Seek the support of more senior engineers in estimating & defending estimates.

Work in shorter iterations (Agile / Scrum style) to produce minimum code that adds business value (gaining confidence & trust), then repeat.

Learn negotiation skills from a book like the classic Getting to Yes (http://www.amazon.com/gp/aw/d/0143118757).

Title: How to answer "When will it be done?"


答:
The first example is likely to be seen in some circles as poor convention as it makes the input value look as though it is in Hungarian Notation.

Many code completion and formatting tools will encourage you to use this in order to be explicit in your use of variables.  I tend to agree with this, as it makes it very clear at a glance whether the variable is local or belongs to the class. Of course, if you are keeping all of your methods nice and short on the order of only a few lines, and the method parameter lists are likewise quite short, then it may not necessarily be an issue for you. Personally I still prefer to see this liberally sprinkled around the code, as this makes variables stand out distinctly due to the syntax highlighting that most modern IDE's provide you with, and the less I have to actually look into the code too deeply, the less distracted I get when jumping around the code while trying to solve complex logic problems in my head.

With that said, the compiler won't care a jot which way you've written your setters. Your colleagues on the other hand may have differing opinions, so it is up to you all to decide which approach you might wish to enshrine in a coding standard.


问:
Software license restricting commercial usage like CC BY-NC-SA
I want to distribute my software under license like Creative Commons Attribution - Non commercial - Share Alike license, i.e.

Redistribution of source code and binaries is freely.

Modified version of program have to be distributed under the same license. Attribution to original project should be supplied to.

Restrict any kind of commercial usage.

However CC does not recommend to use their licenses for software. Is there this kind of software license I could apply? Better if public license, but as far as I know US laws says that only EULA could restrict usage of received copy?

答:
Your requirements restrict the use of the software, so at least by the definition of open source from the OSI (definition of open source), it is therefore not open source, so you will find no help in open source licenses. So forget AGPL, GPL, BSD, Apache, MIT, etc.

I also looked at the Aladdin license as suggested by @thiton. This does not restrict commercial use, only sale (just as @thiton pointed out). If that is not strong enough, you may want to start with the wording from, say, MIT license and add you restrictions (but don't call it the MIT license of course, and don't call it open source).

Like crypto, licensing is hard, and rolling your own is tricky. The world doesn't like more licenses (they add friction), and is part of why OSI exists - to catalog and promote existing "good" licenses for open source so people don't roll their own. Hope it works out.


问:
Does programming in general become easier to read, write and understand as you gain experience?
I'm a beginner in programming and I've been reading books, studying, reading articles, and whatnot. I'm getting great results since I've started learning programming, and when I was a beginner I used to think I knew everything about programming, but as I learned more I realized how difficult this field is (In fact all fields are difficult, but that's not the point).

Nowadays, I've written functional software and I've learned the BASICS of 3 languages and I'm intermediate in just one language. When I look at advanced things like MYSQL, or OpenGL programming, or even visual studio C++ code it gives me headaches, and even when visualising HTML source code of many websites (Most source codes on websites, seen by google chrome seem very messy and unorganized) it makes me confused to the very limit of my brain. It all seems simple at first, yet when looking at these advanced things it just makes me wonder how can one learn so much.

The question, in a nutshell, is if these things become clearer to a programmer as he advances in his career. Do complicated topics as the ones listed above (OpenGL, MySQL, advanced html sites) become easier to read, write and understand as you learn more, or does it just get more complicated as you go by? How can you combat this feeling that you're an ant in the programming world and this stuff is the foot about to squash you?

答:
Short Answer: Yes, in general

However, you will not become a specialist if you generalize. Becoming a specialist also means realizing all the things you do not know: this is can be an overwhelming feeling.

As you move through time, you gain experience.

As you move through time, other languages/patterns etc are developing parallel to your development.

Another variable to your question, is if you are gaining meaningful experience in relation to the industry as it also moves through the same constant time. The tech industry is a moving target and unlike most other industries.

A good question might also be, are you spreading yourself too thin or to thick on a certain language.


答:
Personally, I think it is hard to avoid at least some specialization. I would just try to focus more on a some-what broad field instead of a really specific one. Let me use 'Bill' and 'Bob' as examples here to describe why I think this is important. So this one large company has a large mainframe of brand X, and the languages it is programmed in are called Xasm and Xc. Bill and Bob are put on a team that is dedicated to improving the security of this mainframe. Bill focuses on security programming in general, and learns the theory behind active venerability management and such, while Bob devotes himself to programming on the machine, and how to migitage threats on this machine's special OS. Suddenly, the company that makes X brand mainframes sells itself to Y and X's designs are phased out. Now because Bill has a great amount of expertise on the field of threat mitigation, along with the knowledge of how to use the old mainframe, he is still of great value to the company, as only minor retraining is required. Bob, on the other hand, only knows about how to mitigate threats that exist on X brand mainframes, many of which may have no counterpart on Y.

I rest my case