问:
What's the dominant naming convention for variables in PHP: camelcase or underscores?
The consensus seems to be that one should follow the convention of the platform they're developing for. See:

Underscore or camelcase?

Naming conventions: camelCase versus underscore_case?

However, PHP doesn't seem to strictly follow any convention internally (no surprises there), even for methods and functions (e.g. mysqli::set_local_infile_default,
PDOStatement::debugDumpParams); however, underscores seem to be dominant in function names.

However, what I couldn't find was this: what's the dominant naming convention for variables in PHP?

答:
There is no definitive naming convention in PHP, and they differ by framework:

Zend does not permit underscores

Symfony also encourages camelCase

Wordpress encourages underscores and does not like camelCase

CodeIgniter also promotes underscores

So: Use whatever your framework uses or create your own naming convention.

At least for function names and class methods, there is a one thing to consider, but some frameworks discard it: PHP is case insensitive in that case, so aTonalFunction() and atonalFunction() are both calls to the same function.


问:
MVC : Does Code to save data in cache or session belongs in controller?
I'm a bit confused if saving the information to session code below, belongs in the controller action as shown below or should it be part of my Model?

I would add that I have other controller methods that will read this session value later.

```<code>  public ActionResult AddFriend(FriendsContext viewModel)
  {
        if (!ModelState.IsValid)
        {
            return View(viewModel);
        }

        // Start - Confused if the code block below belongs in Controller?

        Friend friend = new Friend();
        friend.FirstName = viewModel.FirstName;
        friend.LastName = viewModel.LastName;
        friend.Email = viewModel.UserEmail;

        httpContext.Session["latest-friend"] = friend;

        // End Confusion

        return RedirectToAction("Home");
    }
</code>```

I thought about adding a static utility class in my Model which does something like below, but it just seems stupid to add 2 lines of code in another file.

```<code>public static void SaveLatestFriend(Friend friend, HttpContextBase httpContext)
{
    httpContext.Session["latest-friend"] = friend;
}

public static Friend GetLatestFriend(HttpContextBase httpContext)
{
    return httpContext.Session["latest-friend"] as Friend;
}
</code>```

答:
Storing data should be done in the model:

The way the data is stored is not important to the controller, so it should be handled in the model. So, when you change the storage from session to a database for whatever reason, you will just have to change the model.

ContentLicense: CC BY-SA 3.0


问:
Coding style (do more, then simplify)
I'm a CS student and I have been coding for a few months shy of a year now, and I seem to have developed what I think may be a "bad" habit and I'm wondering if anyone does the same (or whether it's a bad habit at all). When I'm coding / solving a problem with code, I find that my initial implementation is lengthy and overly-complicated; in other words, there is a lot of extraneous code (variables, checks) that is simply not needed. When I finish the initial "draft," and make sure the code actually works, I simplify it and make it easier to understand/less verbose.

I think the reason I do this is that I have trouble foreseeing what I will need to complete a task and end up over-compensating and creating complexities that should not or need not exist. Anyone have any tips or advice on how to improve this facet of my coding style, or any input as to whether the habit is actually a bad one?

答: The best coders and average coders usually have similar code, the difference is how long it takes them to do it.  If you take the time to plan ahead and solve the problem before you start coding it will help you become one of the best coders.  Obviously you won't be able to foresee every problem so you will have to make the little things work and that can get pretty messy so what you are doing is called refactoring the code (and this is a good practice).  The best thing to do is first solve the algorithm on paper and figure out how you are going to accomplish the task.  Then code it and get it to work, then refactor to clean up, make more readable and optimize.  Look at how long it is taking you to solve/code/debug and of those three the debugging should take the least time, then coding a little more and solving the problem the most time.  Hope that helps out. </p>

Title: Coding style (do more, then simplify)


问:
What are the worst false economies in software development?
What are the worst false economies (that is ways of saving money that ultimately cost more than they save) prevalent in the software industry and how do you combat them?</p>

答:
Using "simple" languages without much expressiveness

Yeah, it makes it easier to find programmers to maintain the code, but it makes it harder to find good programmers who don't just learn the latest buzzword that will get them hired.  Yeah, it makes individual bits code easier to understand, but it also makes it about as rigid as a 2x4 and increases the volume of code that needs to be understood.  Yeah, it's backed by a huge corporation, but said huge corporation innovates slowly and bureaucratically.

ContentLicense: CC BY-SA 2.5


问:
Does JMF have support with Xuggler
i am working on a project consisting of sending and receiving streaming multimedia.So,i have installed JMF, but i have seen that JMF has 32 bit library as mine is 64 bit so i wanted to use Xuggler for streaming videos.

Can anyone clarify me about the support of Java Media FrameWork with Xuggler..

答:
Xuggler and JMF are two independent libraries. I dont think JMF 'supports' xuggler

I would advise not to use JMF as it is not under active development, the last release was in 2004! fobs4jmf, QTJ and xuggler would be better options.

Title: Does JMF have support with Xuggler


答:
Verbosity is very common for junior programmer, but you are more advanced that you aware those verbosity and try to remove it.

At first it might sounds like a good habit that you always refactor, but if you need a lot of refactoring after first time it means you should improve your initial coding performance.

Refactoring more often is the key. Don't wait until your implementation complete before refactoring. If you function is too long, make new function. If your code is repetitive, make a function out of it. Think of refactoring all the time when you code, not just after you finished coding.

Constantly refactoring will help you when you need to review what you have written, and it's easier to debug. It is common that your code won't work correctly after the first time, and even yourself in few days later might forgot your own logic if your code look like a mess.

Title: Coding style (do more, then simplify)

Body:
I'm a CS student and I have been coding for a few months shy of a year now, and I seem to have developed what I think may be a "bad" habit and I'm wondering if anyone does the same (or whether it's a bad habit at all). When I'm coding / solving a problem with code, I find that my initial implementation is lengthy and overly-complicated; in other words, there is a lot of extraneous code (variables, checks) that is simply not needed. When I finish the initial "draft," and make sure the code actually works, I simplify it and make it easier to understand/less verbose.

I think the reason I do this is that I have trouble foreseeing what I will need to complete a task and end up over-compensating and creating complexities that should not or need not exist. Anyone have any tips or advice on how to improve this facet of my coding style, or any input as to whether the habit is actually a bad one?


问:
What's the meaning of term context in programming
I was looking through some Objective C docs.. and got this :

UIGraphicsBeginImageContext : Creates a bitmap-based graphics context
  and makes it the current context.

Also, the same term is used in Robotlegs :

(http://www.adobe.com/devnet/actionscript/articles/intro-robotlegs-pt1.html)
  Context: Context is the bootstrapping mechanism that initializes
  dependency injection and the various core utilities that Robotlegs
  uses.

Dictionary meaning of context as i googled, doesnot seem to match the way it's used in programming :

con·text   /ˈkäntekst/ Noun
      The circumstances that form the setting for an event, statement, or idea, and in terms of which it can be fully understood and
  assessed.

The parts of something written or spoken that immediately precede and follow a word or passage and clarify its meaning.

Anybody can throw some light pls!

V.

答:
The circumstances that form the setting for an event, statement, or idea, and in terms of which it can be fully understood and assessed.

That's really not too far from the programming sense of the word. Context generally has to do with some kind of state that's necessary to perform an operation.

A graphics context is typically an object or structure that contains all the information needed to draw in a particular place. Graphics contexts are often maintained in a stack, and any drawing operations happen using the information in the context at the top of the stack. A graphics context could contain information like the buffer in which to draw, current pen size, drawing color, background color, transformation matrix, pen location, and so on.

Similarly, you could have a database context, a file context, an audio context... none of these things are specifically defined outside the scope of a given API, but they all mean the same thing -- the set of conditions needed to properly carry out operations in the system in question.


问:
What kind of algorithm could be used to produce an ordering which maximizes # of satisfied 'less than' constraints?
Let's say I have a set of items {e1, e2, ..., en}, and I also have a set of constraints {c1, c2, ..., cm}, with ci := ej appears before ek, for some j and k.

I want to produce an ordering of my items which maximizes the number of satisfied constraints, with the possibility that some of the constraints are contradictory. I'm not sure how to search for this, but I hope there is some known efficient algorithm for this.

It might also be helpful if, given weights for the constraints, I could instead maximize the total weight of the satisfied constraints, rather than just the number.

答:
I am uncertain as to whether you have any additional information that could allow you to optimize the problem. In general, I agree with World Engineer, that it is NP-complete if presented in this general case.

In general, what you can do if you truly have the NP-complete version of the problem to solve is encode it into any other NP-complete problem, with which you are more familiar with / have better solvers available for. Below is an example of how to do this. In general, if you want to solve larger instances of this problem as fast as possible it might be worthwhile to encode them into SAT problems, as there are blazing fast solvers available for these.

Example encoding as feedback arc set problem

Consider your elements as a graph and the set of lower-than-constraints as edges, hence, you have an edge between two nodes iff there exists a constraint c_i stating that the source node needs to be less than the target node (or vice versa, as long as it is consistent).

You can then search this graph for cycles. A cycle in the graph corresponds to a set of constraints that are inconsistent (smallest possible cycle would be A <-> B, meaning A < B and B < A). The problem can then be reformulated as follows: remove the minimal number of edges required to make the graph acyclic. What you need to find therefore is the minimal feedback arc set (which of course is NP-complete again).

(I will leave it as an exercise to the reader to prove that this is indeed a polynomial-time reduction.)


答:
To add a bit more information to the comment I left on World Engineer's answer:

This is generally referred to as multi-objective optimisation.  Wikipedia has a pretty good summary of the topic, I recommend you go through it.  The good news is that it's a very well researched area, with plenty of ideas and algorithms available.  The bad news is that it is a difficult area of optimisation, except in the most basic cases (which can often be solved with basic maths, e.g. with Linear Programming).

If your set of constraints is pretty fixed (or generally follows some simple pattern), I'd recommend attempting to solve the problem in a mathematical fashion.  These solutions are almost always more efficient than the alternatives, which would be some kind of exhaustive search, or if the search space is too big, a randomised search with some kind of heuristic / intelligence built into it.

A word on weighting: there typically exist a whole number of solutions which are "pareto optimal", which means that you can no longer improve any of the objectives without causing impairment to the others (this is akin to "local minimum / minima" in standard optimisation).  Together, these pareto-optimal solutions form the pareto front, which often forms a visually continuous shape.  Mathematically, these solutions are considered equivalent, and it is up to you to provide extra information in order to choose between them, i.e. which trade-offs you consider more important.  Sometimes, these decisions are left up to the user, and the role of the software is to provide them with the various pareto-optimal solutions (e.g. an investment professional choosing risk profile for a portfolio).  This could be an option to consider in your case, too.

Title: What kind of algorithm could be used to produce an ordering which maximizes # of satisfied 'less than' constraints?

Body:
Let's say I have a set of items {e1, e2, ..., en}, and I also have a set of constraints {c1, c2, ..., cm}, with ci := ej appears before ek, for some j and k.

I want to produce an ordering of my items which maximizes the number of satisfied constraints, with the possibility that some of the constraints are contradictory. I'm not sure how to search for this, but I hope there is some known efficient algorithm for this.

It might also be helpful if, given weights for the constraints, I could instead maximize the total weight of the satisfied constraints, rather than just the number.


答:
Nothing wrong with this habbit in my opinion. The longer you code, the better your coding and problem solving skills will get, thus all of the "extra" code will get less.

I've been working as a junior software engineer for about two years now, and still use this sort of approach, with the difference being that as time has gone by, I've been more often gunning straight to the trimmed down solution/algorithm.

Test variables is still a common thing for me, but gets used much more efficiently.

So no real worries here, just ensure that you keep it as clean as possible, and use lots of comments and regions.

Title: Coding style (do more, then simplify)


答:
Writing and re-writing code isn't a problem, nor is writing more code than is absolutely necessary.  Every time you write code and throw it away or refactor it you are learning--in fact it's possibly the best way to learn.  Trying to be "Optimal" about your coding type or typing time is really harmful to all involved.

Also, all those "Extra" variables are often a good idea--if they help you understand your code initially then they are best left in there!  Don't fall into the trap of writing minimal code thinking that's the way to make it readable, Terse code does not equate to readable.

I'm suggesting you don't get too enthusiastic about "Removing" your code.  If it's absolutely unnecessary, sure, but creating extra functions and more variables tends to be a fairly good thing, if you remove them once you understand the solution, you are only hurting everyone who looks at the code after you (including yourself a few months later).

It IS, however, important to keep your code DRY, in fact that's what I consider the single most important principle in all of software development, but once your code is DRY, further reducing verbosity from what helped you comprehend and design it is usually harmful.

Title: Coding style (do more, then simplify)


问:
Architecting Python application consisting of many small scripts
I am building an application which, at the moment, consists of many small Python scripts.

Each Python script processes items from one Amazon SQS queue. Emails come into an initial queue and are processed by a script, and typically the script will do a small unit of processing (for example, parse email and store some database fields), then an item will be placed on the next queue for further processing, until eventually the email has finished going through the various scripts and queues.

What I like about this approach is that it is very loosely coupled.

However, I'm not sure how I should implement live.  Should I make each script a daemon which is constantly polling its inbound queue for things to do? Or should there be some overarching orchestration program or process? Or maybe I should not have lots of small Python scripts but one large application?

Specific questions:
How should I run each of these scripts - as a daemon with some sort or restart monitor to restart them in case they stop for any reason? If yes, should I have some program which orchestrates this?

Or is the idea of many small script not a good one, would it make more sense to have a larger python program which contains all the functionality and does all the queue polling and execution of functionality for each queue?
What is the current preferred approach to daemonising Python scripts?

Broadly I would welcome any comments or opinions on any aspect of this.

thanks

答:
An alternative to queue processing is to utilise a noSQL schema with a status field - eg. 0-New, 1-pending, 2-processed OK, 3-Processed error and custom fields for whatever processing tasks you need.

Within your schema you could put processing results or useful error data. The important benefit of this approach is transparency. At any moment you can query the pipeline status.

It is important with this approach to use an atomic update (in Mongo findAndUpdate) - so that no two processes will retrieve the same task.


问:
How to port cli c++ program with GNU libraries from windows to Linux
I need to implement some graph partitioning algorithms for my thesis. I have mostly Windows experience. I would like to know if it is hard to migrate c++ console program to Linux. I want to program it on Windows but I want to test and compile it on Linux as well. It will be pure cli application, with no use of windows APi or anything. I just need to use some external libraries. Specifically GNU linear programming kit and GNU scientific library GSL.
I found out, there are windows versions of these libraries, what does it mean for me?, should I compile it on Windows with windows version package and on Linux with linux package. I would like someone to bring a bit clarity to this, I am really not very experienced programmer, so any advice will help. Also I would like to ask, if there is diference if I use Visual Studio for programming or some other IDE in matter of portability issues. Thanks in advance for any help.</p>

答:
The first thing to remember is that, although C++ source code can be ported between Linux and Windows, the compiled binaries can't be exchanged (at least not without using emulation software).

To create a portable application, your best option is to stay with standard C++ code and portable libraries. For the libraries, you can either build them yourself from source or you can use pre-built versions. In the latter case, you should make sure that you install the same version of the library on each platform to avoid hitting incompatibilities due to the different versions.

To ensure your code stays portable and you don't accidentally start using compiler-specific constructs, I would advise you to regularly compile your code for both Windows and Linux. That way you will get an early warning instead of having a pile of work at the end.


问:
How can we track how well we're preventing and avoiding security vulnerabilities?
It's pretty easy to track when we fix security vulnerabilities in existing code.  But to make sure the whole team is staying on their toes about writing secure code, I'd like to also track how well we are preventing and avoiding writing new security vulnerabilities.  What is the right way to measure that?</p>

答:
You can start by going down the OWASP ASVS checklist to verify that you're covering all your bases when it comes to security efforts. To comply with ASVS's requirements you will need some sort of active auditing of the code to look for security issues.

There are several approaches you can take:

Dedicated code reviews for security (all code is reviewed)

Static analysis via automated tools, custom-made or standard

Dynamic analysis of the running application.

Examples of static analysis tools include HP Fortify, Coverity, IBM AppScan. Be warned that there is a lot of snake oil vending here, because these tools are heavily oversold (both in price and in ability). In code I've worked on we ended up developing our own tool with a bunch of regexes to check the codebase during each build for things like improperly quoted variables inserted into SQL statements, because it was cheaper and more effective. Tools that are more general-purpose, like Sonar, can be repurposed to the task, so consider those as well.

There are also dynamic analysis tool which scan a running application, like Zed Attack Proxy and sqlmap. These tools are what an actual hacker would use to scan your application for vulnerabilities, so it can pay off to use them to check your own work.


问:
Design for using your own API
So I'm planning to use APIs for my host app. But the APIs are built such that it requires a sessionkey for every request.

So my question is, how would I dogfood my API? Cause, apparently I'm thinking in the line of creating a "special" key for my host app (cause it makes no sense to request for a key for my own use), but, anyone inspecting the headers of the request could find this key and literally use it and bypass requesting their own keys.

Maybe there's a best practice for dogfooding our own API without a special key or someway to differentiate whether the request is coming from the host app or the public.

I couldn't use IP to differentiate too, cause the public could be using the same server to call the APIs. That's just the way it is, and is a one of the constraints to keep in mind.

答:
There shouldn't be any special key on a live API server as you also mentioned that the header may be parsed and key may be found. What we did in a similar situation was creating a sandbox or a separate environment (separate URL only known to the development team) and then changing the code to accept a special key.

I think the point in the question is to skip authentication. To avoid sniffing secure communication is the solution i.e. communicating over HTTPS

Title: Design for using your own API


答:
You're trying to test a negative - that is, you're testing for something being absent. The problem with this is that it's like testing for the absence of the Loch Ness Monster - the loch is deep, you can't check all of it, and you certainly can't check it all at once. You can never be sure whether it's not there, or if you just missed it.

Your best bet is to flip your test and look for positives. Get some vulnerability-scan software and check your application for holes, both by checking the code for bad things like injection-vulnerable unescaped variables, and by scanning the application as it runs to look for vulnerabilities to known exploits. If your budget can stretch far enough, hire some penetration testers - or recruit some to work in-house - and get them to poke around your software to look for a way in. The aim of all this is to turn your negative "looking for something that's not there" into a positive "we found this vulnerability; fix it". If they don't find anything... well, you can never be completely sure, but at least you have a list of things that you've checked, so that when someone inevitably finds a zero-day exploit in something you're using, you can at least show (to your boss, your customer, or whoever else tries to point fingers) that you were diligent and did all that could be expected to make sure the application was secure.

Title: How can we track how well we're preventing and avoiding security vulnerabilities?

Body: It's pretty easy to track when we fix security vulnerabilities in existing code.  But to make sure the whole team is staying on their toes about writing secure code, I'd like to also track how well we are preventing and avoiding writing new security vulnerabilities.  What is the right way to measure that?</p>


问:
How can I test parts of my application against the output of third party application?
I have a fairly new C# application, approximately 6 months old, that we are now trying to incorporate testing into. (Should have been done from the start but I can't change the past)

Parts of this application involve pushing some documents out to a folder. A third party application then picks these up, does its own work on them, and drops output files in another folder.

My application waits for this to be done, picks up the outputs, then continues its work.

This poses a problem when testing as I can't really install another version of the third party just for testing, nor can I mock it without ending up fully rewriting the third party application.

How can I test these parts of my application? (Preferably with NUnit)

Specifically, I'm asking about how to unit test my code against the output of the 3rd party tool. So it's a little bit different than another similar question, which involves isolating how code interfaces with a third party.

答:
Your test should check if you push correct (whatever it means in your scenario) documents to correct folder.
Then check if you do what you supposed to when new documents appear in folder you monitor.</p>


答: You may transfer existing (already processed files in previous runs) output files into the output folder just to simulate the work of the third party API in the unit test code. This will suffice if you are unit testing your own functionality and not the third party functionality.</p>

Title: How can I test parts of my application against the output of third party application?

Body:
I have a fairly new C# application, approximately 6 months old, that we are now trying to incorporate testing into. (Should have been done from the start but I can't change the past)

Parts of this application involve pushing some documents out to a folder. A third party application then picks these up, does its own work on them, and drops output files in another folder.

My application waits for this to be done, picks up the outputs, then continues its work.

This poses a problem when testing as I can't really install another version of the third party just for testing, nor can I mock it without ending up fully rewriting the third party application.

How can I test these parts of my application? (Preferably with NUnit)

Specifically, I'm asking about how to unit test my code against the output of the 3rd party tool. So it's a little bit different than another similar question, which involves isolating how code interfaces with a third party.


问:
How to prepare yourself for programming interview questions?

Possible Duplicate:

  Really “wow” them in the interview

Let's say I appear for an interview. What questions could I expect and how do I prepare?

答:
Programming Interviews Exposed is also helpful.

This classic book uncovers what
  interviews are really like at
  America's top software and computer
  companies and provides you with the
  tools to succeed in any situation. The
  authors take you step-by-step through
  new problems and complex brainteasers
  they were asked during recent
  technical interviews.

50 interview scenarios are presented
  along with in-depth analysis of the
  possible solutions. The
  problem-solving process is clearly
  illustrated so you'll be able to
  easily apply what you've learned
  during crunch time. You'll also find
  expert tips on what questions to ask,
  how to approach a problem, and how to
  recover if you become stuck.

I've used it in preparing for my last round of interviews and while I didn't end up needing it, reading through it certainly made me feel more confident and prepared. The book also has a section on non-programming questions such as salary negotiation, which I found very helpful.


问:
Clarify the Open/Closed Principle
As I have had it explained, the open/closed principle states that once written code should not be modified (aside from bug fixes). But if my business rules change shouldn't I modify the code implementing those changes? I suspect I'm not understanding something about how the principle because it doesn't make sense to me.</p>

答:
This is probably the hardest of the solid principles to explain. Let me try. Imagine you wrote an Invoice class that works perfectly and has no bugs. It makes a PDF of an invoice.

Then someone says they want an HTML invoice with links in it. You don't change any code in Invoice to satisfy this request. Instead, you make another class, HTMLInvoice, that does what they now want. You leverage inheritance so that you don't have to write a lot of duplicate code in HTMLInvoice.

Old code that was using the old Invoice isn't broken or really affected in any way. The new code can use HTMLInvoice. (If you also do Liskov Substitutability, the L of solid, you can give HTMLInvoice instances to existing code that's expecting Invoice instances.) Everyone lives happily ever after.

Invoice is closed to modification, open to extension. And you have to write Invoice properly in advance for this to work, btw.

Title: Clarify the Open/Closed Principle


问:
Are Java applets worth learning?
I'm on the way of learning Java myself. I find most of texts giving emphasis to Java applets. I got confused about the importance. Is it something widely used?  Do I need to spend more time on it?</p>

答:
As one of the most experienced applet developers1 willing to
help on public forums (e.g. the Oracle forums or Stack Overflow), it saddens
me to see new students 'tossed in at the deep end' to learn how to make an
applet.

The reasons are multiple, but first, I'll look a little at the history of applets
and why applets were ever considered a good idea for teaching small, simple projects.

Applet vs. Frame

The simplest applet is:

import java.applet.Applet;
import java.awt.Label;

public class HelloWorldApplet extends Applet {

    @Override
    public void init() {
        add(new Label("Hello World!"));
    }
}
```

<p>Looks simple, right?</p>

<p>But an applet gets a size & position on screen from the HTML that
loads it.  So an applet also requires a little HTML E.G.</p>

<pre class="lang-html prettyprint-override"><code><html>
<body>
<applet
  code=HelloWorldApplet
  width=400
  height=200>
</applet>
</body>
</html>
</code>```

This makes the total for a working applet 17 LOC.  Not looking quite
so simple now.  Worse, many developers think 'any old mark-up will do'
when that is very much not the case.  Missing opening or closing
elements make the HTML invalid and how a browser will interpret it
is anyone's guess.

Compare that to an application that behaves in as smooth a manner:

import java.awt.Label;
import java.awt.Frame;

public class HelloWorldApplication  {

    public static void main(String[] args) {
        Frame f = new Frame();
        f.add(new Label("Hello World!"));
        f.pack();
        f.setVisible(true);
    }
}
```

<p>So, while it takes just 9 lines of code for the simplest of
applets (even including the <code>@Override</code> notation), while 12 LOC for
the application doing the same thing, add the HTML and it becomes
17 lines for applet/HTML vs. just 12 LOC for the application.</p>

<h2>AWT vs Swing</h2>

<p>Time moves on, and the Swing component toolkit was introduced as
a replacement for AWT.  Nobody uses AWT anymore.  Most Java GUI
developers started using Swing, and those that have used AWT have
largely forgotten the fine details.</p>

<p>This is relevant to the student in terms of getting help when they
get stuck.  It does not matter who we are, when approaching new areas
of CS, we all tend to reach for whatever resources might help us
understand the new technique.  For a student the best resources are
firstly the text books and class notes, but those typically only
go so far at explaining, and the rest is from things like the
JavaDocs, the Java Tutorial, searching the net, or asking for
clarification on forums.</p>

<p>Those last two are particularly relevant in that:</p>

<ul>
<li>There is a slew of extremely poor AWT based code available on the net.</li>
<li>There may also be some poor Swing based code out there, but usually there
is a Swing programmer nearby that can point out the deficiencies in it.</li>
</ul>

<p>Industry uses Swing and that is all that Swing programmers know and
remember.  AWT is obsolete, and a dead end in career or learning.</p>

<p>So let's now look at the proper way to write a Swing applet & application.
The Java Tutorial warns us that all Swing code should be started and
updated on the Event Dispatch Thread, which (ironically) is an AWT based Thread.</p>

<p>A simple Swing applet might then be: </p>

<pre class="lang-java prettyprint-override"><code>import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import java.lang.reflect.InvocationTargetException;

public class HelloWorldApplet extends JApplet {

    @Override
    public void init() {

        @Override
        Runnable r = new Runnable() {
            public void run() {
                add(new JLabel("Hello World!"));
            }
        };
        try {
            SwingUtilities.invokeAndWait(r);
        } catch(InterruptedException ie) {
            ie.printStackTrace();
        } catch (InvocationTargetException ite) {
            ite.printStackTrace();
        }
    }
}
</code>```

This is slightly verbose (25 LOC) for strict clarity, but could be reduced to:

import javax.swing.*;

public class HelloWorldApplet extends JApplet {

    @Override
    public void init() {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                add(new JLabel("Hello World!"));
            }
        };
        try {
            SwingUtilities.invokeAndWait(r);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}
```

<p>It could be further shortened (from 20 LOC) by declaring the <code>Runnable</code> inside the
<code>SwingUtilities</code> method call, but I find that notation to be confusing &
prefer to separate the <code>Runnable</code> into a clearly defined instance.</p>

<p>And now the Swing equivalent application, using the same 'short guidelines'.</p>

<pre class="lang-java prettyprint-override"><code>import javax.swing.*;

public class HelloWorldApplication {

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame();
                f.add(new JLabel("Hello World!"));
                f.pack();
                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
</code>```

Just 18 LOC in total.

Not very much coding to see our simple message on screen, in a
free floating Swing component.

Embedded vs. not embedded

Security

Why won't the applet load my input file?

By default, Java applets run in a security sand-box that prohibits many
actions which might be damaging to other applets, the browser or the user's
machine.

While the security sand-box is of great benefit to end-users, it makes
the life of the developer difficult.  And it has just become that much
more difficult in Java 7 update 21.

In Java 7 Update 21 Security Improvements in Detail
Markus Eisele notes:

With the introduced changes it is most likely that no end-user is able to run your application when they are either self-signed or unsigned.

While that warning is a little extreme, I agree with the underlying
point being made.  A user (or in this case you, the teacher) will need
to OK some very scary dialogs, and posibly lower the default Java
security to an unsafe level, before being able to view an applet.

Error reporting

My applet is broken but shows no errors!  Where are they?

The System.err stream used for displaying stack traces appears on the
command line (or in the IDE) when running an application.  When a stack
trace occurs in an applet it is sent to the Java Console, which is (by
default) not configured to be shown.

Class caching

I changed my applet but the browser shows the same!

Many times I have responded to applet problems where the questioner
swears they have changed the code & recompiled it, yet the browser is
still showing the old values.  The solution is relatively simple when
you know how - flush the class cache from the Java Console.  To someone
learning, it is typically a complete mystery.

Embedded conclusion

Those 3 problems alone have probably earned me a quarter of the
reputation points I've so far earned on this site.  They pose
huge problems when developing and debugging applets.

But more on Java applets as a web app. component - other cons:

Either steal the keyboard focus or do not ever get focus by tabbing around the web page.

Need a JRE (and are not compatible with some tablets and all phones)

Are not indexed by search engines!

At one stage, there was an applet/JRE/browser interaction bug for every fortnight that Java had existed. That is in addition to anything related to security or more generally to JWS apps.

A Frame gets the right size using pack() but an applet has a size forced upon it by the HTML width & height specified in the applet element.

..

Conclusion

The question really comes down to:

Are you teaching Java/CS or how to deploy applets?

If the former, use JFrame based applications and side-step all the
problems that are inherent to an embedded app.  And don't even consider
teaching AWT components - they are obsolete & Swing takes only a few
more LOC to get something on-screen.

Author Credentials

So who am I?

Top ranked provider of answers on Stack Overflow for the applet tag.

The developer of Appleteer.

Host of many applets on my site.

See also the blog post.

Title: Are Java applets worth learning?

Body:
As one of the most experienced applet developers1 willing to
help on public forums (e.g. the Oracle forums or Stack Overflow), it saddens
me to see new students 'tossed in at the deep end' to learn how to make an
applet.

The reasons are multiple, but first, I'll look a little at the history of applets
and why applets were ever considered a good idea for teaching small, simple projects.

Applet vs. Frame

The simplest applet is:

import java.applet.Applet;
import java.awt.Label;

public class HelloWorldApplet extends Applet {

    @Override
    public void init() {
        add(new Label("Hello World!"));
    }
}

Looks simple, right?

But an applet gets a size & position on screen from the HTML that
loads it.  So an applet also requires a little HTML E.G.

<html>
<body>
<applet
  code=HelloWorldApplet
  width=400
  height=200>
</applet>
</body>
</html>

This makes the total for a working applet 17 LOC.  Not looking quite
so simple now.  Worse, many developers think 'any old mark-up will do'
when that is very much not the case.  Missing opening or closing
elements make the HTML invalid and how a browser will interpret it
is anyone's guess.

Compare that to an application that behaves in as smooth a manner:

import java.awt.Label;
import java.awt.Frame;

public class HelloWorldApplication  {

    public static void main(String[] args) {
        Frame f = new Frame();
        f.add(new Label("Hello World!"));
        f.pack();
        f.setVisible(true);
    }
}

So, while it takes just 9 lines of code for the simplest of
applets (even including the @Override notation), while 12 LOC for
the application doing the same thing, add the HTML and it becomes
17 lines for applet/HTML vs. just 12 LOC for the application.

AWT vs Swing

Time moves on, and the Swing component toolkit was introduced as
a replacement for AWT.  Nobody uses AWT anymore.  Most Java GUI
developers started using Swing, and those that have used AWT have
largely forgotten the fine details.

This is relevant to the student in terms of getting help when they
get stuck.  It does not matter who we are, when approaching new areas
of CS, we all tend to reach for whatever resources might help us
understand the new technique.  For a student the best resources are
firstly the text books and class notes, but those typically only
go so far at explaining, and the rest is from things like the
JavaDocs, the Java Tutorial, searching the net, or asking for
clarification on forums.

Those last two are particularly relevant in that:

There is a slew of extremely poor AWT based code available on the net.

There may also be some poor Swing based code out there, but usually there
is a Swing programmer nearby that can point out the deficiencies in it.

Industry uses Swing and that is all that Swing programmers know and
remember.  AWT is obsolete, and a dead end in career or learning.

So let's now look at the proper way to write a Swing applet & application.
The Java Tutorial warns us that all Swing code should be started and
updated on the Event Dispatch Thread, which (ironically) is an AWT based Thread.

A simple Swing applet might then be:

import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import java.lang.reflect.InvocationTargetException;

public class HelloWorldApplet extends JApplet {

    @Override
    public void init() {

        @Override
        Runnable r = new Runnable() {
            public void run() {
                add(new JLabel("Hello World!"));
            }
        };
        try {
            SwingUtilities.invokeAndWait(r);
        } catch(InterruptedException ie) {
            ie.printStackTrace();
        } catch (InvocationTargetException ite) {
            ite.printStackTrace();
        }
    }
}

This is slightly verbose (25 LOC) for strict clarity, but could be reduced to:

import javax.swing.*;

public class HelloWorldApplet extends JApplet {

    @Override
    public void init() {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                add(new JLabel("Hello World!"));
            }
        };
        try {
            SwingUtilities.invokeAndWait(r);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

It could be further shortened (from 20 LOC) by declaring the Runnable inside the
SwingUtilities method call, but I find that notation to be confusing &
prefer to separate the Runnable into a clearly defined instance.

And now the Swing equivalent application, using the same 'short guidelines'.

import javax.swing.*;

public class HelloWorldApplication {

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame();
                f.add(new JLabel("Hello World!"));
                f.pack();
                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

Just 18 LOC in total.

Not very much coding to see our simple message on screen, in a
free floating Swing component.

Embedded vs. not embedded

Security

Why won't the applet load my input file?

By default, Java applets run in a security sand-box that prohibits many
actions which might be damaging to other applets, the browser or the user's
machine.

While the security sand-box is of great benefit to end-users, it makes
the life of the developer difficult.  And it has just become that much
more difficult in Java 7 update 21.

In Java 7 Update 21 Security Improvements in Detail
Markus Eisele notes:

With the introduced changes it is most likely that no end-user is able to run your application when they are either self-signed or unsigned.

While that warning is a little extreme, I agree with the underlying
point being made.  A user (or in this case you, the teacher) will need
to OK some very scary dialogs, and posibly lower the default Java
security to an unsafe level, before being able to view an applet.

Error reporting

My applet is broken but shows no errors!  Where are they?

The System.err stream used for displaying stack traces appears on the
command line (or in the IDE) when running an application.  When a stack
trace occurs in an applet it is sent to the Java Console, which is (by
default) not configured to be shown.

Class caching

I changed my applet but the browser shows the same!

Many times I have responded to applet problems where the questioner
swears they have changed the code & recompiled it, yet the browser is
still showing the old values.  The solution is relatively simple when
you know how - flush the class cache from the Java Console.  To someone
learning, it is typically a complete mystery.

Embedded conclusion

Those 3 problems alone have probably earned me a quarter of the
reputation points I've so far earned on this site.  They pose
huge problems when developing and debugging applets.

But more on Java applets as a web app. component - other cons:

Either steal the keyboard focus or do not ever get focus by tabbing around the web page.

Need a JRE (and are not compatible with some tablets and all phones)

Are not indexed by search engines!

At one stage, there was an applet/JRE/browser interaction bug for every fortnight that Java had existed. That is in addition to anything related to security or more generally to JWS apps.

A Frame gets the right size using pack() but an applet has a size forced upon it by the HTML width & height specified in the applet element.

..

Conclusion

The question really comes down to:

Are you teaching Java/CS or how to deploy applets?

If the former, use JFrame based applications and side-step all the
problems that are inherent to an embedded app.  And don't even consider
teaching AWT components - they are obsolete & Swing takes only a few
more LOC to get something on-screen.

Author Credentials

So who am I?

Top ranked provider of answers on Stack Overflow for the applet tag.

The developer of Appleteer.

Host of many applets on my site.

See also the blog post.


答: You're about to learn an important lesson about APIs.  Any time you find yourself saying "I need something special that shouldn't be available to others", you're wrong.  That's especially true when it comes to identification and authentication.

Title: Design for using your own API

Body:
So I'm planning to use APIs for my host app. But the APIs are built such that it requires a sessionkey for every request.

So my question is, how would I dogfood my API? Cause, apparently I'm thinking in the line of creating a "special" key for my host app (cause it makes no sense to request for a key for my own use), but, anyone inspecting the headers of the request could find this key and literally use it and bypass requesting their own keys.

Maybe there's a best practice for dogfooding our own API without a special key or someway to differentiate whether the request is coming from the host app or the public.

I couldn't use IP to differentiate too, cause the public could be using the same server to call the APIs. That's just the way it is, and is a one of the constraints to keep in mind.


问:
How did they debug segmentation faults before protected memory?
Now, when I make a programming mistake with pointers in C, I get a nice segmentation fault, my program crashes and the debugger can even tell me where it went wrong.

How did they do that in the time when memory protection wasn't available? I can see a DOS programmer fiddling away and crashing the entire OS when he made a mistake. Virtualization wasn't available, so all he could do was restart and retry. Did it really go like that?

答:
Back in my day, we didn't have memory protection and all that snazzy business!  We used printf to determine where we were in the program, and we liked it!

Though in all seriousness, it usually meant we were just more careful.  Where malloc is called, there had to be a free somewhere else in the program, and such checking was rigorous because in the case of a problem, as you've clearly pointed out, segmentation faults are not helpful errors.

In the case of such errors, the best you could do is try to understand when such segmentation faults occur (using printf) and, looking at the code, determine why access to memory at that point was not valid and work backwards from there.

In essence, the same thing happens today, except we use debuggers to determine when errors occur, but you still have to understand why it happened, and it isn't always as simple as finding the line in which the error occurred.  Errors cause errors like a chain reaction, and if you were a C programmer in those days, you spent 20% of your time coding and the rest of the time pulling your hair out fixing bugs.


答:
well ..

a segfault is a really nice indicator that something is wrong but you still have to find the root cause. So if you ask the question how do you find the root cause than the answer is not much different today than it was then. Of course the languages and tools became easier to work with but the general taktik is the same:

logging helps to find the area where your problem is. Binary search printf is a form of it.

debugging, step by step, break points and watches

refactoring to get a better understanding

staring hard at the code

look at the memory / core dump

feeding it with different data

showing it to other people

switch to a language without pointers (and a new set of problems)
...

On a more abstract level you have three approaches:
1. work with the code
2. look at the program while it runs
3. look the results after it did something stupid

btw a pointer error does not have to create a segfault.

As a Amiga programmer I used pretty much all of it.
And yes restarts where common practise.

Title: How did they debug segmentation faults before protected memory?

Body:
Now, when I make a programming mistake with pointers in C, I get a nice segmentation fault, my program crashes and the debugger can even tell me where it went wrong.

How did they do that in the time when memory protection wasn't available? I can see a DOS programmer fiddling away and crashing the entire OS when he made a mistake. Virtualization wasn't available, so all he could do was restart and retry. Did it really go like that?


答:
I can see a DOS programmer fiddling away and crashing the entire OS when he made a mistake.

Yeah, that's pretty much what happened.  On most systems that had memory maps, location 0 was marked invalid, so that null pointers could be easily detected, because that was the most common case.  But there were lots of other cases, and they caused havoc.

At the risk of sounding like a geezer, I should point out that the current focus on debugging is not the way of the past.  Much more effort was previously made to write correct programs, rather than to remove bugs from incorrect programs.  Some of that was because that was our goal, but a lot was because the tools made things hard.  Try writing your programs on paper or on punched cards, not in an IDE, and without the benefit of an interactive debugger.  It gives you a taste for correctness.


答:
Welcome to the world of integration testing.

The best way of approaching this is automated tools that can exercise your 3rd party app directly (if possible) or via a thin wrapper. You write a test rig to send various data in to the component, and inspect what comes out, preferably with some automated checking - eg run a regex on the file contents and see if it matches what you expect. In this regard its a lot like unit testing, except you need different tooling to check the results.

For the parts of your application that run the 3rd party component, you will still need to check that it works correctly. You might not be able to use the same unit test frameworks as you'll need to check the reading of the data correctly, and for that you'll need a file to read. I guess you could write a standard file in your unit test routines, but that seems like a lot of work for little results. Personally, I would keep a set of sample files and copy them in to the right place one at a time as you run tests. (mind you, I'd also run these as part of an external tool, rather than an "internal" unit test framework)

You can obviously unit test the rest of your program by wrapping the calls to the 3rd party in your own interface and mocking that at the cost of an additional layer of abstraction in your code.


答:
Note that you can cross compile using GCC, with the right flags and compiler options, and an install of mingw, you can compile Windows binaries on Linux (obviously you won;t be able to run them on Linux unless you install wine)

For a command line app, you should be ok - it depends how many Windows-specific system calls you make that will have to be replaced with Linux equivalents, though there are a few cross-platform libraries that might support these calls.

For cross platform development If you are looking for a cross platform IDE, you'll need to dump visual studio for one of the other ones. For C++, there's Qt Creator or Code::blocks both of which work well on Windows as well as Linux.

Title: How to port cli c++ program with GNU libraries from windows to Linux

Body:
I need to implement some graph partitioning algorithms for my thesis. I have mostly Windows experience. I would like to know if it is hard to migrate c++ console program to Linux. I want to program it on Windows but I want to test and compile it on Linux as well. It will be pure cli application, with no use of windows APi or anything. I just need to use some external libraries. Specifically GNU linear programming kit and GNU scientific library GSL.
I found out, there are windows versions of these libraries, what does it mean for me?, should I compile it on Windows with windows version package and on Linux with linux package. I would like someone to bring a bit clarity to this, I am really not very experienced programmer, so any advice will help. Also I would like to ask, if there is diference if I use Visual Studio for programming or some other IDE in matter of portability issues. Thanks in advance for any help.</p>


答:
Months of work save days of planning

(Not investing enough time into planning)

Title: What are the worst false economies in software development?

Body: What are the worst false economies (that is ways of saving money that ultimately cost more than they save) prevalent in the software industry and how do you combat them?</p>


问:
Shift bytes through a fixed sized buffer
I'm writing an InputStream that processes data streams containing "trailer" data. That is, the final n bytes of the stream is a piece of data that must be handled separately and shouldn't be returned from the read  methods.

My class will maintain an internal byte array of length n and read data into this byte array from the underlying stream. Data will then be popped from the front of the buffer to service the requests to read.

Implementing the int read() method is simple enough - I just call the same method on the underlying stream, shift my byte array by 1 and pop the result to the caller.

Implementing int read(byte[] b) is more challenging as it requires shifting a large number of bytes through my n-byte buffer, whilst popping and collating the bytes from the front. Essentially a "sliding window" buffer, always containing the last n bytes from my underlying stream.

I get the feeling I'm re-inventing the wheel if I start coding this from scratch. Can anyone suggest if I've overlooked an existing InputStream or Queue implementation that would be well suited to this task?

答: Don't shift your buffer, it is not a linked queue. Use an integer as an index, which you increment as you read data out. When the index is equal to the length of the byte array, you read more data.</p>


问:
Why is Zend Framework so complicated?
I am web developer and have experience of developing several web applications in PHP. I have an idea of developing a product for myself and decided to use a MVC based framework because I really like the idea of MVC and how one can easily manage and modify the application without any difficulty.

I chose Zend Framework and it seems more difficult than learning a new programming language. There are so many things going at one time even to run a small application.

Similarly the idea of routing is very complex as it is new for a core programmer. I know that the guys here read thousand of such questions like one I am asking but I am not looking to learn Zend Framework overnight. I am willing to give as much time as it needs but until now it's making no sense to me. There are thousand of classes in the Zend library, but how would a noob know where to use a specfic class and how to use it? I am still finding it very difficult to understand the bootstrap of Zend Framework and its mapping. I read the manual, follow it and things start working but I really don't exactly how they are actually happening.

I also still have no clue how models, views and controllers work together and how to plan an application in Zend Framework. When it comes to core php I exactly have the idea in my mind what to do and than easily translate them in code but in Zend Framework I don't know how to translate my idea.

答:
I believe zend is just to make things complicated, MVC is just a fraud logically its working like plain PHP.
but you are developing it in front of MVC, like separating files in different directories.

Remember that who is saying that Zend is very secure and and unable to hack, is a big fool.
Zend can also able to hack easily if you didn't use Mysql injection protections.
I whould like to suggest you define your own functions,
then separate your files in different directories to make it similar like MVC
save your functions, classes, and other core material in one directory called controller
then add your web pages in different directory where you need to include all those function files this directory will know as view.
place your javascript and css files in different directories which will known as model.

Remember that, in this world many of people always work hard to make thing more complicated, because they are themself complicated to understand.

PHP is the language which you have learn in book and from teachers.
Zend is nothing just a framework, to make things complicated for your clients. so whenever there client need any modification they will run back to the real developers and those developers will charge you more money.
Zend is protected its all just lie, a single mistake like plain php coding can cause the website hackable.

Title: Why is Zend Framework so complicated?


答:
Use a ring buffer of size n. I don't suppose there is a ready-made implementation, but it isn't that complicated to do yourself. As you intend to retain n bytes at all times, after initialization you don't need to worry about the buffer being partially filled (so you probably only need one read/write pointer, rather than one read pointer and one write pointer). Reading k bytes is simple:

Copy the k bytes following the r/w pointer to the output buffer (special case k = 1 for read()).

Read k bytes from the underlying stream and adjust the r/w pointer.

When the underlying stream runs out, you'll have a n-element array with the last n bytes starting from the r/w pointer. This is extremely fast too - no need to shift whole arrays around. One downside is that processing the trailer is not as trivial as if it was an array (but still simple).

Title: Shift bytes through a fixed sized buffer

Body:
I'm writing an InputStream that processes data streams containing "trailer" data. That is, the final n bytes of the stream is a piece of data that must be handled separately and shouldn't be returned from the read  methods.

My class will maintain an internal byte array of length n and read data into this byte array from the underlying stream. Data will then be popped from the front of the buffer to service the requests to read.

Implementing the int read() method is simple enough - I just call the same method on the underlying stream, shift my byte array by 1 and pop the result to the caller.

Implementing int read(byte[] b) is more challenging as it requires shifting a large number of bytes through my n-byte buffer, whilst popping and collating the bytes from the front. Essentially a "sliding window" buffer, always containing the last n bytes from my underlying stream.

I get the feeling I'm re-inventing the wheel if I start coding this from scratch. Can anyone suggest if I've overlooked an existing InputStream or Queue implementation that would be well suited to this task?


问:
Creating an entity relationship in REST: May I create the parent by posting to a child id?
We are currently designing a REST API to access classical customer data.
One of the elements in the API are the assets of an user. The assets are added under a given service.  The backend API will only add an asset to an user under a given service. So, there's no User--Asset relation, but a  User--[Service]--Asset relationship.

Our URI's will look like this:

```<code>/users/{id}/assets/{id}/services/{id}
</code>```

Uses of the API will know the asset id and the service id to create a new entry.
What we are struggling with is the creation of this relation.

One straightforward way would be to post the whole relation to /users/{id}/assets/

```<code>POST /users/{id}/assets
{asset:${id}, service:{id}, attribute1:"{var}", attribute2:"{var}"}
</code>```

but then we are not actually creating an asset as the URI might indicate, but an asset-service relation.

As an alternative, we are considering POST'ing to the URI addressing the relation, like this:

```<code>POST /users/{id}/assets/{id}/service/{id}
{attribute1:"{var}", attribute2:"{var}"}
</code>```

But in this case, the resource path /users/{id}/assets/{id} will not exist before the POST and will be created as a side-effect.

Is POST'ing to a resource path that does not exist yet allowed at all?

Thanks for your thoughts,

Gerard.

答:
It sounds like you're suggesting that, whenever a user first posts to a non-existent relation, you will create it as part of the post.

If you're asking whether this kind of create-on-access pattern is a valid, acceptable development pattern, the answer is yes it is - it's both valid, and a fairly common pattern to see.


问:
Coding style (do more, then simplify)
I'm a CS student and I have been coding for a few months shy of a year now, and I seem to have developed what I think may be a "bad" habit and I'm wondering if anyone does the same (or whether it's a bad habit at all). When I'm coding / solving a problem with code, I find that my initial implementation is lengthy and overly-complicated; in other words, there is a lot of extraneous code (variables, checks) that is simply not needed. When I finish the initial "draft," and make sure the code actually works, I simplify it and make it easier to understand/less verbose.

I think the reason I do this is that I have trouble foreseeing what I will need to complete a task and end up over-compensating and creating complexities that should not or need not exist. Anyone have any tips or advice on how to improve this facet of my coding style, or any input as to whether the habit is actually a bad one?

答:
I guess having trouble "foreseeing what is needed" is only natural given your short experience: you are just beginning to learn how to write programs. It takes a lot of trial and error to learn to design and that is the skill needed to avoid extraneous coding. It seems you are on the right path.

Perhaps you already write detailed comments but if not, you could try using comments as a tool of small scale design. Try writing descriptions first. Before writing a single line of code into a method, write a description for it: what it does, what parameters it takes and what it returns, what side effects it has and what kind of exceptions it could throw. You could also outline the implementation using comments before writing code. The same goes for classes or modules: try describing them as a whole before actually diving into details and implementation.

This approach forces you to design something before coding. It could also lead you to thinking about structure first which will be essential further down the road.

Title: Coding style (do more, then simplify)


问:
Copyright notices/disclaimers in source files
It's a common practice to place copyright notices, various legal disclaimers and sometimes even full license agreements in each source file of an open-source project. Is this really necessary for a (1) open-source project and (2) closed-source project? What are you trying to achieve or prevent by putting these notices in source files?

I understand it's a legal question and I doubt we can get a fully competent answer here at programmers.SO (it's for programmers, isn't it?) What would also be interesting to hear is, when you put legal stuff in your source files, is it because "everyone does it" or you got legal advice? What was the reasoning?

答:
Is this really necessary

No. It's not legally required. (I am not a lawyer, but I've seen this stated by one.)

If you've got a project where individual files might be taken out of context, it may be sensible - but it only requires a couple of lines, to say something like:

This file is part of <project> which is released under <license>.

  See file <filename> or go to <url> for full license details.

For anything else, you can simply put a LICENSE text file in the project root, and any relevant details/credits/etc in the README file - it's still copyrighted (automatically), so it's just a question of being clear license-wise in the readme file.

ContentLicense: CC BY-SA 4.0


问:
I can write code... but can't design well. Any suggestions?
I feel that I am good at writing code in bits and pieces, but my designs really suck. The question is, how do I improve my designs - and in turn become a better designer?

I think schools and colleges do a good job of teaching people how to become good at mathematical problem solving, but let's admit the fact that most applications created at school are generally around 1000 - 2000 lines long, which means that it is mostly an academic exercise which doesn't reflect the complexity of real world software - on the order of a few hundred thousand to millions of lines of code.

This is where I believe that even projects like topcoder / project euler also won't be of much help, they might sharpen your mathematical problem solving ability - but you might become an academic programmer; someone who is more interested in the nice, clean stuff, who is utterly un-interested in the day to day mundane and hairy stuff that most application programmers deal with.

So my question is how do I improve my design skills? That is, the ability to design small/medium scale applications that will go into a few thousand of lines of code? How can I learn design skills that will help me build a better html editor kit, or some graphics program like gimp?

答: Learn to ask the right questions. More often than not you'll improve your design by looking at the problem from a different angle. In particular this will help you to move away from focusing on solving the problem at hand and look more into solutions that solve multiple related problems.</p>


问:
I should have used a factory method instead of a constructor. Can I change that and still be backwards-compatible?
The problem

Let's say I have a class called DataSource which provides a ReadData method (and maybe others, but let's keep things simple) to read data from an .mdb file:

```<code>var source = new DataSource("myFile.mdb");
var data = source.ReadData();
</code>```

A few years later, I decide that I want to be able to support .xml files in addition to .mdb files as data sources. The implementation for "reading data" is quite different for .xml and .mdb files; thus, if I were to design the system from scratch, I'd define it like this:

```<code>abstract class DataSource {
    abstract Data ReadData();
    static DataSource OpenDataSource(string fileName) {
        // return MdbDataSource or XmlDataSource, as appropriate
    }
}

class MdbDataSource : DataSource {
    override Data ReadData() { /* implementation 1 */ }
}

class XmlDataSource : DataSource {
    override Data ReadData() { /* implementation 2 */ }
}
</code>```

Great, a perfect implementation of the Factory method pattern. Unfortunately, DataSource is located in a library and refactoring the code like this would break all existing calls of

```<code>var source = new DataSource("myFile.mdb");
</code>```

in the various clients using the library. Woe is me, why didn't I use a factory method in the first place?

Solutions

These are the solutions I could come up with:

Make the DataSource constructor return a subtype (MdbDataSource or XmlDataSource). That would solve all my problems. Unfortunately, C# does not support that.

Use different names:

```<code>abstract class DataSourceBase { ... }    // corresponds to DataSource in the example above

class DataSource : DataSourceBase {      // corresponds to MdbDataSource in the example above
    [Obsolete("New code should use DataSourceBase.OpenDataSource instead")]
    DataSource(string fileName) { ... }
    ...
}

class XmlDataSource : DataSourceBase { ... }
</code>```

That's what I ended up using since it keeps the code backwards-compatible (i.e. calls to new DataSource("myFile.mdb") still work). Drawback: The names are not as descriptive as they should be.

Make DataSource a "wrapper" for the real implementation:

```<code>class DataSource {
    private DataSourceImpl impl;

    DataSource(string fileName) {
        impl = ... ? new MdbDataSourceImpl(fileName) : new XmlDataSourceImpl(fileName);
    }

    Data ReadData() {
        return impl.ReadData();
    }

    abstract private class DataSourceImpl { ... }
    private class MdbDataSourceImpl : DataSourceImpl { ... }
    private class XmlDataSourceImpl : DataSourceImpl { ... }
}
</code>```

Drawback: Every data source method (such as ReadData) must be routed by boilerplate code. I don't like boilerplate code. It's redundant and clutters the code.

Is there any elegant solution that I have missed?

答:
I would go for a variant to your second option that allows you to phase-out the old, too generic, name DataSource:

```<code>abstract class AbstractDataSource { ... } // corresponds to the abstract DataSource in the ideal solution

class XmlDataSource : AbstractDataSource { ... }
class MdbDataSource : AbstractDataSource { ... } // contains all the code of the existing DataSource class

[Obsolete("New code should use AbstractDataSource instead")]
class DataSource : MdbDataSource { // an 'empty shell' to keep old code working.
    DataSource(string fileName) { ... }
}
</code>```

The only drawback here is that the new base-class can't have the most obvious name, because that name was already claimed for the original class and needs to remain like that for backwards compatibility. All the other classes have their descriptive names.

Body:
I would go for a variant to your second option that allows you to phase-out the old, too generic, name DataSource:

abstract class AbstractDataSource { ... } // corresponds to the abstract DataSource in the ideal solution

class XmlDataSource : AbstractDataSource { ... }
class MdbDataSource : AbstractDataSource { ... } // contains all the code of the existing DataSource class

[Obsolete("New code should use AbstractDataSource instead")]
class DataSource : MdbDataSource { // an 'empty shell' to keep old code working.
    DataSource(string fileName) { ... }
}

The only drawback here is that the new base-class can't have the most obvious name, because that name was already claimed for the original class and needs to remain like that for backwards compatibility. All the other classes have their descriptive names.


问:
Handling subscriptions, balances and pricing plan changes
Preamble

My aim is to create reusable code for multiple projects (and also publish it on github) to manage subscriptions. I know about stripe and recurring billing providers, but that's not what this module is aiming for. It should just be a wrapper/helper for calculating account balance, easy notifications to renew a subscription, and handle price calculations.

There are countries you can't use recurring billing because of the providers or payment possibilities having poor or no support for it or are too expensive (micropayments). And there are people that don't want to use recurring billing but pay their bill manually / avingg an invoice at the end of the year. So please don't suggest paypal recurring billing, recurly or similar services.

Situation

Let's say you have a model that can subscribe to a subscription plan (e.g. User). This model has a field that stores the identifier of a subscription plan it is currently subscribed to. So, on every plan change, the change is recorded.

There is a model (e.g. SubscriptionPlanChanges) with the following fields recording the mentioned changes:

subscriber relating to the subscribing model (User in this case)

from_plan defining the plan identifier the model had before change

to_plan defining the plan identifier the model has selected now

created_at is a date-time field storing the change

valid_until stores the date until the actual subscription is valid

paid_at is also a date-time field that defines if (and when) subscription was paid

Of course, that layout is discussable.

Question of account balance

When a User changes his/her subscription plan, I need to compare the plan fields, get the pricings, and calculate the deduction for the new plan based on the current plan's valid_until and its price. Say: You subscribed for a year of plan A but after 6 months, you upgrade to plan B, so you get a deduction of half the paid price for the 6 months of plan A.

What I am wondering: If a user e.g. switches to the free plan, he has a credit which can be deducted if the user wants to switch again. Would you cache that value in an additional field, or calculate through all the records related to that user every time? Would you add/change something about the table layout?

Question of easy comprehensibility

When the end of a subscription period arrives, the user gets notified and has the possiblity to renew his subscription by paying again. The easiest way would be to just update paid_at and valid_until with new subscription options. However, I am not sure if you store every data someone might need, like a payment/subscription history.

Another option would be to create an additional record for this, where from_plan and to_plan are having the same identifier (thus symbolizing "no change"). But wouldn't that interfer with calculating the account balance in some way?

If someone could point me into the right direction about the logics handling such subscriptions, I'd appreciate it very much.

UPDATE

Thanks for the help by now. I think my question was too vague so I'll try to be more precisely by using less abstraction. Unfortunately, I could not solve my problem yet.

Case A

User can select Subscription Plan A. This currently stores a SubscriptionPlanChange to keep track of it. After e.g. 5 months, User upgrades his subscription to Subscription Plan B. So he pays the price for his new subscription, deducting the price of plan a for the unused 7 months.

Case B

After 3 months, User rolls back to his Subscription Plan A. He does not have to pay but receives a balance for it so that, at the end of the subscription, he gets that balance deducted for his new subscription.

Case C

User can select a subscription plan for a sub-service that has independent subscription plans. Same Case A and Case B can apply for that sub-service subscription.

_Case D_
User cancels one of his subscriptions. This results in a top up of his balance.

My question (currently, at least) mainly depends on how to store that data properly so I can reproduce a history of subscriptions for business analysis and calculate balances, get outstanding payments based on the subscriptions etc.

I am also not sure if the balance should be stored in e.g. the users model itself, or if it is not stored but can be calculated any time based on the stored data / history.

Some things to note, although I don't think that they should introduce problems:

It does not have to be a User, it could be anything, that's why the Subscriber is polymorphic

Plans do not necessarily have to be plans, but could be e.g. Magazines like mentioned. That's what I've described with Case C and Case D.

答:
Unfortunately, the answer to a complicated problem is usually complicated.  My advice to you would be to save only relevant information, then use a model to construct the bigger picture.

In other words, your table SubscriptionPlanChanges would have the following information for its key:

subscriber

plan

valid from

In this way, you allow for multiple plans for the same subscriber which can overlap.  Other fields include:

valid until

paid until

rate (also 0 if free)

Notice that there is no "plan from" or "plan to".  Although you could have them, the information is superfluous and can be calculated on your own (storing such information means you have the additional task of keeping it consistent).  When a new plan begins, rather than having to modify existing plans, you leave them and simply add a new record.  If another overlapping plan exists after thew new plan, you may then decide you want to delete it (more intuitive this way).  When you load these plans for a subscriber, you sort them by their "valid from" date.

Once you obtain this, calculating the credit of a user is relatively simple.  If two plans cannot overlap, you simply take the lesser of two dates between the "valid until" date of the previous plan and the "valid from" of the current plan in order to determine the end date.  The start date is the greater of the two dates between the "valid from" date and the "paid until" date (if defined).  The payment (or credit) can then be calculated on the rate multiplied by the interval of time between the above-mentioned start and end dates of that plan.

In this way, you can in theory calculate whatever you'd need to know.  I would advise against trying to save calculated values, since it would change when an existing record is modified, added, or deleted.

Variations of how you would calculate these values can be managed by adding an additional type field.  In your code, you could create special handlers to manage the logic of calculating particular plans in order to keep your main algorithm relatively clear of complicated calculations.  Better still if you manage to create a handler for the case in which no type is specified so all you have to do is call the appropriate handler according to its type in order to make any sort of calculation you require.

I hope that answers your question.


问:
Is having my objects so aware of each interconnection a bad thing?
I'm looking to refactor an existing design; to move a bunch of stuff out of a database and into memory where it should be (There are many reasons the DB approch is dangerous as it is now).  My first act was to take all the existing objects and expand more state to them.  The previous objects new only their parents, and that was it.  From the youngest child you could walk up to find parents, but you couldn't ask "what edges are on this node" at all.

I changed things to make state more accessible from every object.  Now each object effectively knows of it's parent and all of it's children.  I thought this was an obvious simplification that would make storing things in memory much easier.  The problem is that I need to be able to construct objects without modifying my model, untill addToModel is called, which means I need to be able to construct objects in one state, and then update some of their state to be consistent with the Model's state and properly represent all the interconnectivity (node has to be informed when an edge is added, edge needs to know it's paths etc etc).

This proved surprisingly complicated to keep consistent.  I end up with either encapsulation issues (like assuming each object knows not to call the package scope methods that change memory from public methods that shouldn't be able to change state), as well as a concern about aliasing (what if someone creates a new Node A with no connections, when my Model says node A should be connected to B, C, and E?).  I thought of many approches that work, but none feel 'clean'.  Is the issue that I"m trying to make my objects too aware of state, and thus putting too much effort on my model to maintain this state?

答:
This is why linked lists are not defaultly doubly linked. It seems at first glance that doubly linked would be easier, but pretty quickly you realize the actual implementation for a singly linked list is considerably simpler.

So you refer to the model in this way being an obvious simplification; but are coming to realize, that's not actually the case. The less any given object knows, the simpler it's implementation, and maintenance in the long term will be. This is why it's best to make objects only know so much as is necessary, then add state/memoization only when tasks working with the model become overly difficult. Weigh the scenarios you need account for with each piece of state your add to an object against the implementation necessary to deal without that bit of state added to the object.

Another way of ensuring simpler maintenance of your model is to make all objects that won't need necessary mutability immutable. This again reduces the amount of implementation as those parts of your models don't need to account for update scenarios.


答:
You can externalize edges from your nodes and use something else to modify/query connections.
For example look at JUNG (java graph library) where nodes and edges can be anything and you tell graph that it should contain node(s) and edges between them.
And there are multiple implementations (build in are IIRC dense and sparse, but you can create your own). Anyone with acces to graph can query it and change it, but you could create some graph view (something with only query methods and pass only it outside, not the graph object itself). </p>

Title: Is having my objects so aware of each interconnection a bad thing?

Body:
I'm looking to refactor an existing design; to move a bunch of stuff out of a database and into memory where it should be (There are many reasons the DB approch is dangerous as it is now).  My first act was to take all the existing objects and expand more state to them.  The previous objects new only their parents, and that was it.  From the youngest child you could walk up to find parents, but you couldn't ask "what edges are on this node" at all.

I changed things to make state more accessible from every object.  Now each object effectively knows of it's parent and all of it's children.  I thought this was an obvious simplification that would make storing things in memory much easier.  The problem is that I need to be able to construct objects without modifying my model, untill addToModel is called, which means I need to be able to construct objects in one state, and then update some of their state to be consistent with the Model's state and properly represent all the interconnectivity (node has to be informed when an edge is added, edge needs to know it's paths etc etc).

This proved surprisingly complicated to keep consistent.  I end up with either encapsulation issues (like assuming each object knows not to call the package scope methods that change memory from public methods that shouldn't be able to change state), as well as a concern about aliasing (what if someone creates a new Node A with no connections, when my Model says node A should be connected to B, C, and E?).  I thought of many approches that work, but none feel 'clean'.  Is the issue that I"m trying to make my objects too aware of state, and thus putting too much effort on my model to maintain this state?


问:
Was C designed to facilitate Object-Oriented programming?
I am trying to broaden my understanding of the history and development of object-oriented programming, and I am curious to find out
if C was designed to facilitate Object-Oriented programming? (like C++ and Objective-C definitely are) or if it was, on the contrary, simply just a clever exploitation of the language's constructs.

I cannot seem to find any sources, including K&R, where the original authors comment on this approach.

Recently I have been looking into OOP in ANSI-C, which is described in Object-Oriented Programming With ANSI-C by Axel Schreiner.

For a freely available PDF version visit http://www.cs.rit.edu/~ats/books/ooc.pdf.

A slightly different approach is used in the part of the Linux kernel dealing with file systems, visit http://lwn.net/Articles/444910/ for more info.

The common idea is to put function pointers in a struct along with fields in order to 'emulate' a class' methods and data members.

Chronology

From Wikipedia.org/wiki/Object-oriented_programming#History

Objects as a formal concept in programming were introduced in the 1960s in Simula 67

While Wikipedia.org/wiki/C_programming#K.26R_C states that

In 1978, Brian Kernighan and Dennis Ritchie published the first edition of The C Programming Language.

The chronology seem to suggests that K&R must have been well aware of OOP.

So again:

Was C designed to facilitate Object-Oriented programming?

答:
Short version: C was before OOP's time, so it wasn't a design choice.

Object oriented programming, OOP, is an old idea. But as a cultural phenomenon it only took off in the 80's and 90's. As someone born in the 80's I'd say it was C++ that launched the hype, set the trend, started the buzzword, or otherwise got OOP off the ground. That turned it from an academic pet project to something businesses looked for on resumes. And that's the sort of statement out of ignorance that will get the grey-beards to come out of the woodwork claiming that it was really Delphi or some other language that was the igniter. And they'll be countered by the historians that can show some Renaissance Italian first had the concept of oriented objects. And the whole thing ends in flames. But trust me, OOP really took off well after C was designed.

History aside, C is a low-level language and as such it can implement nearly anything that the higher level languages take for granted. You can implement a system that acts like C++'s inheritance. You can implement a system that acts like Java's reflection. Whatever crazy design patterns these young whippersnappers come up with in their fancy dancy new languages will probably be able to be implemented in C. Whether or not it's a good idea, is another issue.


答:
Some problems with ZF, which make it annoying (and hard for beginners) to work with:

ORM not included. One would think that this should be very base of modern MVC framework, yet ZF only comes with Zend_Db_Table, which is ridiculously low-level. You can use Doctrine, but then you're on your own, it's not in any way integrated with ZF.

Unreadable, bloated URL routers. For example it takes 9 lines of code to define the very simplest of routing:

```<code>$route = new Zend_Controller_Router_Route(
    'archive/:year',
    array(
        'controller' => 'archive',
        'action'     => 'show'
    ),
    array('year' => '\d+')
);
$router->addRoute('archive', $route);
</code>```

Given amount of question related to this it's anything but simple for most people.
Also, I can't help it and compare it to Django, where the equivalent of above it would be

```<code>url(r'^archive/(?P<year>\d+)/$', 'archive.show')
</code>```

Zend_Acl is way to complicated for most of use cases. Normally you'd have authentication to identify user. And an option to easily limit access to some controllers only to authenticated users. For many user case that's enough. For more complicated case it would be up to business logic in controller to determine if user has permissions to perform certain action. In ZF you don't have option to easily limit access only to authenticated users, the standard way is to use ACL and roles system, regardless how simple your need actually are.

Bloated directory and file layout.  Recommended directory structure looks like this:

```<code><project name>/
    application/
        configs/
            application.ini
        controllers/
            helpers/
        forms/
        layouts/
            filters/
            helpers/
            scripts/
        models/
        modules/
        services/
        views/
            filters/
            helpers/
            scripts/
        Bootstrap.php
    data/
        cache/
        indexes/
        locales/
        logs/
        sessions/
        uploads/
    docs/
    library/
    public/
        css/
        images/
        js/
        .htaccess
        index.php
    scripts/
        jobs/
        build/
    temp/
    tests/
</code>```

Title: Why is Zend Framework so complicated?

Body:
I am web developer and have experience of developing several web applications in PHP. I have an idea of developing a product for myself and decided to use a MVC based framework because I really like the idea of MVC and how one can easily manage and modify the application without any difficulty.

I chose Zend Framework and it seems more difficult than learning a new programming language. There are so many things going at one time even to run a small application.

Similarly the idea of routing is very complex as it is new for a core programmer. I know that the guys here read thousand of such questions like one I am asking but I am not looking to learn Zend Framework overnight. I am willing to give as much time as it needs but until now it's making no sense to me. There are thousand of classes in the Zend library, but how would a noob know where to use a specfic class and how to use it? I am still finding it very difficult to understand the bootstrap of Zend Framework and its mapping. I read the manual, follow it and things start working but I really don't exactly how they are actually happening.

I also still have no clue how models, views and controllers work together and how to plan an application in Zend Framework. When it comes to core php I exactly have the idea in my mind what to do and than easily translate them in code but in Zend Framework I don't know how to translate my idea.

Body:
Some problems with ZF, which make it annoying (and hard for beginners) to work with:

ORM not included. One would think that this should be very base of modern MVC framework, yet ZF only comes with Zend_Db_Table, which is ridiculously low-level. You can use Doctrine, but then you're on your own, it's not in any way integrated with ZF.

Unreadable, bloated URL routers. For example it takes 9 lines of code to define the very simplest of routing:

$route = new Zend_Controller_Router_Route(
    'archive/:year',
    array(
        'controller' => 'archive',
        'action'     => 'show'
    ),
    array('year' => '\d+')
);
$router->addRoute('archive', $route);

Given amount of question related to this it's anything but simple for most people.
Also, I can't help it and compare it to Django, where the equivalent of above it would be

url(r'^archive/(?P<year>\d+)/$', 'archive.show')

Zend_Acl is way to complicated for most of use cases. Normally you'd have authentication to identify user. And an option to easily limit access to some controllers only to authenticated users. For many user case that's enough. For more complicated case it would be up to business logic in controller to determine if user has permissions to perform certain action. In ZF you don't have option to easily limit access only to authenticated users, the standard way is to use ACL and roles system, regardless how simple your need actually are.

Bloated directory and file layout.  Recommended directory structure looks like this:

<project name>/
    application/
        configs/
            application.ini
        controllers/
            helpers/
        forms/
        layouts/
            filters/
            helpers/
            scripts/
        models/
        modules/
        services/
        views/
            filters/
            helpers/
            scripts/
        Bootstrap.php
    data/
        cache/
        indexes/
        locales/
        logs/
        sessions/
        uploads/
    docs/
    library/
    public/
        css/
        images/
        js/
        .htaccess
        index.php
    scripts/
        jobs/
        build/
    temp/
    tests/


问:
What's the dominant naming convention for variables in PHP: camelcase or underscores?
The consensus seems to be that one should follow the convention of the platform they're developing for. See:

Underscore or camelcase?

Naming conventions: camelCase versus underscore_case?

However, PHP doesn't seem to strictly follow any convention internally (no surprises there), even for methods and functions (e.g. mysqli::set_local_infile_default,
PDOStatement::debugDumpParams); however, underscores seem to be dominant in function names.

However, what I couldn't find was this: what's the dominant naming convention for variables in PHP?

答: This depends on the programmers/developers as well as the framework or open source they are working on. For example, in the Yii framework, it is advisable to use camel case whereas in the Codeigniter framework, most people follow variable names with underscores. One thing for certain is that regardless of which framework you use, the variable name must be understandable and identifiable.</p>


答:
It all depends of what you are trying to test. If you want to test only your own application because the 3rd party application has already been tested, then:

Unit test the calls that creates data on the folder in a way that doesn't really create these files (you don't want to use file or database in unit testing). Anyway, if you use .NET, you already know that the saving of the file works (it's part of the framework)

Unit test the function that are called when the event of new file in the folder is triguered. Again, no needs for a real folder, juste inject already processed data to your function.

This will make a realy fast unit test of all your code.

But... If you want to test the interaction with the 3rd party or with the file system, then what you need is integration testing which means that you test all the parts that have already been unit tested and assert how they work together. This can be done with GUI automation software like Ranorex or if you software is triggered by event like "Is folder updated with new file?", you can just do a .bat that do the trick.

Anyway, I know what I'm saying has been formulated with other words in other question but I think it was important to tell the difference between unit testing and integration testing.

Hope it helps!


答:
The usual sequence is 'make it correct, then make it elegant, then make it efficient'. The first step may result in as lengthy code as you need, as long as you can keep track of what's going on.

Gradual refining of code is an ongoing process, and even best programmers are known to say that some of their most productive days were when they removed 1000 lines of code. You should worry when you can't simplify your large and complex code any more, not the other way around.

Title: Coding style (do more, then simplify)


答:
As coding for more than ten years with PHP, I can see a change from underscore to camelCase. Especially the bigger frameworks like Zend and Symfony build up on camelCase also when they don't prohibit underscore, but all the core function is camelCase.

You can see a lot of underscore solutions in older systems, like the old Typo3 branch (Typo3 Neo changed to camelCase, too).

But there is definitely no strict rule, which is used by everyone, that's just what I can see over the past few years.

Title: What's the dominant naming convention for variables in PHP: camelcase or underscores?

Body:
The consensus seems to be that one should follow the convention of the platform they're developing for. See:

Underscore or camelcase?

Naming conventions: camelCase versus underscore_case?

However, PHP doesn't seem to strictly follow any convention internally (no surprises there), even for methods and functions (e.g. mysqli::set_local_infile_default,
PDOStatement::debugDumpParams); however, underscores seem to be dominant in function names.

However, what I couldn't find was this: what's the dominant naming convention for variables in PHP?


问:
What is a good analogy to explain how software development is different than building a bridge?
If you had a manager, a couple of levels above you, tell you that building software is like building a bridge, how would you respond to that?

If this manager truly believes that we should be able to accurately estimate and build a system, what good metaphors are out there to explain why this isn't the case?

答:
He is right, but not in the way he thinks. Do you know how much time and energy goes into planning a civil engineering project?

In contrast, most software engineering projects probably receive 1/10th the planning and are expected to be at least 50% more accurate.