问:
Inject specific classes or not
I have a TableSqlBuilder interface which has a method getCreateTableSql. This interface is used in some other class as follows:

```<code>function createTable( $tableDefinition ) {
    $sql = $this->tableSqlBuilder->getCreateTableSql( $tableDefinition );
    $this->db->execute( $sql );
}
</code>```

The TableSqlBuilder interface has multiple implementations, such as SQLiteTableSqlBuilder and MySQLTableSqlBuilder.

SQLiteTableSqlBuilder originally created all SQL itself, and had methods to create SQL for an index or for a field. It turned own that the functionality of these methods was needed on its own at other places, so it has been split off into a SQLiteFieldSqlBuilder and a SQLiteIndexSqlBuilder. These classes are instantiated by SQLiteTableSqlBuilder - they are thus not injected, and SQLiteTableSqlBuilder depends on these concrete classes.

I'm unsure if this should be changed to have these field and index sql builders injected. On the one hand this gives more flexibility. It also allows mocking out this behaviour in tests. Then again, the binding and flexibility is currently the same as before the code was split of into new classes.

When going with the injection approach, the accepted types could be FieldSqlBuilder and IndexSqlBuilder, both interfaces implemented by the current concrete classes. This however means one can happily end up with a MySqlIndexBuilder in a SQLiteTableBuilder, which is clearly to be avoided. Could also just type hint against the concrete class, pretending it is an interface, which gets rid of the dependency as long as the construction happens outside of the table sql builder.

Do you think these collaborators should be injected, or is it a valid exception where it is better to not go all the way?

答:
It's a good idea to inject SQLiteFieldSqlBuilder and SQLiteIndexSqlBuilder specifically into SQLiteTableBuilder. If you decide you want to allow alternate implementations (e.g. for mocking), you can more easily refactor SQLiteIndexSqlBuilder and SQLiteFieldSqlBuilder into interfaces when necessary.

Injecting general FieldSqlBuilder and IndexSqlBuilder implementations into a SQLiteTableBuilder is not a good idea, since it doesn't properly represent its dependencies. The situation in which you would inject implementations of general interfaces like FieldSqlBuilder and IndexSqlBuilder would be for a general TableSqlBuilder class that works for both SQLite and MySQL field/index builders. This is a perfectly valid and recommendable approach, provided that the logic inside of TableSqlBuilder can be generalized for both cases.

Title: Inject specific classes or not


问:
How to implement software for my vehicle
I'm developing a Driver Safety Monitoring System which is kind of small software which would be implemented inside a car with connections to few cameras.

What I want to know is to implement this software inside the vehicle what kind of computer can I use?

答:
In a modern car there are several CAN buses, connected with a router. The mission-critical electronics reside on a low-latency bus, while the user experience (multimedia, air conditioner) devices reside on a high-throughput bus.

Regardless of which network the cameras belong to, your software will probably need to know current speed, airbag readiness, etc, and those are accessible from the "critical" network. And you should really not be touching there!

So, enough rambling.

If you decide to produce your own computer/board/smartphone app, you will need to interface it to the CAN bus, and send request to the central router for certain data streams.

If you decide to embed it in the car's computers ... I don't know. Everything is closed source and many things are safety-crytical.

Take a look at this car software inegration suite. Some manufacturers use it.

Best bet - go to your repair shop and ask the mechanics what tools they use to update the software, and how much they cost.

Only painless/possible way that I see is to use dedicated cameras connected to a dedicated computer (could be a smartphone) through a dedicated bus.

ContentLicense: CC BY-SA 2.5

ContentLicense: CC BY-SA 3.0


问:
How would I implement a "self-destruct" feature into the free trial version of my software?
There is the ongoing argument of free trial versus a freemium model (that is, a free-for-life version of their software with restricted and/or stripped down features) for allowing potential customers and users to test run their product. Upon my research, I can conclude that the free trial is the way to go on both for the benefit of the user experience of the individual using the software and for the benefit of the vendor in both aspect of sales and maximizing usage. There are many factors for a free trial software that can greatly maximize user usage like the length of the free trial.

One keyword that reoccurs on my research for "freemium" is "frustrating". Many individuals chose to uninstall the software instead of having to use a piece of software where some features were unavailable to them. At the same time, these users never had the chance to use the "paid" features. Unbeknownst to them, and hidden by the very own vendors who are selling the software, they don't know and cannot know what benefits the Pro features will bring. Without first having to use them, a user will not know they have the feeling of "needing" something. Which brings me onto my next point of a free trial model.

Some opinions of a free trial user is "I cannot imagine using this software without the Pro features." This goes back to the point of "the user not knowing they need something until they first understanding the feeling of have." Those that have had 14 days to use a the "full" version features said they cannot imagine not having or using the features provided there. So when fourteen days were over, they were more likely to dish out money than someone who's never experienced the full features. The length of the free trial is also an important factor is creating a lasting impression on users. In an experiment conducted by Visual Website Optimizer, they noticed that for a 14 day free trial versus a 30 day free trial, while the number of sign ups and installs were the same, the usage for the 14 day trial increased 102%. This, of course, in turn increased their revenue as well.

Another very important point to mention is that "offering a useful and fully functional free version of the product" is VERY IMPORTANT. Fully functional free trials are effective in getting media coverage, and this publicity for new software and/or software vendors are fairly crucial.

One other relevant aspect is the importance for users to give feedback. Consider, in the fully functional time-limited free trial, the ability for users to give feedback.

One other feature important for our software is the need for telemetric data, that is, quantitative and comprehensive data on how a user uses our software. Some of usage statistics may fall into a legal grey area, as laws are different depending on the location in the United States, and the world. One way to combat this legal issue is to have an opt-in feature for gathering anonymous usage statistics. An opt-in feature would mean giving the user an option to turn off statistics gathering and at the same time, the user must be very well aware of what the gathering of anonymous usage information does. It is important to make it CLEAR to the user what data will be collected, what "we" will be doing with it, and make it easy to turn off any time, including allowing them to change their mind for turning it on or off. For more detailed statistics, like tracking individual activities of users, it could lead to legal issues. The Eclipse IDE logs detailed usage statistics, but it does it by the full consent of the user. We may have to potentially prepare a consent form with our legal team.

The Eclipse Usage Information Collection collects this information:
1. Plug-ins that are started by the system.
2. Commands accessed via the keyboard shortcuts and actions invoked via menus or toolbars.
3. When the "view" of the editor is given focus.
4. System information like the version of the software being used, the operating system being used.
5. Description of internal errors.

Kill Switch

A kill switch for our software can be managed logging the initial data, encrypting it with a salt, and whenever it's an invalid date, that is, the user tried to change it, it would disable the software. Another option is to have internet authentication on install, log that date to a central web database, and check the date every time the application is opened.

On disabling the software, we can delete vital DLLs. The option of having to pay to generate a report cannot be considered.

I am interested in implementing a free trial version to my existing software. I plan on having the trial last 14 days. Upon the 14th day, my software would prompt the user to either pay for the paid version, or have the consequence of not being able to use it. The free trial version is entirely unlocked, meaning all paid features are there.

However, my dilemma is about the "best" way to implement what to do for an end-of-trial solution. Do I delete vital DLLs? Have a user authentication system upon installation or use? Encrypt the initial time and date of use with a salt, and if it's an invalid date (AKA they try to change their initial date), disable the software?

I am interested in knowing what are some effective measures of disabling software.

答:
It depends on how hard you want to make it for your potential customers to circumvent that self-disabling features (sounds better than "self-destruct"). Assumed your potential customers won't try to manipulate the program code itself (which some of them will try, trust me), you have the following options:

store the initial date time somewhere (hidden) on the computer where your software is installed: this has the drawback that your customers can easily circumvent it, for example, by installing your program in a virtual machine, and deinstalling it after the trial period by resetting the VM to its original state

make sure each downloaded copy of your program has an individual hard-encoded download time somewhere hidden in the programs binary code. This will need a lot more administrative effort from you, and you still cannot be sure that the same person does not download a new copy of the program from your server after the trial period (perhaps, using a different identity)

deliver the trial version only with a "dongle" where the end of the trial period is stored. This will be only feasible for programs with a handful of potential customers and a price far higher than the price of the dongle.

make the thing a web app, or parts of it, or just a web-connected app. In this case, you could store the initial date on your server, but you will have to identify and distinguish the people who are using your software (for example, by setting cookies or creating a log-in). But again, you cannot be 100% percent sure that the people don't change their identity.


问:
Understanding the difference between mutable and immutable classes
I faced this question in one interview. I explained that String is immutable and StringBuffer is mutable class. I don't know very much about mutable and immutable and also don't know the exact answer. What are the key concepts to be able to distinguish the two ideas?  Is there a performance impact when chosing one over the other?

答:
An immutable class is immutable, as in, it is not mutable. You cannot change it. If you have x::String, you can be absolutely 100% certain that x will never ever change ever (or at least, if it does, people are abusing the flexibility of your language and you have every right to tell them where to go).

A mutable class is not immutable. You can change it, other people can change it, and you can't rely on it being the same. It could be changed in another thread, you can't even be sure of it being in the same state from line to line unless you have good locking.

The ability to alter the state of the object is the key concept, but the story doesn't end there. You might want to choose an immutable class in a threaded environment, because now you don't need to worry about locking, because nobody can write to it anyway. You might want to choose immutable objects in a large system, because you can't be certain that nobody else has a handle on that input parameter and won't change it out from under you the first chance they get. You might want to choose immutable objects because they make reasoning about the behaviour of your code in small units possible--as in, if everything about a function relies on immutable data, you can look at that function in isolation, guaranteed.

There are performance impacts, but it's not all one way. Immutable objects enable a lot of optimisations you just can't do on mutable data, like aggressively sharing memory (because hey, it can't change) or more aggressive inlining. Mutable data tends to get performance increases when you need to make a lot of changes to blocks of memory.

If you're interested in seeing somewhere where immutability really shines, take a look at a language like Haskell, which was designed from the ground up for immutability, enabling language-level support for things like laziness and a lot of optimisation.


问:
Should there be a formal role (internal or external) assigned to dev environments to control wasteful complexity?
A few years ago, I worked for a small company that went so far into developing in-house frameworks that they dedicated their most senior developer, and their architect to developing a custom MVC framework and ORM from scratch. These two things were orthogonal to their core product. Unfortunately the support for this framework-driven approach came from the top, and it delayed delivery of revenue-generating software - and the frameworks produced were notably inferior to off-the-shelf alternatives, which compounded the delays. The company burned through cash quickly, and, eventually, everyone was laid off.

A later employer made a similar mistake - they got a highly technically skilled developer - a perfectionist, with a strong grounding in enterprise design patterns to grossly over-engineer a consulting solution for one of their clients, knowingly taking a loss, in the hope that the solution could be adapted and extended for other customers. The project overran significantly. But no other potential customers bit. A gold-plated strategic blunder that cost a small fortune.

In both cases there was a significant degree of overengineering. In both cases the company and project management were people with domain or analysis backgrounds, rather than a programming background. In both cases the software architects built overly-complex solutions to scratch their itches, and enhance their résumés, with some complicity from non-technical management. In both cases the architects had no stake in keeping costs down (apart from the risk of losing their jobs if the companies went bankrupt- which wasn't much of a risk, considering their high employability).

My experience suggests that it isn't an uncommon trap for dev shops to fall into.

Is there place in software projects for a formal internal or external technical adversarial role - a "Quantity Surveyor" - to use a building analogy- that can call out, or prevent wasteful over-engineering? Who is best suited to fill this role?

答:
Is there place in software projects for a formal internal or external technical adversarial role - a "Quantity Surveyor" - to use a building analogy- that can call out, or prevent wasteful over-engineering? Who is best suited to fill this role?

No, usually there isn't such position.

The trick is to hire right people for the job. People who are not going to over-engineer, and do just what is needed.

This may be done by using agile approaches (like implementing requirements in iterations, or using TDD or BDD). But again, if the architecture is over engineered, it is not going to help.


答:
It's not difficult to do. It really depends on how much effort you want to put into it.

Remember, the purpose of a trial version is to increase sales. All trial version schemes for installable software can theoretically be gotten around by some means, even if it involves tremendous effort, since the code is executed locally and can thus be edited with a hex editor. This answer is working from the assumption that the original poster is asking about practical solutions to this business problem, not theoreticals.

As one of the other posters mentioned, the point is to make sure the effort involved in getting around the trial version scheme exceeds the cost in terms of time and effort than the cost of buying the software. Dedicated 'pirates' will simply download pre-cracked versions of your software using BitTorrent. Don't worry about them, as they wouldn't be customers anyway. The approaches below have been taken by countless software companies for decades, and as long as you are not crippled by the notion that such systems must be theoretically perfect, you will find they work quite well out in the real world.

At the simplest level, you could simply keep a start date/end date time 'window' in the registry (encrypted). Each time the program runs, you check that the system time is between those two dates, and update the 'start' component of that date.  That prevents the casual user from simply setting the clock back to allow access to the trial version.

You can extend this by keeping track of that time window in several locations (both in the registry and in your application's data folder), and making sure they match on each start up. That prevents people from monkeying around with the entries - they have to know exactly where they are and how to unencrypt/encrypt the data.

There's a number of other ways to tighten things down as well, which I'm sure you'd encounter as you start developing the trial functionality.

If you don't want to do all this yourself, there are quite a few third-party libraries that provide this sort of functionality.

Note regarding actually deleting files: If you're application tries to delete files, it may get flagged as malware by the user's anti-virus software. Anti-virus software is very aggressive these days. And many end users will be convinced there is a virus in your software if their anti-virus program pops up an alert.

Title: How would I implement a "self-destruct" feature into the free trial version of my software?

Body:
There is the ongoing argument of free trial versus a freemium model (that is, a free-for-life version of their software with restricted and/or stripped down features) for allowing potential customers and users to test run their product. Upon my research, I can conclude that the free trial is the way to go on both for the benefit of the user experience of the individual using the software and for the benefit of the vendor in both aspect of sales and maximizing usage. There are many factors for a free trial software that can greatly maximize user usage like the length of the free trial.

One keyword that reoccurs on my research for "freemium" is "frustrating". Many individuals chose to uninstall the software instead of having to use a piece of software where some features were unavailable to them. At the same time, these users never had the chance to use the "paid" features. Unbeknownst to them, and hidden by the very own vendors who are selling the software, they don't know and cannot know what benefits the Pro features will bring. Without first having to use them, a user will not know they have the feeling of "needing" something. Which brings me onto my next point of a free trial model.

Some opinions of a free trial user is "I cannot imagine using this software without the Pro features." This goes back to the point of "the user not knowing they need something until they first understanding the feeling of have." Those that have had 14 days to use a the "full" version features said they cannot imagine not having or using the features provided there. So when fourteen days were over, they were more likely to dish out money than someone who's never experienced the full features. The length of the free trial is also an important factor is creating a lasting impression on users. In an experiment conducted by Visual Website Optimizer, they noticed that for a 14 day free trial versus a 30 day free trial, while the number of sign ups and installs were the same, the usage for the 14 day trial increased 102%. This, of course, in turn increased their revenue as well.

Another very important point to mention is that "offering a useful and fully functional free version of the product" is VERY IMPORTANT. Fully functional free trials are effective in getting media coverage, and this publicity for new software and/or software vendors are fairly crucial.

One other relevant aspect is the importance for users to give feedback. Consider, in the fully functional time-limited free trial, the ability for users to give feedback.

One other feature important for our software is the need for telemetric data, that is, quantitative and comprehensive data on how a user uses our software. Some of usage statistics may fall into a legal grey area, as laws are different depending on the location in the United States, and the world. One way to combat this legal issue is to have an opt-in feature for gathering anonymous usage statistics. An opt-in feature would mean giving the user an option to turn off statistics gathering and at the same time, the user must be very well aware of what the gathering of anonymous usage information does. It is important to make it CLEAR to the user what data will be collected, what "we" will be doing with it, and make it easy to turn off any time, including allowing them to change their mind for turning it on or off. For more detailed statistics, like tracking individual activities of users, it could lead to legal issues. The Eclipse IDE logs detailed usage statistics, but it does it by the full consent of the user. We may have to potentially prepare a consent form with our legal team.

The Eclipse Usage Information Collection collects this information:
1. Plug-ins that are started by the system.
2. Commands accessed via the keyboard shortcuts and actions invoked via menus or toolbars.
3. When the "view" of the editor is given focus.
4. System information like the version of the software being used, the operating system being used.
5. Description of internal errors.

Kill Switch

A kill switch for our software can be managed logging the initial data, encrypting it with a salt, and whenever it's an invalid date, that is, the user tried to change it, it would disable the software. Another option is to have internet authentication on install, log that date to a central web database, and check the date every time the application is opened.

On disabling the software, we can delete vital DLLs. The option of having to pay to generate a report cannot be considered.

I am interested in implementing a free trial version to my existing software. I plan on having the trial last 14 days. Upon the 14th day, my software would prompt the user to either pay for the paid version, or have the consequence of not being able to use it. The free trial version is entirely unlocked, meaning all paid features are there.

However, my dilemma is about the "best" way to implement what to do for an end-of-trial solution. Do I delete vital DLLs? Have a user authentication system upon installation or use? Encrypt the initial time and date of use with a salt, and if it's an invalid date (AKA they try to change their initial date), disable the software?

I am interested in knowing what are some effective measures of disabling software.


答:
Just my 2¢.

100% reliable self-destruction is impossible. There will always be a  sophisticated way to crack your protection.

What you can do is to make using or cracking an expired trial more hassle than buying a full version for your target market.

If I were in your shoes, I'd try to ensure that my software is: (1) popular, so everyone interested at least tried it, and (2) reasonably priced, so those willing to pay can buy it, and you turn a profit. The rest of users can play with expired trials to their hearts' content: they'd not buy it anyway, but they do help popularity, and provide more potential hires for companies that actually buy your software.

I suppose that the target market for a Revit plugin consists of architects, building contractors, designers, all people handling relatively large amounts of money per contract, and no excess of free time or low-level computer expertise.

So make sure that your expired trial version sufficiently annoys them without actually breaking anything (or they'll hate you). People who need work done will eventually cave in and pay the [reasonable] price.

A few ideas:

Make a trial version quickly (and cleanly) uninstall itself on expiration. Reinstallation should be possible, so that users see their work intact, followed by another automatic uninstallation shortly afterwards.

Let output of an expired version include a mark or text saying "Made with an EXPIRED TRIAL version of [your software]". A serious user would not show such output to a customer. (And if he does, again, he's too cheap to pay for your software anyway).

Make an expired trial version show message boxes at random moments, warning that the trial has expired and giving a link to the full version. Such things break the flow of work enough to make an upgrade worthwhile for a serious user.

Any combination of usual tricks can be applied to mark a computer as having an expired trial: cryptic registry keys, cryptic files at random locations (don't forget to restore the timestamp if you modify them), hiding timestamps in unrelated graphic files or other forms of steganography, etc.

Of course if the user e.g. reinstalls the OS, he'll get a free trial period again. Never mind: a serious customer will hardly resort to that. Of course this scheme will eventually be cracked; be sure that your software is popular enough by then that you can offer an upgrade with compelling features and a different protection scheme.

As one example of very successful "inconvenience-ware" I'd pick Balsamiq Mockups. You can use their software for free (on the web), with some features limited, including saving your work. The work can be "exported" and "imported" back with some hassle. That is, any high-school student that wants to play with the free almost-fully-functional version can do so, and even can have some work done. The student won't buy it anyway. But a serious designer that values their time and convenience will buy it.

As another very successful example I'd of course take MS Windows.


答:
You're looking for something that's essentially impossible.  Some of the biggest, best-funded companies in the software industry have spent years, and millions upon millions of dollars, looking for a way to accomplish what you're trying to do, and it's never once actually produced successful results.

First off, you can forget all about screwing up a local install.  As long as the original installer still exists, (or can be backed up, or re-downloaded,) that's nothing more than a speed bump.  Even placing something somewhere in system settings means very little when the user can install to a VM and then back up and restore the entire VM image.

The next obvious step is online authentication: set up a server and have the program "call home" each time it's started to check credentials.  This doesn't work either. First, you run into obvious (and highly frustrating) problem of false negatives when the server is down or unreachable for any reason, or has some glitch in its software.  And you can't make the software just validate the user automatically if it can't reach the server, or it's trivial to work around the authentication with a few networking tricks, or just by using it on a machine with the wi-fi turned off.  (And of course, this means that people trying to legitimately use it with a good reason for not having a wi-fi connection, such as bringing their laptop along with them on the bus, will be locked out.  That won't make anyone like your program.)

The other problem with online authentication is that in the end, it boils down to a boolean somewhere in your code.  Somewhere it calls AuthenticateUser() and if it returns True, the user is in, and if it returns False, they're locked out.  And no matter what you do to encrypt, obfuscate or hide the code, in the end it boils down to the simple fact that if a computer can read it at some point, so can a programmer.  Someone, somewhere, is going to produce a crack where AuthenticateUser always returns True, and they'll put it up on the Web.

The fundamental problem of cryptography can be described as "Alice wants to send a letter to Bob, without Charlie being able to read it even if it were to fall into his hands."  The problem with what you want is that Bob and Charlie are the same person, which makes your goal impossible.

If you want to make money from your software, twisting your users' arms is not the answer.  What will work, the only thing that does consistently work these days, is basic market theory:  offer a product that the user perceives as having a greater value to him than the price you're asking for it, and he will be willing to pay.  Anything else will just be a waste of time and effort on your part.


问:
What techniques are there for debugging remote client side errors?
What techniques are there for debugging remote client side errors in a web application, especially when they only affect a small subset of users?

In my case we have an app that is working well for hundreds of users, internally and externally, but a handful (12) have a specific problem with a JavaScript that prevents them from using the site.  We have screenshots of the error, have confirmed they have no server side errors, confirmed that everything is getting rendered to the browser correctly, have seen the specific error in the IE console, but still have no idea why it isn't working for these specific users.  The issue is exhibiting on different versions of IE.  We have never been able to replicate the problem here.

I'm not looking for a solution to my problem here, but rather what are the steps you would take to solve this kind of problem, and what tools there may be that might help?

答: If you get really desperate, you can see if one of the users with this problem will allow you to remote desktop into their machine (using something like Logmein, or similar service.  I know at least one of them has a free option).  Then you can load your site, hit F12 in IE, and run the debugger to see whats going on.  This of course would only work if they are using a version of IE that has an integrated debugger... I don't know how far back that goes.</p>


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

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

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

Have you got any personal experience to share?

答:
One possible reason is that estimates are based on smaller projects, assuming a linear growth in cost with the project size, when in fact cost growth is e.g. quadratic due to increasing complexity, longer project duration (more time for requirement changes) etc. Estimating is hard, and the bigger the project, the harder it gets to estimate correctly.

Another reason are optimizm biased estimates: To win the bidding, best-case estimates are used to calculate the price. The larger the project, the less likely is a best-case scenario. Bidding rules make it likely that the most optimistic offerer gets the acceptance, so even if 5 vendors make a realistic estimate and the 6th is too optimistic, the optimistic one wins the bidding and fails later. So this is kind of a negative selection.


问:
How can I unit test a class which requires a web service call?
I'm trying to test a class which calls some Hadoop web services. The code is pretty much of the form:

```<code>method() {
    ...use Jersey client to create WebResource...
    ...make request...
    ...do something with response...
}
</code>```

e.g. there is a create directory method, a create folder method etc.

Given that the code is dealing with an external web service that I don't have control over, how can I unit test this? I could try and mock the web service client/responses but that breaks the guideline I've seen a lot recently: "Don't mock objects you don't own". I could set up a dummy web service implementation - would that still constitute a "unit test" or would it then be an integration test? Is it just not possible to unit test at this low a level - how would a TDD practitioner go about this?

答:
I would use something like EasyMock for this test. Mocking frameworks are an ideal way to remove outside dependencies on a class and gives you total control over the result of outside dependencies during tests. To extend your example a little:

```<code>class WebClass {

private WebServiceInterface webserviceInterface;

    void method(){
        R result = webServiceInterface.performWebServiceCall();
        ... do something with result
    }

    public void setWebServiceInterface(WebServiceInterface webServiceInterface){
        this.webServiceInterface = webServiceInterface;
    }
}

interface WebServiceInterface {

   R performWebServiceCall();

}

class WebClassTest {

private WebServiceInterface mock;
private R sampleResult = new R();

    @Before
    public void before(){
        mock = EasyMock.createMock(WebServiceInterface.class);
    }

    @Test
    public void test() {
        WebClass classUnderTest = new WebClass();
        EasyMock.expect(mock.performWebServiceCall()).andReturn(sampleResult);
        classUnderTest.setWebServiceInterface(mock);
        classUnderTest.method();
        EasyMock.verify(mock);
    }
}
</code>```

The first thing you'll need to do is extract the logic in your class where you use Jersey to get a WebResource and call the web service into a separate class. Creating an Interface for this class will allow you to create a mock to which you can then dictate behaviour.

Once this interface is created, you can create a mock using EasyMock, which will return a specified object accoring to your test case. The example above is a simplification of how to structure a basic mocked test and how your interface will work.

For more information on mocking frameworks, please see this question. Also, this example assumes the use of Java but mocking frameworks are available in all languages and although they be implemented differently, they will work in generally the same way

Body:
I would use something like EasyMock for this test. Mocking frameworks are an ideal way to remove outside dependencies on a class and gives you total control over the result of outside dependencies during tests. To extend your example a little:

class WebClass {

private WebServiceInterface webserviceInterface;

    void method(){
        R result = webServiceInterface.performWebServiceCall();
        ... do something with result
    }

    public void setWebServiceInterface(WebServiceInterface webServiceInterface){
        this.webServiceInterface = webServiceInterface;
    }
}

interface WebServiceInterface {

   R performWebServiceCall();

}

class WebClassTest {

private WebServiceInterface mock;
private R sampleResult = new R();

    @Before
    public void before(){
        mock = EasyMock.createMock(WebServiceInterface.class);
    }

    @Test
    public void test() {
        WebClass classUnderTest = new WebClass();
        EasyMock.expect(mock.performWebServiceCall()).andReturn(sampleResult);
        classUnderTest.setWebServiceInterface(mock);
        classUnderTest.method();
        EasyMock.verify(mock);
    }
}

The first thing you'll need to do is extract the logic in your class where you use Jersey to get a WebResource and call the web service into a separate class. Creating an Interface for this class will allow you to create a mock to which you can then dictate behaviour.

Once this interface is created, you can create a mock using EasyMock, which will return a specified object accoring to your test case. The example above is a simplification of how to structure a basic mocked test and how your interface will work.

For more information on mocking frameworks, please see this question. Also, this example assumes the use of Java but mocking frameworks are available in all languages and although they be implemented differently, they will work in generally the same way


答:
mutable - liable to change.

immutable - unchanging over time or unable to be changed.

Ok so we have the definitions. We know exactly what the words mean but how do they apply to programming? Let us move on to two new definitions.

mutable object - an object that is liable to change.

immutable object - an object that is unchanging over time or unable to be changed.

We can directly use the original definition when we put it in terms of object oriented programming. The final question is how do I use this in practice?

An immutable object must be initialized upon construction and rely
only upon other immutable objects once initialized.

Title: Understanding the difference between mutable and immutable classes

Body: I faced this question in one interview. I explained that String is immutable and StringBuffer is mutable class. I don't know very much about mutable and immutable and also don't know the exact answer. What are the key concepts to be able to distinguish the two ideas?  Is there a performance impact when chosing one over the other?


问:
Is it possible to do decent spam filtering without scanning the contents of emails?
I don't have much knowledge of the subject but as I know, when servers receive an email they have two sources of data to classify it as SPAM or not. The contents of the message (subject + body) and the metadata that goes with it (from who / to who / server that sent the message, etc).

I know you can do basic filtering by blacklisting emails list and other sorts of metadata. But is it possible to do decent spam filtering without checking the contents of a message? Defining 'check the contents' as using any function that relies on data found on the body/subject of the message to classify it as spam or not spam.

Edit: The reason I ask for this because of the "scroogled" campaign where Microsoft accuses Google of scanning the contents of emails for advertising purposes, and I think that they do the same for spam prevention purposes. So I asked them and they said:

We have tools and system set up to filter spam emails to and from
  Outlook.com email accounts. However, we are not allowed to disclose
  how these spam filters work for security purposes.

ME: So can you assure me that no content from my personal email is
  being analysed and cross referenced with other data in any way?

...In response to your question, its a yes, we can assure you that.

答:
is it possible to do decent spam filtering without checking the
  contents of a message?

Considering that 100% of the metadata that is useful in spam filtering can be spoofed,the answer to your question, is a big fat "NO".  The actual contents is vital in order to determine if the contents matches previous spam email.

Lets put it another way, there is an infinite amount of email addresses, there isn't enough storage to filter every single email address that sends spam.  While some of the metadata cannot be spoofed, the contents are not universal, email servers don't have the same behavior.  Some email providers verify the sender was actually the sender, others will trust the information, and do no other verification process.

Microsoft's claims are connection to the fact they will not display ads based on the content of your email.  Microsoft does indeed scan your email in order to block email spam from reaching you or at the very least flagging it as spam so you can delete it yourself.

Additional your question was "... is being analysed and cross referenced" which means their answer is accurate your email is NOt being analysed AND cross referenced its likely just being analysed.  Furthermore the person replied isn't likely to be qualified to answer your question


问:
Why I'm not selected in an interview?
I'm working in development for 4 years, and 3.5 in PHP - why I don't seem to be able to be selected in an interview.

I want to know what special things the interviewer wants to see in candidates - for senior PHP developer roles.

Interviewer asks me 10 questions and I'm able to answer only 5. Does selection depend on these things? It doesn't mean that I can't solve the problem, I can google the question, I can ask on forums. Why don't they understand that a man can't remember all the answers for each and every question? Especially programming ones.

Please advise.

答:
UPDATE: this answer has been made based on the first version of the question, which asked "why i am not selected in interview"

Show us your CV and we'll tell you.

Did you...

... put your photo? Remove it

... put emphasis on your problem solving capabilities?

... send it to enough companies? (To get one interview, you must send 10 CV)

... have too much pages? Limit your CV to one page

... send it to companies that actually need PHP?

... tried different versions of your CV?

Title: Why I'm not selected in an interview?


问:
Is smarter software necessarily bigger?
This is kind of a vague question so I apologize in advance.

When software is "smarter", I tend to interpret that as really just saying that it covers more edge cases.  First of all, is this correct?

Assuming it is, does this mean that the software is full of if/switch statements to make sure input is handled properly, therefore making it "smarter"?

This thinking makes me feel like the code would end up bloated and messy.  I'm running into a point where I'm wanting to handle these edge cases, but I don't want to bloat my code merely overlooking some best practice. What am I missing?

答:
As FrustratedWithFormsDesigner mentioned, more likely than not, not covering for edge cases produces incorrect or error prone software. Not to mention the security risks caused by poor handling of edge cases(i.e. buffer overflows, sql injection, etc.).

Intelligence of software depends on your definition, it may refer to software capable of machine learning, it may also refer to software that handles inputs & errors gracefully and goes the extra mile by doing the end user a favor. For example, suggesting links related to the search query when it returns no results. Autocomplete with suggested terms, etc...

Now, making your application "smarter" doesn't necessarily make it bloated or bigger. An efficient and well-written algorithm can probably keep your code from being bloated, not to mention that most of the times, there are already pre-existing libraries and frameworks out there that help you do the basics without bloating up your code.

For example, when dealing with sanitizing input from the user, instead of making a switch case block or a large if else block, a ruby on rails programmer can just make use of the validates helper methods. This drastically reduces the amount of code needed to do the form validations, not to mention that it makes your job easier.

In programming, there are always more than one way to do things, so if you think what you're doing is causing your codebase to bloat, take a step back and reexamine your code, maybe you can code it better to keep the bloat to a minimal.

Title: Is smarter software necessarily bigger?


答:
If the design is similar then yes it will be larger. No it shouldn't be bloated and messy.

Explore ways to handle your edge cases gracefully.  Contracts and aspect oriented programming are two such ideas you might find interesting.  Other than that smarter code organization can help.  Small functions that just check edge conditions and can be reused in multiple places can help cut down on clutter. Do you organize your code as precondition, work, postcondition?  I find that helps me keep things neat.

Also make sure your edge cases need to be handled. The fewer assumptions your code checks the more flexible it is when things change.  A function should only check things it needs to get the job done, unless it is "border guard" code that needs to do user input validation.

Title: Is smarter software necessarily bigger?

Body:
This is kind of a vague question so I apologize in advance.

When software is "smarter", I tend to interpret that as really just saying that it covers more edge cases.  First of all, is this correct?

Assuming it is, does this mean that the software is full of if/switch statements to make sure input is handled properly, therefore making it "smarter"?

This thinking makes me feel like the code would end up bloated and messy.  I'm running into a point where I'm wanting to handle these edge cases, but I don't want to bloat my code merely overlooking some best practice. What am I missing?


答:
When software is "smarter", I tend to interpret that as really just saying that it covers more edge cases. First of all, is this correct?

Sometimes, yes. Generally, not so much.

Consider a spell checker. A "smarter" spell checker might include suggestions for correction. It might get smarter yet to detect typos by transposed letters that are physically close on a keyboard. These don't check any extra edge cases, they do more work to provide better results.

Assuming it is, does this mean that the software is full of if/switch statements to make sure input is handled properly, therefore making it "smarter"?

Very rarely. More often a different algorithm is used which solves "harder" variants of the problem or at least provides better results at the expense of "easy" problems or via time/resource consumption.

I'm running into a point where I'm wanting to handle these edge cases, but I don't want to bloat my code merely overlooking some best practice.

Sometimes edge cases require this sort of conditional logic, but often they can be dealt with via a more general solution, or a more general view of your data.

It's not a guarantee that a solution for A and B is necessarily less complex than a solution for A, B and C.

Title: Is smarter software necessarily bigger?


答: No! smarter software can simplify how a problem is approached and solved, leaving fewer 'edge cases'. Less can be more.</p>

Title: Is smarter software necessarily bigger?


问:
Is it practical to write exit codes in a script where the outcome is more complex than success/fail?
Where I work, we're in the process of automating a lot of tasks that currently need to be run manually by an IT person to determine if the next task can be performed (the second task depends on certain outcomes of the first task). We're ending the first phase of our script automation process, having reworked the first task to have better support for logging, error handling and even emailing a report, but we will not be able to get to reworking the second task right away so it will remain in its current state of manual use.

In the meantime, it has been suggested that we implement exit codes into the first task so that we can simply chain the second task, in its current state, on a successful first task. The only issue here is that the first task is a little more complicated than just success/fail. There are many different parts that can pass that will allow the second task to be run a certain way. Now I know none of this is impossible with exit codes. We could take the time to implement the first task to return all these different exit codes so that the second task can be run in a semi-automated fashion based on these exit codes as a temporary solution to making the entire process automated until we have the time to go in and rework the second task the correct way.

My question is, is it practical to take the time to implement exit codes into a script as a temporary solution to a larger problem where the script is more complex than success/fail?

Note: The exit codes will take some time to implement as our rework of the first task was not designed to return exit codes (it is a self-contained script that handles its own logging and error reporting).

Edit: It is a given that we have to go back and rework the second task in a way that the two tasks can be run independently of each other (their outcomes/state will be shared through a database).

Edit: In general, I know it is useful to have exit codes, but my current situation involves spending a considerable amount of development time to go back and implement the exit codes properly (again because the outcome of the script is quite complex with many different levels of success/fail), when they aren't part of the overall solution, but a temporary hack to our new system in order to "fake" it as a completely automated system until we can actually complete the rework. I guess it's more of a "Is the time spent to implement this hack, while not a complete solution, worth it if we have to go back and undo the hack later?" question.

答:
I would stick to the exit codes of task1 giving pass or how it failed info. No more.

Task2 should have a pre-task written that parses the output logs etc of task1 amongst other sources to make the decision of if task2 should run (and maybe what it should run on)..

With a bit of practice, you can keep edits to task1 and task2 to a minimum (or no changes at all). That would be re-use but in a modified flow, so the flow with the task2 pre-condition tester would still need testing.


问:
How to design (just the outline) an enterprise class PHP application
For the last year or so, I have been working on a very large application. I am currently on version 17 of it, and every time, I start over with some of the code from before. But now, this is starting to become unmanageabley large.

When I do the design for the application, I generally start with a Word document, outlining all the classes, with the functions, descriptions for each, their dependencies, default configuration data, and how each component augments the rest of the application. But with that method, within a few hours, I can easily reach 20-30 pages of documentation, and the nice simple outline of the software because so complex in itself, using that as the template to write the code to becomes difficult.

So, now, I am trying to describe the application in an XML format, built on an XSD that contains the structure of how the classes will be laid out. But, this is also demonstrating its problems.

At this stage, everything ahead of the base application has been designed (the database er diagrams, the functionality, etc), but the main problems lies in the design of the underlying software that runs it all.

So, can anyone recommend what path I should go down, either with specific ways to lay out a Word document for easy reading, an XML pattern that would do the same, or some other software package that can do this for me and help guide me through the development?

Any help would be greatly appreciated, mainly because once this part has been cracked, my application can finally be built and completed.

Thanks

答:
Think of how you can make it smaller!
Chuck stuff!
Prioritise features and only plan highest priority stuff. Implement that minimum. Getting something small but working might well change all your plans anyway.</p>


答:
There are two issues here - one is a programming problem, and one is a business problem. For the second one, asking programmers about business analysis is about as good advice as you can get from your local bus driver; which is to say it may be good, or terrible, but you aren't asking experts so assign no inherent weight to any of it. (As an aside, one of my bus drivers often gives me good ideas.)

But as for a programming problem, the downside is that it seems most people don't like the idea to start with. There's lots of good reasons for this, but they aren't really important here. Sadly, we are also in some ways a terrible group of people to ask, because by virtue of our position and knowledge most of us are pretty darn good at pirating software to the point that we think it pointless to try to implement trial measures at all!

The fact is, your core issue is a business analysis and sales experiment problem, and there is no answer save from getting to know your customers and experimentation. It doesn't sound like you already have a big pool of customers to talk with about their product sales pipeline and how you can implement trial software to improve it, so one must understand that we are now in a position of stabbing blindly in the dark. The first step to working in a dark room is know you are in one!

So, start somewhere. The goal is not the right answer, because I can only 100% guarantee one thing - you aren't going to start with the right answer. But start we must.

Give Your Customers a KISS

Also, "keep it simple, stupid." Or, from a programming methodology, "try the simplest thing that could possibly work." Then go from there.

So, when installing get a date. Store it. Get your data on installs and usage, and bask in the warmth that data analysis can bring. Disable whatever part of the software you want when the trial expires - I suggest if (trial_expired()). Then adjust.

First of all, get good data. Are you expecting to provide updates in the future for your software? Then if someone tries to beat v1.0, don't worry about it.

The easiest thing is uninstall the software, then reinstall it. New trial period (because your software deleted that old date). Do you care? If v1.0 is soon to be updated, then I strongly suggest you get a way to find out if this happens - but don't try to stop them (yet). It's like people who take 2 mints instead of 1 - it's just a mint, let it go. They probably weren't going to pay you for it (yet), anyway.

How? Well, in Windows this was usually done by shoving random orphaned keys in the registry and weirdly named files in various common installation directories. Your installer would explicitly pretend they didn't exist and just leave them there. The level of computer sophistication this requires to defeat is vastly more than uninstalling.

But if you don't try to stop someone from reinstalling, then you get data you are going to need. They aren't robbing your store, here - they are giving you a valuable opportunity to study a potential customer. Use it to tailor your marketing, software help prompts, email campaigns, 'special offers'. I'd try detecting the event and then, a day later, sending them a key they could enter into the program to extend their trial until next month. You might find a method that turns them into paying customers, or not; no way of knowing ahead of time!

This seems trivial, but lets face it - do you really need anything more than that? If you are collecting data, that's worth money to you. You'll probably want to spend time on making sure emails are good, designing in-software messaging that you can update to guide new users (invisible sales pitches, really), rewriting your app blurb, hammering out bugs that would prevent any sane person from buying your software in the first place, etc.

But the key here is you are communicating honestly and clearly to all potential customers - if you want this, you should pay us. Just because you are being (invisibly) magnanimous doesn't mean this is freeware - you are just going to be smart about it and not drive away customers because they haven't sealed the deal in the first two weeks.

If you think about it, these people are coming in to your store to really look over your product. They are taking a test drive, yet it costs you (nearly) nothing. No successful store got that way by driving out customers who weren't yet ready to buy! Yet we all know if you can get something for free, forever, why pay? So use the best of both worlds.

With each step you take you will be working a filter, and if your software is good you WILL be making conversions with every step. My simple suggestion:

1) 14 day free trial

2) Extend the free trial, no questions asked

3) Offer to extend the free trial again, if they'd be so kind to fill out a short form that communicates to you their opinions of your software so far.

4) Are you sure these people who are still actually using your software won't consider buying it? Find a way to entice them - or at least try to squeeze more info out of them on what you could do to get others to buy. Maybe allow them to 'request' an extension through a form, which your sales staff will kindly grant regardless and then use the info to see if they can deal with any objections they might have to buying your software.

What if this user is evaluating it for use in their entire department? If the budget meeting is next month, do you really want them to be unable to use the software until then?

5) Maybe you cut them off now...and maybe you invite them for a special offer a week later at a discount. Maybe not. Maybe you offer to extend to give a final extension.

These people don't owe you money, so treat them as potential future customers - not thieves, freeloaders, or people who need to pay their bill or get their service turned off. Everyone hates bill collectors, so don't act like one.

Programmatically, let's face it - this isn't actually hard. Use orphaned files to keep track of dates. If you have to have a valid account like through iTunes, this tracking is way easier. If it isn't required, then I would generally suggest you not require it for a first install - never turn people away from the first version because they don't want to fill out a stupid form. People hate forms! And they don't know your software, so why 'pay' to fill out a form if they don't even know if your app works?

On step 2, I'd get a signup/email to extend. Again, programming it is trivial.

3) After 30 days I'd probably require some kind of 'phone home' behavior. If people are going to crack that - like they do - congratu-friggin-lations! You must be getting pretty popular. But don't worry, if this isn't a video game people probably don't care enough to bother, so just change your code in the next version and make them go back to the drawing board.

TL;DR;

#1 Don't solve a problem you don't really have (you aren't Adobe, yet - DRM can be simple and effective if you don't over-think it).
#2 Don't ask a programmer when you need to ask a marketer, business analyst, or salesman.
#3 Treat your customers as people who might give you a living, not as people who owe you money, and especially not as thieves.
#4 DRM is really, really, easy. Just don't think you are going to stop people from using your software who will almost certainly never, ever, ever give you money...at least, not today.

I have bought software I've pirated, years later. So don't piss off future customers needlessly, either.


答:
I would have written a shorter letter, but I did not have the time.

~ Blaise Pascal

Smarter software is not necessarily bigger, but in most cases it is.

In the best case, smarter software simply doesn't allow you to follow an error path.  By controlling what conditions can occur, the total number of cases to be coded for can be reduced.

For example, three flags A, B, C provides up to 8 permutations.  If you only need 3 of those 8 permutations and the software prevents the other 5 from being selected, then you have written less code.  So the smarter application can be smaller.

But edge cases crop up all the time, and it can be difficult to control the permutations associated with those edge cases.  So the application needs more conditional checks and error path code.  In which case, smarter does mean bigger.

I opened my answer with Pascal's quote because it really captures the conundrum your questions presents.  If given the time, you'll have less code providing more functionality.  But that also requires or implies a solid understanding of the problem and the ability to find an eloquent solution.  Frequently, we run out of time to create the eloquent solution and our application codebase grows a proportionality larger amount as a result.

Title: Is smarter software necessarily bigger?


问:
Python decorators and Lisp macros
When looking Python decorators someone made the statement, that they are as powerful as Lisp macros (particularly Clojure).

Looking at the examples given in PEP 318 it looks to me as if they are just a fancy way of using plain old higher-order functions in Lisp:

def attrs(**kwds):
    def decorate(f):
        for k in kwds:
            setattr(f, k, kwds[k])
        return f
    return decorate

@attrs(versionadded="2.2",
       author="Guido van Rossum")
def mymethod(f):
    ...
```

I haven’t seen any code transforming in any of the examples, like described in Anatomy of a Clojure Macro. Plus, Python’s missing homoiconicity could make code transformations impossible.

So, how do these two compare and can you say they are about equal in what you can do? Evidence seems to point against it.

Edit: Based on a comment, I’m looking for two things: comparison on “as powerful as” and on “as easy to do awesome things with”.

答:
A decorator is basically just a function.

Example in Common Lisp:

(defun attributes (keywords function)
  (loop for (key value) in keywords
        do (setf (get function key) value))
  function)
```

<p>In above the function is a symbol (which would be returned by <code>DEFUN</code>) and we put the attributes on the symbol's <em>property list</em>.</p>

<p>Now we can write it around a function definition:</p>

<pre class="lang-lisp prettyprint-override"><code>(attributes
  '((version-added "2.2")
    (author "Rainer Joswig"))

  (defun foo (a b)
    (+ a b))

)
</code>```

If we want to add a fancy syntax like in Python, we write a reader macro. A reader macro allows us to program on the level of s-expression syntax:

(set-macro-character
 #\@
 (lambda (stream char)
   (let ((decorator (read stream))
         (arg       (read stream))
         (form      (read stream)))
     `(,decorator ,arg ,form))))
```

<p>We then can write:</p>

<pre class="lang-lisp prettyprint-override"><code>@attributes'((version-added "2.2")
             (author "Rainer Joswig"))
(defun foo (a b)
  (+ a b))
</code>```

The Lisp reader reads above to:

(ATTRIBUTES (QUOTE ((VERSION-ADDED "2.2")
                    (AUTHOR "Rainer Joswig")))
            (DEFUN FOO (A B) (+ A B)))
```

<p>Now we have a form of <em>decorators</em> in Common Lisp.</p>

<p><strong>Combining macros and reader macros.</strong></p>

<p>Actually I would do above translation in real code using a macro, not a function. </p>

<pre class="lang-lisp prettyprint-override"><code>(defmacro defdecorator (decorator arg form)
  `(progn
     ,form
     (,decorator ,arg ',(second form))))

(set-macro-character
 #\@
 (lambda (stream char)
   (declare (ignore char))
   (let* ((decorator (read stream))
          (arg       (read stream))
          (form      (read stream)))
     `(defdecorator ,decorator ,arg ,form))))
</code>```

The use is as above with the same reader macro. The advantage is that the Lisp compiler still sees it as a so-called top-level form - the *file compiler treats top-level forms specially, for example it adds information about them into the compile-time environment. In the example above we can see that the macro looks into the source code and extracts the name.

The Lisp reader reads the above example into:

(DEFDECORATOR ATTRIBUTES
  (QUOTE ((VERSION-ADDED "2.2")
           (AUTHOR "Rainer Joswig")))
  (DEFUN FOO (A B) (+ A B)))
```

<p>Which then gets macro expanded into:</p>

<pre class="lang-lisp prettyprint-override"><code>(PROGN (DEFUN FOO (A B) (+ A B))
       (ATTRIBUTES (QUOTE ((VERSION-ADDED "2.2")
                           (AUTHOR "Rainer Joswig")))
                   (QUOTE FOO)))
</code>```

Macros are very different from reader macros.

Macros get the source code passed, can do whatever they want and then return source code. The input source does not need to be valid Lisp code. It can be anything and it could be written totally different. The result has to be valid Lisp code then. But if the generated code is using a macro too, then the syntax of the code embedded in the macro call could again be a different syntax. A simple example: one could write a math macro which would accept some kind of mathematical syntax:

(math y = 3 x ^ 2 - 4 x + 3)
```

<p>The expression <code>y = 3 x ^ 2 - 4 x + 3</code> is not valid Lisp code, but the macro could for example parse it and return valid Lisp code like this:</p>

<pre class="lang-lisp prettyprint-override"><code>(setq y (+ (* 3 (expt x 2))
           (- (* 4 x))
           3))
</code>```

There are many other use cases of macros in Lisp.

Title: Python decorators and Lisp macros

Body:
A decorator is basically just a function.

Example in Common Lisp:

(defun attributes (keywords function)
  (loop for (key value) in keywords
        do (setf (get function key) value))
  function)

In above the function is a symbol (which would be returned by DEFUN) and we put the attributes on the symbol's property list.

Now we can write it around a function definition:

(attributes
  '((version-added "2.2")
    (author "Rainer Joswig"))

  (defun foo (a b)
    (+ a b))

)

If we want to add a fancy syntax like in Python, we write a reader macro. A reader macro allows us to program on the level of s-expression syntax:

(set-macro-character
 #\@
 (lambda (stream char)
   (let ((decorator (read stream))
         (arg       (read stream))
         (form      (read stream)))
     `(,decorator ,arg ,form))))

We then can write:

@attributes'((version-added "2.2")
             (author "Rainer Joswig"))
(defun foo (a b)
  (+ a b))

The Lisp reader reads above to:

(ATTRIBUTES (QUOTE ((VERSION-ADDED "2.2")
                    (AUTHOR "Rainer Joswig")))
            (DEFUN FOO (A B) (+ A B)))

Now we have a form of decorators in Common Lisp.

Combining macros and reader macros.

Actually I would do above translation in real code using a macro, not a function.

(defmacro defdecorator (decorator arg form)
  `(progn
     ,form
     (,decorator ,arg ',(second form))))

(set-macro-character
 #\@
 (lambda (stream char)
   (declare (ignore char))
   (let* ((decorator (read stream))
          (arg       (read stream))
          (form      (read stream)))
     `(defdecorator ,decorator ,arg ,form))))

The use is as above with the same reader macro. The advantage is that the Lisp compiler still sees it as a so-called top-level form - the *file compiler treats top-level forms specially, for example it adds information about them into the compile-time environment. In the example above we can see that the macro looks into the source code and extracts the name.

The Lisp reader reads the above example into:

(DEFDECORATOR ATTRIBUTES
  (QUOTE ((VERSION-ADDED "2.2")
           (AUTHOR "Rainer Joswig")))
  (DEFUN FOO (A B) (+ A B)))

Which then gets macro expanded into:

(PROGN (DEFUN FOO (A B) (+ A B))
       (ATTRIBUTES (QUOTE ((VERSION-ADDED "2.2")
                           (AUTHOR "Rainer Joswig")))
                   (QUOTE FOO)))

Macros are very different from reader macros.

Macros get the source code passed, can do whatever they want and then return source code. The input source does not need to be valid Lisp code. It can be anything and it could be written totally different. The result has to be valid Lisp code then. But if the generated code is using a macro too, then the syntax of the code embedded in the macro call could again be a different syntax. A simple example: one could write a math macro which would accept some kind of mathematical syntax:

(math y = 3 x ^ 2 - 4 x + 3)

The expression y = 3 x ^ 2 - 4 x + 3 is not valid Lisp code, but the macro could for example parse it and return valid Lisp code like this:

(setq y (+ (* 3 (expt x 2))
           (- (* 4 x))
           3))

There are many other use cases of macros in Lisp.

ContentLicense: CC BY-SA 4.0


答:
Whatever you do, make sure you test what happens beyond the expiration date very carefully.   I once worked for a company which distributed software with a trial scheme much like the one you describe. The difference was that the expiration was a fixed date in the future.

We dropped the scheme immediately after we got a ton of calls from angry customers when their legitimately purchased versions also stopped working on that date.


问:
Feature vs. Function
Often I hear PMs (Project Managers) talk about feature and function. And I'm just so puzzled to differentiate them. Sometimes I think of a feature to be equivalent to a user story. Something like "As a user, Bob should be able to see a list of his payments", and they call it a feature. Sometimes it gets as big as a subsystem, something like "the ability to send SMS via web application". Function on the other hand sometimes gets as small as a task, "implementing digit grouping for number inputs", while there are cases when it gets as big as a whole CRUD operation.

My question is, how can we differentiate feature from function?

答:
For a PM, "Function" is purpose and "Feature" is a product behavior that a user can interact with. However people often get the two backwards (which I think is the case in your question).

Getting me from place A to place B is a key function of a car. Its the reason (purpose) it exists.  The steering wheel is a feature, as is the gear stick. The driver interacts with multiple features to achieve the function of getting somewhere.

"Function" here should not be confused with a programming language function (method) which talks about implementation of a feature software.  That is most likely not what a PM would be talking about when they refer to "Features and Functions".

There is not a nice hierarchy to functions and features, as one feature may be used to support multiple product functions.

Title: Feature vs. Function


问:
How to explain to non-programmer to build my Visual Studio source code in "Release" mode?
I'm writing documentation for some software that I wrote.  Specifically, I'm writing a guide to installing the software.  I'm delivering the source-code to my client, so I expect that they will want to be able to build from source.

I explain to open the solution in Visual Studio 2010 and to right-click on the project and select "Publish".

There doesn't seem to be a clear and straight-forward way to explain that they must build it in "Release" mode or what the simplest way to explain how to do that is.

What's the best way to explain this?

Edit: In response to the comments asking me to be more specific, on my setup of Visual Studio 2010, there is a drop-down list next to the green icon that starts the debugger.  It doesn't have any label next to it.  That's how I'm familiar with changing the setting myself, but I don't want to write in my documentation, "Click on the drop-down list next to the green button and select "Release".  There's got to be a better way.  I am particularly concerned that if I get in wrong, it could result in someone changing the setting at the project level instead of the solution level.

答:
I would just add a command line script (*.bat) to your package, calling VS with commands like

```<code>set VSPATH=C:\Program Files (x86)\Microsoft Visual Studio 10.0
set DEVENV="%VSPATH%\Common7\IDE\devenv.exe"
%DEVENV% YourProgramsSolutionFile.sln /build "Release" /out Build.log
</code>```

This script can be run by a simple double-click, which should not be too hard to  explain to anyone else, programmer or not.

Actually, I find it very cumbersome to force a non-programmer to install Visual Studio on his machine only to let him compile your program. So when you want to deliver a package to someone else, why don't you provide a setup routine for an already compiled binary additionally to the source code?

Here is a related article you might find interesting: http://www.codinghorror.com/blog/2007/10/the-f5-key-is-not-a-build-process.html

Body:
I would just add a command line script (*.bat) to your package, calling VS with commands like

set VSPATH=C:\Program Files (x86)\Microsoft Visual Studio 10.0
set DEVENV="%VSPATH%\Common7\IDE\devenv.exe"
%DEVENV% YourProgramsSolutionFile.sln /build "Release" /out Build.log

This script can be run by a simple double-click, which should not be too hard to  explain to anyone else, programmer or not.

Actually, I find it very cumbersome to force a non-programmer to install Visual Studio on his machine only to let him compile your program. So when you want to deliver a package to someone else, why don't you provide a setup routine for an already compiled binary additionally to the source code?

Here is a related article you might find interesting: http://www.codinghorror.com/blog/2007/10/the-f5-key-is-not-a-build-process.html


问:
How are the forwarding of requests normally managed in the Chain of Responsibilty pattern?
I was just experimenting with the Chain of responsibility design pattern, implementing my own version.

I'm currently reading Design Patterns, but I'm not really sure whether DP tells to stop the forwarding of the requests when a single action is accomplished, or just continuing to the end of the chain.

What I'm interested in is how this feature of the COR pattern is managed in most of cases. In my example below, I let the forwarding continue to the end of my chain.

I don't think you need any source, but you can anyway find it here.

If I missed some DP paragraphs telling about this, please provide me its location!

答:
in this example there is very distinct line drawn that one thing permanently handles the request, and only if that thing is unable to handle it does the next in line even get a chance to look at the request.

```<code>public override void ProcessRequest(Purchase purchase)
{
  if (purchase.Amount < 10000.0)
  {
    Console.WriteLine("{0} approved request# {1}",
    this.GetType().Name, purchase.Number);
  }
  else if (successor != null)
  {
    successor.ProcessRequest(purchase);
  }
}
</code>```

http://www.dofactory.com/Patterns/PatternChain.aspx#_self2

i have a feeling there is more richness and dynamicism to be had here.  like you could have one of these handlers, that had a certain threshold where it would allow the next in line to 'bid' and then make a decision.  you'd really have to write such logic, and keep in organized as the base pattern doesn't really address this kind of complexity.

i'd say that such rich patterns would tend towards an overall Reponsibility Driven Design  instead of a cookie cutter Chain of R.

Body:
in this example there is very distinct line drawn that one thing permanently handles the request, and only if that thing is unable to handle it does the next in line even get a chance to look at the request.

public override void ProcessRequest(Purchase purchase)
{
  if (purchase.Amount < 10000.0)
  {
    Console.WriteLine("{0} approved request# {1}",
    this.GetType().Name, purchase.Number);
  }
  else if (successor != null)
  {
    successor.ProcessRequest(purchase);
  }
}

http://www.dofactory.com/Patterns/PatternChain.aspx#_self2

i have a feeling there is more richness and dynamicism to be had here.  like you could have one of these handlers, that had a certain threshold where it would allow the next in line to 'bid' and then make a decision.  you'd really have to write such logic, and keep in organized as the base pattern doesn't really address this kind of complexity.

i'd say that such rich patterns would tend towards an overall Reponsibility Driven Design  instead of a cookie cutter Chain of R.


答:
Not java, but I would recommend reading Eric Lippert's articles about immutability.  This issue isn't as clear cut as you might think for java.  There is no inherent performance impact in choosing one over the other, although it can impact performance depending upon your exact usage.

The key concept is whether and how an object can be changed.


问:
Is there a name for web applications that do most of the navigation on the client side?
Does the web industry have any standard or common name that refers specifically to web applications that don't use the conventional window-HTTP-navigation model, instead relying on mostly or wholly on DOM manipulation?

These applications usually have the following attributes:

load an application frame from the server once (or infrequently)

use a combination of Ajax requests, DOM modifications and history manipulation (via web fragment or pushState) to change state after that (while preserving reloadability)

do not typically trigger new conventional location bar navigation events (window- or frame-level HTTP requests)

most likely, present UIs that are highly interactive with a combination of dialog boxes, overlay layers, infinite scrolling, etc.

Examples:

Facebook

Twitter

Gmail

USAToday

Popular counterexamples, still relying mostly on traditional models

YouTube (some navigation is done this way, but not enough)

cnn.com

I'm interested in names for this type of web application specifically.  It feels like something I must have heard already, but I can't think of anything specifically.

These seem too broad:

Web application (could mean anything)

AJAX application (could mean anything)

答:
One trait of these applications: They stay on one page.

SPA = Single Page App

A single-page application (SPA), also known as single-page interface (SPI), is a web application or web site that fits on a single web page with the goal of providing a more fluid user experience akin to a desktop application.

In an SPA, either all necessary code – HTML, JavaScript, and CSS – is retrieved with a single page load, or the appropriate resources are dynamically loaded and added to the page as necessary, usually in response to user actions. The page does not reload at any point in the process, nor does control transfer to another page, although modern web technologies (such as those included in HTML5) can provide the perception and navigability of separate logical pages in the application. Interaction with the single page application often involves dynamic communication with the web server behind the scenes...


答:
If you aren't getting interviews then it could be that your 3½ to 4 years experience isn't seen as sufficient for a senior developer role. You should look at revising your CV to highlight your strengths. You should also look at applying for more relevant roles - perhaps at a more junior level.

If you are getting interviews then it could be down to anything.

You might come over as too nervous/shy or you might come over as too abrasive/aggressive
or ....

Ultimately only the interviewer can answer this question and they might not even be able to articulate the answer themselves - they just "know" you won't fit in.

Title: Why I'm not selected in an interview?

Body:
I'm working in development for 4 years, and 3.5 in PHP - why I don't seem to be able to be selected in an interview.

I want to know what special things the interviewer wants to see in candidates - for senior PHP developer roles.

Interviewer asks me 10 questions and I'm able to answer only 5. Does selection depend on these things? It doesn't mean that I can't solve the problem, I can google the question, I can ask on forums. Why don't they understand that a man can't remember all the answers for each and every question? Especially programming ones.

Please advise.


答:
A large percentage of spam is sent from botnets using barely-compliant SMTP implementations. If you implement a mail acceptance policy like https://www.nearlyfreespeech.net/about/email, what is left is still annoying, but requires far less effort to scan.  (If Microsoft did this, however, the spammers would adapt, so I hope they don't.)

If you are concerned about the confidentiality of your message content, make sure it is encrypted before it leaves your (trusted) computer. And delete it from the server as soon as possible, even if it is encrypted. See https://ssd.eff.org/3rdparties to learn how little protection your messages have on a machine you don't own.

OT, but funny: most of the spam that hits my server uses SomeRandomAddress@outlook.com as the sender.

Title: Is it possible to do decent spam filtering without scanning the contents of emails?

Body:
I don't have much knowledge of the subject but as I know, when servers receive an email they have two sources of data to classify it as SPAM or not. The contents of the message (subject + body) and the metadata that goes with it (from who / to who / server that sent the message, etc).

I know you can do basic filtering by blacklisting emails list and other sorts of metadata. But is it possible to do decent spam filtering without checking the contents of a message? Defining 'check the contents' as using any function that relies on data found on the body/subject of the message to classify it as spam or not spam.

Edit: The reason I ask for this because of the "scroogled" campaign where Microsoft accuses Google of scanning the contents of emails for advertising purposes, and I think that they do the same for spam prevention purposes. So I asked them and they said:

We have tools and system set up to filter spam emails to and from
  Outlook.com email accounts. However, we are not allowed to disclose
  how these spam filters work for security purposes.

ME: So can you assure me that no content from my personal email is
  being analysed and cross referenced with other data in any way?

...In response to your question, its a yes, we can assure you that.


问:
Naming boolean field that is a verb
In Java, by convention getter and setter for boolean fields will be isField() and setField(). This works perfectly fine with field names that are adjectives like active, visible, closed, etc.

But how do I name a field that has meaning of a verb, like haveChildren? Add “_ing” to the verb (havingChildren), maybe?

To clarify, I don't have control of the method names (getter and setter) as they are auto-generated by the IDE. So what I need is an appropriate field name so that when the IDE generate a getter for it, it make senses. For example, hasChildren is a perfect field name, but when the IDE generate the getter for the field it would be isHasChildren. How do I solve this?

答:
I would suggest renaming the field to parent so that the getter will be isParent and setter will be setParent.

You can also try childPresent for the variable name and isChildPresent and setChildPresent as the getter and setter.

Title: Naming boolean field that is a verb


问:
PHP high traffic default page
I have a php website that will be experiencing high levels of traffic in a few weeks. We scaled the servers to accept the traffic, but want some sort of fallback page in the event that something happens.

Does anyone know of an easy way to implement this?

My initial thought is to check for the headers when the page is requested, but don't quite understand if that will even matter. Does the user even receive the initial http headers, if they get a 504 Gateway Timeout error?

Would something like checking the result of: var_dump(http_response_code()); in a conditional even reach the client?

答:
For a better answer we certainly could use some more information, for example:

What web server are you using?

How are you balancing connections to them?

Do you have any layer of cache?

What kind of data do you send clients? Can it be cached? It is behind an HTTPs-only protocol?

Based on the information you gave, I would discourage doing what you want to do in PHP. As you may have guessed, depending on the occasion (all workers are busy processing other requests), PHP won't even be triggered and a 504 header will be sent to the client as a response by the web server, without reaching PHP as you already expect.

I would recommend a HTTP cache layer before all requests, like Varnish. By default it will cache pages and prevent that your web servers get overloaded. In the event of that happening, you can easily configure varnish to send a response (HTML page, for example) instead of the 504 page. But if the page can be cached, than if you have more than one varnish load balanced with HAproxy (for example) you will hardly experience the problem.

Title: PHP high traffic default page


问:
is it bad that I have no html, or javascript in my php files
I have been writing my website, front-end: html, JS, jquery and css, back-end: php mysql. However my php files only contain php and mysql code. Is this a really bad thing? In what situation should PHP files contain html/javascript?? Currently my php files are just there to receive request and response with array of information. I just dont understand why people would put front-end stuff in back-end, is it for security?</p>

答:
Three questoins, three answers.  YMMV.

1. Is this a really bad thing? (that you have no  HTML or javascript in your PHP)

No, it isn't.  It's just fine to have clear separation of concerns, especially for PHP files meant to be included by other PHP files, or core navigation PHP's.

What would be bad form is if you're not including any HTML, XML, or JSON in the final responses your PHP code returns.

2. In what situation should PHP files contain html/javascript?

PHP files should include client-side language to the extent that separating out such language into their own files does not provide a reduction in labor or complexity sufficient to offset the cost of the separation itself.

For example, it's perfectly acceptable to do a block of code like the following, to parrot back the fields of a HTTP POST request as hidden <input> fields:

```<code>?><input type="hidden" value="<?php $POST('email') ?>"> <?
</code>```

3. I just don't understand why people would put front-end stuff in back-end, is it for security?

PHP is not the back-end.  The database server that your web-server connects to is the "back-end".  PHP is a front-end language designed to dynamically build HTTP responses, most of which by size and volume are HTML documents.

Body:
Three questoins, three answers.  YMMV.

1. Is this a really bad thing? (that you have no  HTML or javascript in your PHP)

No, it isn't.  It's just fine to have clear separation of concerns, especially for PHP files meant to be included by other PHP files, or core navigation PHP's.

What would be bad form is if you're not including any HTML, XML, or JSON in the final responses your PHP code returns.

2. In what situation should PHP files contain html/javascript?

PHP files should include client-side language to the extent that separating out such language into their own files does not provide a reduction in labor or complexity sufficient to offset the cost of the separation itself.

For example, it's perfectly acceptable to do a block of code like the following, to parrot back the fields of a HTTP POST request as hidden <input> fields:

?><input type="hidden" value="<?php $POST('email') ?>"> <?

3. I just don't understand why people would put front-end stuff in back-end, is it for security?

PHP is not the back-end.  The database server that your web-server connects to is the "back-end".  PHP is a front-end language designed to dynamically build HTTP responses, most of which by size and volume are HTML documents.


问:
Choosing which application instance will do the updates when dealing with multiple workstations w/o server involved?
So, I've got an interesting design problem and I honestly don't know how to tackle this.  I have an application that will be ran on a dozen of workstations.  Of those workstations, it is impossible to know at any given time how many of them will be on or using my application.  Every 4 hours of local time if any of the applications are on, they would check database and perform some changes.  The problem is that if more than one tries to do that, there will be some major complications.  So I need a way for only one application to perform the updates if more than one are running.

I was thinking of creating a file that would reside on the network drive where applications would append their workstation addresses as they're turned on and remove as they're turned off.  Every 4 hours of local time, applications would check the file and whoever is at the top would be the one to run the update.  The problem with that is that if an application is shut down in the way that it can't remove itself from the top of the list, no updates will appear from there on.

I don't have an option to put any applications to run on the server itself, besides storing files there, so that's out of question.  Does anyone know of a solution to this problem?  I can't seem to wrap my brain around it.

Edit:  What I have implemented right now is this:

```<code>        int updateTimerOffset = (Convert.ToInt32(DateTime.Now.ToString("mm")) * 60000) - 120000;

        updateTimer = new System.Timers.Timer(3600000 - updateTimerOffset);
        updateTimer.AutoReset = true;
        updateTimer.Enabled = true;

        updateTimer.Elapsed += new System.Timers.ElapsedEventHandler(PerformUpdates);
</code>```

and then down in my PerformUpdates I have some code that looks like this:

```<code>        int currentHr = Convert.ToInt32(DateTime.Now.ToString("HH"));

        if (currentHr % 4 >= 0 && currentHr >= fileNum)
        {
            // change fileNum in the file to currentHr + 4 if currentHr is not 24,
            // if it is, then make the value equal to 4
            // Update database stuff
        }
</code>```

fileNum is a number that is stored in a file on the server.

This is done on every application's start up. So, every application, unless started absolutely at the exact same second will have a difference of 2 minutes (120,000 milliseconds) plus some seconds that I didn't account for between their start ups.

What I can do is have a simple file holding a number for the target hour (fileNum). So that when the application checks it, it looks at the number to do comparison.

So let's say that it's 16:00, in which case 16 % 4 gives us 0 and it's time for an update. That application checks the file and sees that the value is 12.  16 is equal to or greater than 12.  So it changes the value to current hour (16) + 4, which is 20.

The next application's timer elapses a minute or so later, and it has 0 for its hour mod value.  So, it looks at the file and sees that value is 20, which is greater than 16, so it doesn't do anything.

What do you guys think of this solution?  It wouldn't work if there were hundreds of workstations, since chances of having both applications trying to do this at the same time are higher, but with a dozen or so workstations I can pull this off?  Unless someone has a better solution?

答:
Put an agent program on the server, and allow your client programs to initiate an update through the agent, rather than updating the database directly.  This will give you the ability to manage the clients in a way that they don't clash with each other.

For example, if one client requests an update cycle, you can set a flag on the agent program to accept update requests from other clients, but simply ignore them.  You can even send status back to the second client, saying "Thanks, but this update is already in progress."

You can use a Windows Service and WCF to build the agent, and talk to it as a WCF service from the clients.


问:
Reconstructing a tree from depth information
I have a data structure that describes a tree. Nodes are ordered, with "depth" information, and knowing the order and the depth the tree can be reconstructed. I'm not entirely sure how to describe it so I'm hoping this small example will illustrate it

```<code>node #1, depth 0 // parent: none
node #2, depth 1 // parent: #1
node #3, depth 1 // parent: #1
node #4, depth 2 // parent: #3
node #5, depth 1 // parent: #1
node #6, depth 2 // parent: #5
</code>```

(I added parent information in there for clarification. That's not part of the data structure.)

I'm trying to write an algorithm (in JS, if that's any help) that will iterate over each node and build a tree out of the data. I'm fairly recursion is the way to go but beyond that I'm not sure where to start. Any suggestions?

Edit: The way I see it, I have four cases:

Node has depth 0 (initial case)

Node has same depth as previous

Node has greater depth as previous (should only be previous.depth+1)

Node has less depth than previous

Here's my pseudo-JS-code so far:

```<code>process (nodes, 0);
process = function(nodes, i) {
  cur = nodes[i], prev = nodes[i-1]
  if cur.depth = 0 then cur.parent = null  // case #1
  else if cur.depth == prev.depth then cur.parent = prev.parent // case #2
  else if cur.depth > prev.depth then cur.parent = prev // case #3
  else // case #4... here's where I'm stuck.
  if i <= nodes.length then process (nodes, i+1)
}
</code>```

答:
Ok, some pseudocode and ugly globals for enhanced lazyness:

```<code>var tree;
var position = 0;
var list = []; // to be filled with your list before you start;

process = function(depth, pos) {
  var nodes = [];
  while(list[pos + 1].depth >= depth) {
    pos = pos + 1;
    if(list[pos].depth == depth) {
      nodes.push({some_value: value,
                  another_value: whatever,
                  children: null});
    else {
      nodes[nodes.length-1].children = process(depth + 1, pos);
    }
  };
  return nodes;
};

tree = process(0, 0);
</code>```

So, I hope I didn't mess up too many details, but the idea should work.

Body:
Ok, some pseudocode and ugly globals for enhanced lazyness:

var tree;
var position = 0;
var list = []; // to be filled with your list before you start;

process = function(depth, pos) {
  var nodes = [];
  while(list[pos + 1].depth >= depth) {
    pos = pos + 1;
    if(list[pos].depth == depth) {
      nodes.push({some_value: value,
                  another_value: whatever,
                  children: null});
    else {
      nodes[nodes.length-1].children = process(depth + 1, pos);
    }
  };
  return nodes;
};

tree = process(0, 0);

So, I hope I didn't mess up too many details, but the idea should work.


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

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

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

Have you got any personal experience to share?

答:
Most of the time a combination of two or more of the following:

collaboration problem between departments

politics... too much politics...

wrong team

unrealistic scheduling

changing scope without the appropriate methodology

missing informations

Nice book on the subject: Death March.


问:
Story Point Estimation - Component Based
I have read that story point estimation is not intended to actually tie with number of hours , but is used to identify the relative capacity. I have a java application which has a adapter layer , a service implementation layer , a DAO layer and an external connector service layer. If I am given a high level requirement , is it a good practice to a classification of story points for each layer - eg:

Adapter : small : 1 SP , medium 3 SP , Large : 5 SP , Extra Large : 8 SP
Impl : small : 3 SP , medium 5 SP , Large : 8 SP , Extra Large : 11 SP
DAO : small : 1 SP , medium 3 SP , Large : 5 SP , Extra Large : 8 SP

Is it a good way of estimation? Or should we always estimate by looking as application as whole for each change? For eg, If I have got 2 user stories , should I estimate size of user story as a whole , say 1 US takes up 5 SP and other takes 13 SP? Does component-wise breakdown make sense for story point estimation?

答:
In agile methods, there are usually two levels at which estimations are done: The level of a whole User Story and the level of the Tasks that are needed to realize a User Story.

If you are estimating on the User Story level, you should estimate the User Story as a whole, for two reasons:

If you break the story into layers/components, then that implies that somebody (presumably the product owner) has already made design decisions on how the story should be implemented. But that should not be part of a User Story. A User Story gives who needs what and why they need it, but the how is reserved to the development team that has to realize it. This is a very important difference with traditional requirement formulations that often tend to step into the how-realm.

In your proposal, a medium "story part" in the adapter layer is 3 SP, but in the service layer it is 5 SP. This difference in sizing between the layers will cause confusion eventually. The team will have to keep three or four references in their mind for how much effort corresponds with say 3 SP to account for the different scales used in the different layers.

Using different scales within one estimation should be avoided as much as possible (I would even say, at all costs), so even when the team is estimating the individual tasks of the story. The units used for task estimation don't have to match those for story estimation (you can even use hours for task estimation, because a typical task should be between 2 and 8 hours anyway), but within one estimation you should use the same units.

Suppose that storypoint estimations were used for the individual tasks, with the units per layer as you indicated in your question and a task comes up that could be implemented in either the adapter or the service layers. Just knowing that it is a medium complexity task or that it is a 5 SP task does not tell you anything, because you still have to know what layer was envisioned to implement it in when giving the estimate.