问:
Are unit tests really that useful?
I just graduated with a degree in CS and I currently have a job as a Junior .NET Developer (C#, ASP.NET, and web forms). Back when I was still in university, the subject of unit testing did get covered but I never really saw the benefits of it. I understand what it's supposed to do, namely, determine whether or not a block of code is fit for use. However, i've never actually had to write a unit test before, nor did I ever feel the need to.

As I already mentioned, I'm usually developing with ASP.NET web forms, and recently I've been thinking of writing some unit tests. But I've got a few questions about this.

I've read that unit testing often happens through writing "mocks". While I understand this concept, I can't seem to figure out how I'm supposed to write mocks for websites that are completely dynamic, and where almost everything depends on data that comes from a database. For example: I use lot's of repeaters who have ItemDataBound events etc. (again depending on data that is "unknown").

So question number 1: Is writing unit tests for ASP.NET web forms something that is done often, and if it is: how do I resolve the "dynamic environment" issue?

When I'm developing I go through a lot of trial-and-error. That doesn't mean I don't know what I'm doing, but I mean that I usually write some code, hit Ctrl F5 and see what happens. While this approach does the job most of the time, sometimes I get the feeling that I'm being a little clueless (because of my little experience). I sometimes waste a lot of time like this as well.

So, question number 2: Would you guys advise me to start writing unit tests? I think it might help me in the actual implementation, but then again I feel like it might slow me down.

答:
In my experience, unit tests are indeed very useful, when you start with them and stay with them i.e. Test-Driven Development. Here's why:

Unit tests force you to think about what you want, and how to verify that you got it, before you write the code that does it. In a TDD scenario, you write the test first. You thus have to know what the code you're about to write needs to do, and how you can verify that it successfully did so, in order to write a "red" test that you then make "green" by writing the code to pass it. In many cases this forces you to think just a little more about the algorithm you are about to write to pass this test, which is always a good thing as it reduces logic errors and "corner cases". While you're writing the test, you're thinking "how could this fail" and "what am I not testing here", which leads to a more robust algorithm.

Unit tests force you to think about how the code you are about to write will be consumed. Before I learned TDD, there were MANY times where I wrote code expecting a dependency to work one way, and then was given a dependency written by a colleague that worked a completely different way. While this is still possible with TDD, the unit test you're writing forces you to think about how you want to use the object you're writing, because it is an example usage of said object. You will then hopefully write the object in such a way that it's easy to consume, and thus to adapt if necessary (though programming to predefined interfaces is a better overall solution to this problem which doesn't require TDD).

Unit tests allow you to "code by testing". A refactoring tool like ReSharper can be your best friend if you let it. You can use it to define the skeleton of new functionality as you are defining the usage in a test.

For instance, say you need to create a new object MyClass. You start by creating an instance of MyClass. "But MyClass doesn't exist!", ReSharper complains. "Then create it" you say, with a press of Alt+Enter. And presto you have your class definition. In the next line of test code you call a method MyMethod. "But that doesn't exist!", says ReSharper. "Then create it", you repeat, with another Alt+Enter. You have, with a few key presses, defined the "skeleton" of your new code. As you continue to flesh out the usage, the IDE will tell you when something doesn't fit, and usually the solution is simple enough that the IDE or a tool that plugs into it knows how to fix it.

More extreme examples conform to the "Triple-A" model; "Arrange, Act, Assert". Set everything up, perform the actual logic you are testing, then assert that the logic is correct. Coding in this way, it is very natural to code the solution into the test; then, with a few keypresses, you can extract that logic and put it somewhere where it can be used in production code, then make small changes to the test that point it at the new location of the logic. Doing it this way forces you to architect the code in a modular, easy-to-reuse way because the units you are testing must still be accessible.

Unit tests run many orders of magnitude faster than any manual test you could think of. There is a point, very quickly met in the case of larger projects, where the time overhead of unit testing begins to pay for itself by reducing the time spent manually testing. You must ALWAYS run the code you just wrote. Traditionally, you did so manually, by starting up a large program, navigating through the UI to set up the situation you have changed the behavior for, and then verifying the results again through the UI, or in the form of data produced. If the code were TDDed, you just run the unit tests. I guarantee you if you are writing good unit tests, the latter option will be many times faster than the former.

Unit tests catch regression. Again, there have been many times before I learned TDD where I went in, made what I thought was a surgical change to a piece of code, verified that the change fixed an errant behavior (or produced a new desired behavior) in the reported situation, and checked it in for release, only to find that the change broke some other corner case in a completely different module that happened to reuse that same code block. In a TDDed project, I can write a test verifying a change I'm about to make, make the change, then run the full suite, and if all other usages of the code were TDDed and my change broke something, the tests for those other things will fail, and I can investigate.

If developers had to manually find and test all the lines of code that could be affected by a potential change, nothing would ever get done because the cost of determining the impact of a change would make making the change infeasible. At the very least, nothing would be SOLID and thus easily maintained, because you would never dare touch something that may be used in multiple places; you would instead roll your own very-similar-but-incorporating-your-minor-change solution for this one case, violating SRP and probably OCP,  and slowly turning your codebase into a patchwork quilt.

Unit tests shape architecture in a typically-advantageous way. Unit tests are tests performed in isolation from any other logic. In order to be able to unit test your code, then, you must write the code in such a way that you can isolate it. Good design decisions such as loose coupling and dependency injection thus naturally shake out of the TDD process; dependencies must be injected so that in a test you can inject a "mock" or "stub" that produces the input or handles output for the situation being tested without creating "side effects". TDD's "usage first" mentality generally leads to "coding to interfaces", the essence of loose coupling. These good design principles then allow you to make changes in production such as replacing an entire class, without requiring large masses of the codebase to be changed to adapt.

Unit tests show that the code works, instead of proving the code works. At first glance you might think that a disadvantage; surely proof is better than demonstration? Theory's great; computational and algorithmic theory is the foundation of our work. But, a mathematical proof of correctness of an algorithm is not proof of correctness of the implementation. A mathematical proof only shows that code adhering to the algorithm should be correct. A unit test shows that the code actually written does what you thought it would do, and is thus evidence it is correct. This is generally of much more value all around than a theoretical proof.

Now, all that said, there are disadvantages to unit testing:

You can't unit-test everything. You can architect your system to minimize the number of LOC not covered by a unit test, but there are quite simply going to be certain areas of the system that cannot be unit-tested. Your data-access layer can be mocked when used by other code, but the data-access layer itself contains a lot of side effects and it is typically not feasible to unit test much (most?) of a Repository or DAO. Similarly, code that uses files, sets up network connections, etc have side-effects built-in and you simply cannot unit-test the line of code that does that. UI elements often cannot be unit-tested; you can test codebehind methods such as event handlers, you can unit test constructors and verify that handlers are plugged in, but there simply is no in-code substitute for a user clicking the mouse on a particular graphical element and watching the handler be called. Reaching these boundaries between what can and cannot be adequately unit-tested is called "scraping the edge of the sandbox"; beyond that point you are limited to using integration tests, automated acceptance tests, and manual testing to verify behavior.

Many advantages of unit testing do not apply without TDD. It is perfectly possible to write code, then write tests that exercise the code. They're still "unit tests", however by writing code first, you lose many of the advantages inherent in "test-first" development: code isn't necessarily architected in a way that can be easily tested, or even used in production; you don't get the "double-check" thought process inherent in writing the test and thinking about what you hadn't been thinking about; you don't code by testing; and if you write code, manually test it and see it work, then code a unit test that fails, which is wrong, the code or the test? Your main advantages are regression prevention (you'll be alerted when code that previously passed its tests now fails) and high-speed verification versus manual testing. The loss of TDD's other advantages may tip the balance away from using unit tests at all.

Unit testing introduces an overhead. Quite simply, you're writing code to test the code you're writing. This will necessarily increase the total LOC of a development project, and yes, the LOC for tests can exceed the LOC for the actual project. Naive developers and non-developers will look at this state of affairs and say the tests are a waste of time.

Unit testing requires discipline. You have to write tests that will adequately exercise the codebase (good code coverage), you have to run them regularly (as in whenever you commit a change, the full suite should be run), and you have to keep everything "green" (all tests passing). When things break, you must fix them either by fixing code that doesn't meet expectations, or by updating the expectations of the tests. If you change the tests, you should be asking "why", and keeping a very close watch on yourself; it's incredibly tempting to simply change failing assertions to match current behavior, or simply remove failing tests; but, those tests should be based on requirements, and when the two don't match you have a problem. If these things aren't done, the tests have no value once you use each one to show the code you are actually writing works as of when you last touched the test (which was to prove your initial dev or surgical change did what you thought when you wrote it).

Unit testing requires more equipment. The usual solution to the above need for discipline, and a natural tendency of humans to get lazy and compacent, is a "build-bot" running a "Continuous Integration" software package like TeamCity, CruiseControl, etc, which performs unit tests, calculates code coverage metrics, and has other controls such as "triple-C" (coding convention compliance, a la FxCop). The hardware for the build-bot must be reasonably performant (otherwise it won't keep up with the rate of code check-ins the average team will make), and check-in procedures on the bot must be kept up to date (if a new library of unit tests is created, build scripts that run unit tests must be changed to look in that library). This is less work than it sounds, but typically requires some technical expertise on the part of at least a few people on the team who know how the nitty gritty of various build processes work (and thus can automate them in scripts and maintain said scripts). It also still requires discipline in the form of paying attention when the build "breaks", and fixing whatever caused the build to break (correctly) before checking in anything new.

Unit testing can force code to be architected in a non-ideal way. While TDD is typically good for the modularity and reusability of code, it can be detrimental to the proper accessibility of code. Objects and members, placed in production libraries, can't be private or internal if they are directly used by unit tests. This can cause problems when other coders, now seeing an object, try to use it when they should instead use something else present in the library. Code reviews can help with this, but it can be a concern.

Unit testing generally prohibits "rapid application development" coding styles. If you're writing unit tests, you're not coding "fast-and-loose". That's typically a good thing, but when you're under a deadline imposed from outside your control, or you're implementing a very small-scoped change and the stakeholder (or your boss) is wondering why all this cruft has to happen just to change one line of code, it can simply be infeasible to write and maintain the proper unit test suite. Agile processes typically help with this by allowing the developers a say in the time requirements; remember, all the salesman has to do is say "yes we can" and they get the commission check, unless the process involves the people who have to actually do the work saying "no we can't" and being paid attention to. But, not everyone's Agile, and Agile has its own limitations.

Title: Are unit tests really that useful?


问:
What are the advantages of myBatis over Hibernate?
I've done some research on my own and understand the basic concept. But some insights can only be gained through actual experience.

What are the advantages of myBatis that would make it worth learning a new framework?

In what case would you avoid using it?

答:
MyBatis is SQL centric. It heps you calling SQL statements and mapping results (tables) to object trees.

The main benefit is that it is not an ORM. It does not map tables to object so does not suffer the orm impedance mismatch. Fits well for complex or legacy databases or to use db features like stored procedures, views and so.

It is quite simple and easy to learn so fits also well for low skilled teams because there is no need to have an hibernate guru among them.

Have a look at jpetstore 6 http://mybatis.org/spring/sample.html

ContentLicense: CC BY-SA 3.0


问:
Next step after creating mock-up screens
I have created some mockup screens for my app in HTML/CSS. I have 4 screens in total.

They contain no client-side coding i.e. Javascript or jQuery.

The screens themselves are quite bland at the moment, and I realise they require some further work. Some of my plans for the app going forward are:-

Introducing client-side templating : eg Mustache/Dust.js

Add some effects and transitions using jQuery

Improve the visual look of the screens (through css and images)

I'm indecisive on the best way forward. My main aim is that I want changes to be easy to manage, and that's why I did mockup screens first as per the recommendation in the Getting Real book by 37Signals.

I'm currently in the process of gathering feedback for the mockup screens.

From a programming point of view, which of the 3 steps above, would be a good logical step forward considering my requirement of making changes easy to manage?

I should point out that i am very new to programming and development, and this is the first time i am learning programming. Some terms may not make sense to me and you may have to elaborate.

答:
Work on usability and maintainability of your templates and pages. It includes the navigation and ease of updating.

You may definitely want to consider benefits of master template technique. This will also provide consistency between pages, look and feel, and ease in maintainability.


问:
Should I charge a client for mistakes that I made?
After developing a website for a client, I've realized that the load time is too extreme, and some changes need to be made. The extreme load times are attributed to the bloated css/js frameworks that I've been using. Much of the code that was included with these frameworks is not even being used and is slowing the site load time. My plan is to get rid of the css framework and just use a bare bones responsive css framework which is only like 1kb in size, and just add only the code needed. So my question is, should I charge the client for back-stepping and fixing this mistake? </p>

答:
If the choice of framework/libraries was entirely yours, you need to own that.  Customers (especially family) don't want to pay you for the job twice.  If there was a better way to do it and you missed that, as a professional you have the responsibility to do the right thing.

There are certain assumptions about the level of quality that the client expects from any job.  For example,  suppose you had a carpenter build a flight of stairs and because of warpage in the wood, the stairs are uneven.  Since he was responsible for the wood, and stairs being level is a fair expectation, whether in writing or not, you would expect the carpenter to fix the problem and you wouldn't want to pay.

If your problem was that the app worked fine for 2000 users but not for 5000, that might be something you could argue based on contracted levels of load on the site.  From your description it sounds like a single user would have problems, and that falls back on your development choice.  I think you should just fix it and let them know you identified a performance problem and took care of it.  That will build good will which could be way more valuable then the amount you would bill for the work.


问:
Should I use switch statements or long if...else chains?
Often when I hear about the switch statement, its put off as a way to replace long if...else chains. But it seems that when I use the switch statement I'm writing more code that I would be just writing if...else. You also have other issues like keeping all variables for all calls in the same scope.

Here's some code that represents the flow I normally write (thanks to diam)

```<code>String comment;   // The generated insult.
int which = (int)(Math.random() * 3);  //  Result is 0, 1, or 2.

if (which == 0) {
    comment = "You look so much better than usual.";
} else if (which == 1) {
    comment = "Your work is up to its usual standards.";
} else if (which == 2) {
    comment = "You're quite competent for so little experience.";
} else {
    comment = "Oops -- something is wrong with this code.";
}
</code>```

Then they want me to replace that with this:

```<code>String comment;   // The generated insult.
int which = (int)(Math.random() * 3);  //  Result is 0, 1, or 2.

switch (which) {
    case 0:
             comment = "You look so much better than usual.";
    break;
    case 1:
             comment = "Your work is up to its usual standards.";
    break;
    case 2:
             comment = "You're quite competent for so little experience.";
    break;
    default:
             comment = "Oops -- something is wrong with this code.";
}
</code>```

Seems like a lot more code in a much more awkward syntax. But is there really an advantage to using the switch statement?

答:
In this case the switch statement more clearly matches the intent of the code: pick an action to take based on a single value.

The if statements on the other hand are much harder to read - you have to look at all of them to be sure what's going on. To me it's less code (even if the character count may be slightly higher) as there's less to mentally parse.

ContentLicense: CC BY-SA 2.5


问:
How to handle frequent ajax requests in shopping cart
Is it common and/or acceptable to have Ajax requests every time a button is clicked on a shopping cart page?  This is not a high traffic site. It will only have a few users at a time, like 5 max.  I'm calling it a shopping cart for lack of a better term.  The site is intended to let customers create highly customized orders, which benefits from logic being on the server instead of on the client.

I have many questions regarding the best practices in this sort of design.  Like, should I block user input until the ajax request is received?  Should I be sure to display an error message if the ajax request fails?  Should I automatically repeat the ajax request if it fails?  Are there any other considerations?

答:
It looks like you are interested in best practices to follow or just use in your case.
There are a number of written article on this subject matter, however there are few good once that combine techniques in one as well :)

Regarding your questions, i would skip the one saying "Should I automatically repeat the Ajax request if it fails?" - No, just process the failure message in user friendly way.

More readings on best practices with Ajax calls:

THE PERFECT JQUERY AJAX REQUEST

24 Best Practices for AJAX Implementations

Ajax Best Practices: Reduce and Aggregate similar XHR calls

ContentLicense: CC BY-SA 4.0


答: It's better to have something you are proud of and can use to sell yourself in the future. You can offset your own additional costs in fixing the issue as an investment into your own learning.</p>

Title: Should I charge a client for mistakes that I made?

Body: After developing a website for a client, I've realized that the load time is too extreme, and some changes need to be made. The extreme load times are attributed to the bloated css/js frameworks that I've been using. Much of the code that was included with these frameworks is not even being used and is slowing the site load time. My plan is to get rid of the css framework and just use a bare bones responsive css framework which is only like 1kb in size, and just add only the code needed. So my question is, should I charge the client for back-stepping and fixing this mistake? </p>


答:
should I block user input until the ajax request is received?

Only if user actions should be blocked.  For example, if you're updating the cart total there is no need to block.  But if the user is removing an item from the cart, you probably need to complete processing and recalculate before allowing them to manipulate something else in the cart.  To put it simply, only block user input when necessary but be sure to consider every situation where it is really necessary.

Should I be sure to display an error message if the ajax request fails?

If it will matter to the user then yes, display a user-friendly message.  For example, if removing an item from the cart fails, the user will not see their action succeed, or may see incorrect information.  That must be handled correctly with the user.  Be sure the backend properly logs the error so by the time the user reports it there's a solution.

Should I automatically repeat the ajax request if it fails?

Maybe if it fails from a timeout, but otherwise no.  No need to repeat something that will likely fail.

Are there any other considerations?

Lots! If you ask more specific questions we can give you more specific answers.  In short, I would say think of your AJAX calls just as any other subsystem with architectural, performance, maintenance and user considerations.

Title: How to handle frequent ajax requests in shopping cart

Body:
Is it common and/or acceptable to have Ajax requests every time a button is clicked on a shopping cart page?  This is not a high traffic site. It will only have a few users at a time, like 5 max.  I'm calling it a shopping cart for lack of a better term.  The site is intended to let customers create highly customized orders, which benefits from logic being on the server instead of on the client.

I have many questions regarding the best practices in this sort of design.  Like, should I block user input until the ajax request is received?  Should I be sure to display an error message if the ajax request fails?  Should I automatically repeat the ajax request if it fails?  Are there any other considerations?


问:
Integrated ads in phone apps - how to avoid wasting battery?
Considering the PCWorld review that came out in March:

Free Android Apps Packed with Ads are Major Battery Drains

...Researchers from Purdue University in collaboration with Microsoft claim that third-party advertising in free smartphone apps can be responsible for as much as 65 percent to 75 percent of an app's energy consumption...

Is there a best practice for integrating advert support into mobile applications, so as to not drain user battery too much?

...When you fire up Angry Birds on your Android phone, the researchers found that the core gaming component only consumes about 18 percent of total app energy. The biggest battery suck comes from the software powering third-party ads and analytics accounting for 45 percent of total app energy, according to the study...

Has anyone invoked better ways of keeping away from the "3G Tail", as the report puts it? Is it better/possible to download a large set of adverts that are cached for a few hours, and using them to populate your ad space, to avoid constant use of the Wi-Fi/3G radios?

Are there any best practices for the inclusion of adverts in mobile apps?

答:
I know that this could sound very time-intensive, but you could think about:

write a personal ad manager, aimed to this particular objective (energy consumption)

profile every existing ad component for energy consumption

And I really think this is not going to be wasted time.

You just have to remember that every different OS version could have a different energy policy.


问:
HTTP Response Header for a unique Request ID for REST service
For our REST service I want to send back a unique request ID with every response; useful for debugging internal projects but also for offering support to any third parties who might use the service in the future.

I have decided that I need to use a response header, since not all REST requests need to result in a response body (often lower-level REST APIs take advantage purely of status code and description), but would still need to send back this request ID.

I want to ensure, if possible, that I use an HTTP Response Header that is unlikely to be stripped out by any proxies along the way.

This could be very important since a large number of clients will likely be mobile devices with what is bound to be 'interesting' network topologies between them and our servers.

However, the same services are likely to be marketed to other businesses with their own corporate firewalls/proxies too.

Because of this I've basically chucked out the idea of using a custom response header in favour of a well-known header.

My current winning well-known header would be the ETag header, but while it's almost right, it's not quite - because an ETag is for a resource, not a request (i.e. two separate requests for the same resource will legitimately return the same ETag).  Moreover, if I do use that, it'll mean I can't do any entity-tagging for anything else.

Anyone have any better ideas?

Update

The Pragma header, it appears, could be used, but I'm having issues writing to it within the Asp.Net WebAPI.  Here's a related question on SO.

答:
I would use a standardized body and not use the header.  For example, every body can be JSON and include an ID field.  As long as it's standardized across your platform it's guaranteed to work.

I would not use a custom header because of the risk of it getting stripped.  I would not use a standard header because I don't know of one that fits perfectly (e.g. the ETag you mention is used to determine file changes and caching keys.)


问:
How can I estimate projects when I need to include a learning curve for new technology?
Sometimes, there are research and development projects where nothing is known in advance about the technology, concepts, and client. However, the manager still needs time estimates. What can I do to produce useful estimates?</p>

答:
The absolute first thing you need is some idea of the scope. The more concrete the better, but any form of requirements can be used to produce initial estimates. Customer requirements, vision and scope, and concept documents can be used early on. As the requirements and operating environment begin to become more clear, then the estimates will improve. A greater understanding of the client (especially the interfaces between the client and the developing organization), the team performing the work, the technologies to be used, the system architecture, and a detailed design will all contribute to a more accurate estimate. This is visible in the Cone of Uncertainty.

If you are using a parametric modeling tool, such as SLIM or COCOMO (Intermediate or Advanced only, as Basic doesn't account for cost drivers), then there should be adjustment factors for the unfamiliarity of the technology. As an example, COCOMO has a large number of cost drivers, including some that are specifically geared toward familiarity with the target platform as well as the language and tools being used to develop the system. SLIM also accounts for the overall experience of the development team, which should include considerations of the tools and technologies being used.

With this technique, the output of the modeling tools are typically validated because they have successfully been used to estimate previous software projects over many years in many organizations. However, the output is only as good as the input to the tool.

If you aren't using parametric models for estimation, you'll have to simply consider these factors when producing your estimates. It becomes more of a judgement call, but you can consider activities such as reading documentation, setting up the new development environment, and developing sample applications on the target platform or with the target languages.

In these instances, you will need to break down your estimates by task and be able to use your professional judgement to back it up. Hopefully, you have historical data and other concrete evidence to base your estimates on. Otherwise, it's more of an uphill battle.


问:
What's the most important, useful or enlightening thing you learnt in the last 12 months?
A lot of people in the coding community talk about continuous improvement, deliberate practice and so-on - but when they talk about their current practices it's almost like they 'sprang fully formed from the loins of Zeus' because you don't hear about how their opinions changed over time or what they learnt recently.

Every now and then though I go to a talk, or read a book, or talk to someone and they open up a bit more and I find that I learn a lot from these insights.

So, if you had to pick one thing from the last 12 months that you learnt what would it be?

答: Learning the MVVM pattern helped me become much less of a hack. </p>


问:
How to manage, in practice, licence files when combining GPL and BSD licensed code?
I am writing code that uses one library with GPL (not LGPL) license, and one with the 3-clause BSD license. Since I link to GPL-licensed library, my code will need to be GPL as well. How should I, in practice, deal with the original LICENSE.txt from the BSD-library?

(A) Can I distribute a project so that the main source code is GPL-licensed, and then some subdirectory is BSD-licensed?

(B) If I were not only to link to libraries, but to use and combine the BSD and GPL code in a more involved manner, what to do with the LICENSE.txt then?

The 3-clause BSD text tells: "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer." so apparently I should retain the copyright notice, and that list of conditions, somewhere. But then I'll also need to put the GPL license txt-file somewhere.

Further, apparently I don't need to retain the "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:" part of the BSD license text, since it only tells me to retain the other parts.

So, how, and in which text files, should I in practice organize the GPL license text and the parts of the BSD license and copyrights that I retain?

EDIT: So in case B, I would be taking 3-clause BSD licensed code, and redistributing it under GPL, which is permitted, as 3-clause BSD license is (one-way) compatible with GPL. I am just asking how to deal with the license texts and textfiles in practice.

答:
Ok, reading section 7 of GPLv3, is does allow for "additional permissions [that] apply only to part of the Program"[1]. So keeping some of the files or directories under the BSD license seems ok, since I guess the "do whatever you want" of the BSD license is an "additional permission".

Also, section 7 allows to "supplement the terms of this License with terms:" (6 point list of allowable kind of terms follows), and all of the 3 clauses (+ the disclaimer) of the BSD license are covered, so in case of mixing BSD and GPL code in a single file, maybe I'd just need to put an ADDITIONAL_TERMS.txt somewhere, containing the 3 clauses + disclaimer from the BSD license.

(To be extra precise, all the time that I have talked about the BSD license, I have meant the 3-clause license AKA "New BSD License" AKA "Modified BSD License", that I linked to in my question.)

[1] As long as a recipient of the program would be allowed to remove the additional permissions if he further redistributes. And the BSD license allows for this.


问:
Documentation degrading - how to deal with it?
Important: we have no issues whatsoever with source code documentation. This belongs to regular code audit and is kept up to date. Our problem is with developers documentation (or, "external" if you like), little blog-like tips from programmers to programmers which tend to be once written, often left behind.

We use wiki-like system to produce programmers documentation - articles wrote by programmers for programmers describing in a bit more details how particular piece of code works. Those wiki-pages usually include:

motivations behind design decisions for parts of API (for example; we did this ugly thing because this particular 3rd party library wants stuff to be done this way, because this other library ..., because ...)

explanation of how we deal with particular common tasks (for example; displaying trivial popup, which needs to reference appropriate application styles, register itself in registry component, and implement some interface in order to be automatically "scanned" by other component)

good practices (subjective as it is, we do actually write this stuff down)

environment configuration, required tools and its setup

In general, primarily stuff related to writing code that doesn't fit regular code-documentation due to its size and blog post/article-like nature.

The Problem

As far as introducing this system seemed like a good idea few months ago, nowadays I feel like it's causing more problems than it solves. For example:

people do write articles... but once code changed, wiki update rarely follows

lot of scratch articles, wrote by somebody in hurry and left like that

even though article-request usually comes from project lead, it's hardly ever verified for correctness/composition - which sometimes results in poor quality

The usual degradation. Code changed, wiki stays the same. Next time somebody looks for information, what he usually finds is bunch of outdated, low quality stuff - and is wondering what's going on, whether stuff that he found is accurate or (even worse) which parts of it are. And what was supposed to help, ends up doing the opposite.

At the moment it seems people are aware of the problem, project lead included, but apparently nobody seems to be bothered to do anything with it (or has more interesting stuff to do).

My initial thought was to throw it all into the oblivion (after I got bitten by outdated "tips" few times in a row), but I suppose that might be too extreme. Some information is worth noting and good read sometimes, but the problem is still the same: how you deal with its "up-to-dateness"? Have it linked to source code somehow (so when updated version of file is checked into, author of article gets notified that he might need to revise code/article)? Have designated person "watching over" it on daily basics? Do regular cleanups?

答:
If you are using a .net language, look at (Sandcastle) which takes the XML documentation (/// in C#) and converts it into MSDN help format.

The format includes description, comments, and has the ability to include code samples, as well as some other features.  You can output into .CHM, .HsX, .MSCH and HTML/ASP.NET formats.  The actual project is added to your solution, and built on the build server.  We have done this and deploy to a web site every release, and the consumers love it because the documentation is relevant to the release, and constantly updated.

You can also specify what to include in the documentation.  Currently we have 2 projects: one for external consumers which includes just the contracts and appropriate items (classes, enums, etc.), and one for internal developers which includes everything in the API, including private and internal flagged items.

This has become the only documentation we use, as motivations and quirks on using the API can be included in the Comments section of the documentation.  The process works well where I work.


答:
I do projects that fit that description somewhat regularly and I haven't figured this out yet! Thankfully where I work I'm given the latitude to do what I need to and not have futile time limits. The projects are not always successful and that's just a part of what the work is with so many unknowns. The company gains knowledge each time though.

Sorry that doesn't help at all.

Title: How can I estimate projects when I need to include a learning curve for new technology?

Body: Sometimes, there are research and development projects where nothing is known in advance about the technology, concepts, and client. However, the manager still needs time estimates. What can I do to produce useful estimates?</p>


问:
What pitfalls are inherent in using partial classes?
Over at this question in the comments I mentioned that I heard that partial classes are best avoided if possible.

What if any is the reason for this sentiment? Or If this is an invalid sentiment, how are the perceived detriments overcome?

答:
Partial classes are a must in .Net in my experience. For example a window in WPF starts out as a partial class since a lot of the implementation is boiler plate that is automatically generated for you.

Another case is when using Entity Framework or other code generators. It will create objects that represent things in the database. You could add your modifications to do for example adding calculated properties to the class in the generated code file but that wouldn't be ideal because whenever you modify your model the code generator would wipe out your custom features. So you should add a partial class outside of the generated code that extends it to add the features you want.

No absolute rule can be made (even this one :-)) about best practices because the problems being solved can be so different. Example: don't use GOTOs except that at the lower level the compiler/assembler code has GOTOs all over the place to implement for loops and ifs.

I'd replace the no partials rule with: if things are so complicated you think you need to move part of the code to another file give a good thought over whether you need to break things down into smaller classes. If a smaller class solution doesn't make sense go nuts with partials.


问:
Is this Hybrid of Interface / Composition kosher?
I'm working on a project in which I'm considering using a hybrid of interfaces and composition as a single thing.

What I mean by this is having a contain*ee* class be used as a front for functionality implemented in a contain*er* class, where the container exposes the containee as a public property.

Example (pseudocode):

```<code>class Visibility(lambda doShow, lambda doHide, lambda isVisible)
    public method Show() {...}
    public method Hide() {...}
    public property IsVisible
    public event Shown
    public event Hidden

class SomeClassWithVisibility
    private member visibility = new Visibility(doShow, doHide, isVisible)
    public property Visibility with get() = visibility
    private method doShow() {...}
    private method doHide() {...}
    private method isVisible() {...}
</code>```

There are three reasons I'm considering this:

The language in which I'm working (F#) has some annoyances w.r.t. implementing interfaces the way I need to (unless I'm missing something) and this will help avoid a lot of boilerplate code.

The containee classes could really be considered properties of the container class(es); i.e. there seems to be a fairly strong has-a relationship.

The containee classes will likely implement code which would have been pretty much the same when implemented in all the container classes, so why not do it once in one place? In the above example, this would include managing and emitting the Shown/Hidden events.

Does anyone see any isseus with this Composiface/Intersition method, or know of a better way?

EDIT 2012.07.26 - It seems a little background information is warranted:

Where I work, we have a bunch of application front-ends that have limited access to system resources -- they need access to these resources to fully function. To remedy this we have a back-end application that can access the needed resources, with which the front-ends can communicate. (There is an API written for the front-ends for accessing back-end functionality as though it were part of the front-end.)

The back-end program is out of date and its functionality is incomplete. It has made the transition from company to company a couple of times and we can't even compile it anymore. So I'm trying to rewrite it in my spare time.

I'm trying to update things to make a nice(r) interface/API for the front-ends (while allowing for backwards compatibility with older front-ends), hopefully something full of OOPy goodness. The thing is, I don't want to write the front-end API after I've written pretty much the same code in F# for implementing the back-end; so, what I'm planning on doing is applying attributes to classes/methods/properties that I would like to have code for in the API then generate this code from the F# assembly using reflection.

The method outlined in this question is a possible alternative I'm considering instead of implementing straight interfaces on the classes in F# because they're kind of a bear: In order to access something of an interface that has been implemented in a class, you have to explicitly cast an instance of that class to the interface type. This would make things painful when getting calls from the front-ends. If you don't want to have to do this, you have to call out all of the interface's methods/properties again in the class, outside of the interface implementation (which is separate from regular class members), and call the implementation's members. This is basically repeating the same code, which is what I'm trying to avoid!

答:
So, you're essentially using a decorator then?

Composition is about collections: eg, a grouping in a vector based app. If you can do the same thing with the group as you do with the single element (eg: resize, delete, etc), then you do composition in the sense of the composite pattern.

If you're just changing API, that's a decorator, or perhaps a Facade (albeit Facade usually hides a complex system of objects)


答:
I would focus on two areas, 1) The code.  2) None-code notes and document.

1) The code.

Try to make it self-documentation.  In the past I found that was often advised but rarely explained well, so...

Instead of this sort of pseudo code:

```<code># Routine by mdd on 7/25/2012
# processes cars for sale
a=0
col = Car.all
Collection.loop |a|
 if a.stat = 'fs' then
   a+= a.value
   call easo
  endif
end
</code>```

Do code that looks more like this:

```<code>accumulating_potential_sale_revenue = 0
cars_to_check = Car.all
cars_to_check.loop |one_car|
  if one_car.sell_status == 'for_sale'
    accumulating_potential_sale_revenue+= one_car.sale_price
    call email_about_special_offer(car)
  endif
end
</code>```

Use source control to track the 'who did what when' info.

2) The non-code

Use a wiki and markdown format to maintain this information.  Make it part of the job.  Publicize it, post it and blog it.  Set up a standard weekly or monthly meeting to review old and new stuff.  Make it a mantra that when someone asks about something the answer is given... along with the thought "should this be in the wiki for the next time someone asks?"

Title: Documentation degrading - how to deal with it?

Body:
Important: we have no issues whatsoever with source code documentation. This belongs to regular code audit and is kept up to date. Our problem is with developers documentation (or, "external" if you like), little blog-like tips from programmers to programmers which tend to be once written, often left behind.

We use wiki-like system to produce programmers documentation - articles wrote by programmers for programmers describing in a bit more details how particular piece of code works. Those wiki-pages usually include:

motivations behind design decisions for parts of API (for example; we did this ugly thing because this particular 3rd party library wants stuff to be done this way, because this other library ..., because ...)

explanation of how we deal with particular common tasks (for example; displaying trivial popup, which needs to reference appropriate application styles, register itself in registry component, and implement some interface in order to be automatically "scanned" by other component)

good practices (subjective as it is, we do actually write this stuff down)

environment configuration, required tools and its setup

In general, primarily stuff related to writing code that doesn't fit regular code-documentation due to its size and blog post/article-like nature.

The Problem

As far as introducing this system seemed like a good idea few months ago, nowadays I feel like it's causing more problems than it solves. For example:

people do write articles... but once code changed, wiki update rarely follows

lot of scratch articles, wrote by somebody in hurry and left like that

even though article-request usually comes from project lead, it's hardly ever verified for correctness/composition - which sometimes results in poor quality

The usual degradation. Code changed, wiki stays the same. Next time somebody looks for information, what he usually finds is bunch of outdated, low quality stuff - and is wondering what's going on, whether stuff that he found is accurate or (even worse) which parts of it are. And what was supposed to help, ends up doing the opposite.

At the moment it seems people are aware of the problem, project lead included, but apparently nobody seems to be bothered to do anything with it (or has more interesting stuff to do).

My initial thought was to throw it all into the oblivion (after I got bitten by outdated "tips" few times in a row), but I suppose that might be too extreme. Some information is worth noting and good read sometimes, but the problem is still the same: how you deal with its "up-to-dateness"? Have it linked to source code somehow (so when updated version of file is checked into, author of article gets notified that he might need to revise code/article)? Have designated person "watching over" it on daily basics? Do regular cleanups?

Body:
I would focus on two areas, 1) The code.  2) None-code notes and document.

1) The code.

Try to make it self-documentation.  In the past I found that was often advised but rarely explained well, so...

Instead of this sort of pseudo code:

# Routine by mdd on 7/25/2012
# processes cars for sale
a=0
col = Car.all
Collection.loop |a|
 if a.stat = 'fs' then
   a+= a.value
   call easo
  endif
end

Do code that looks more like this:

accumulating_potential_sale_revenue = 0
cars_to_check = Car.all
cars_to_check.loop |one_car|
  if one_car.sell_status == 'for_sale'
    accumulating_potential_sale_revenue+= one_car.sale_price
    call email_about_special_offer(car)
  endif
end

Use source control to track the 'who did what when' info.

2) The non-code

Use a wiki and markdown format to maintain this information.  Make it part of the job.  Publicize it, post it and blog it.  Set up a standard weekly or monthly meeting to review old and new stuff.  Make it a mantra that when someone asks about something the answer is given... along with the thought "should this be in the wiki for the next time someone asks?"


答:
One thing that doesn't seem to be touched on is the complexity of testing different types of code.

When you are dealing with stuff with simple inputs and outputs it's generally easy to unit test and if the tests are chosen with a mind to the edge cases of the code being tested they'll give you a lot of confidence that they are right.  Not writing tests for such code would be crazy.  (Note that most code that goes into libraries meets this criteria.)

However, in other cases you end up having to construct huge mocks to test because the code is playing with complex underlying data (usually a database but it doesn't have to be) or produces very complex output data (think of a routine that turns a seed value into a game level for a pretty extreme example) and unit testing isn't nearly so useful.  Covering everything in your test cases usually is a pipe dream and when you do find a bug it's almost always a case you never thought of and therefore couldn't have constructed a test for anyway.

There are no silver bullets, anything portrayed as a silver bullet isn't nearly as good as it's proponents claim but that doesn't mean it's useless.

Title: Are unit tests really that useful?

Body:
I just graduated with a degree in CS and I currently have a job as a Junior .NET Developer (C#, ASP.NET, and web forms). Back when I was still in university, the subject of unit testing did get covered but I never really saw the benefits of it. I understand what it's supposed to do, namely, determine whether or not a block of code is fit for use. However, i've never actually had to write a unit test before, nor did I ever feel the need to.

As I already mentioned, I'm usually developing with ASP.NET web forms, and recently I've been thinking of writing some unit tests. But I've got a few questions about this.

I've read that unit testing often happens through writing "mocks". While I understand this concept, I can't seem to figure out how I'm supposed to write mocks for websites that are completely dynamic, and where almost everything depends on data that comes from a database. For example: I use lot's of repeaters who have ItemDataBound events etc. (again depending on data that is "unknown").

So question number 1: Is writing unit tests for ASP.NET web forms something that is done often, and if it is: how do I resolve the "dynamic environment" issue?

When I'm developing I go through a lot of trial-and-error. That doesn't mean I don't know what I'm doing, but I mean that I usually write some code, hit Ctrl F5 and see what happens. While this approach does the job most of the time, sometimes I get the feeling that I'm being a little clueless (because of my little experience). I sometimes waste a lot of time like this as well.

So, question number 2: Would you guys advise me to start writing unit tests? I think it might help me in the actual implementation, but then again I feel like it might slow me down.


答:
What the others say: don't deal with technology first, make sure it works in theory.

For example, to improve navigation, create a user flow.

A user flow in programmers' terms is a finite state machine, with some transitions labeled as "the" main transition (also called the happy path). It is well-defined and deterministic, that is, for every action that can be taken in the respective states, there exists an output defined, and the conditions which decide what can happen are complete (eg, if there is an "if user has something in the basket", there is an accompanying "if user doesn't have anything in the basket").

Every screen is a state, and every click which does something is a transition (albeit the user might remain on the same screen). The transition always has some condition on when it can happen. Usually such screens are called Key Screens, although I add a special kind of screen called "Error Screen" for the "whoopsie" situations.

There is an abstract start state (from which there are conditions which makes the user arrive on the page, eg. google search), and one or more abstract end states (eg. some could be happy end states, some could be unsuccesful end states). Simple site abandonment isn't mentioned as an end state.

The main flow is usually organized horizontally, while the side flows (eg. error and exception handling) are organized vertically, starting from the first screen where they can go wrong. I usually highlight the main flow by having a much bolder line between them.

The main problem which designers leave out is that they don't care about non-happy issues, or it takes too much steps to achieve a goal.

Remember, a user always has a goal which (s)he wants to fulfill with the site. It can be that that goal is emotional, but sometimes it's rational - eg. Google Maps can help you reach the goal of knowing how to go from A to B, Facebook can help your emotional goal of feeling closeness to your friends, etc.

How easily this goal can be reached is a key issue, it's covered by the GOMS model (about which you can read in the Humane Interface by Raskin)

But, alas, this is not about technology, as technology doesn't matter that much. You can use a vast array of templating technologies (by master template, they mean having a 'layout' template and just modifying some content parts based on situation).

As for technology, try to solve transitions with CSS transitions instead of jQuery.

A technological next step could be to make the mock-up screens work with mock-up data, that is, to make them "live". Use any technology which fits.

Title: Next step after creating mock-up screens

Body:
I have created some mockup screens for my app in HTML/CSS. I have 4 screens in total.

They contain no client-side coding i.e. Javascript or jQuery.

The screens themselves are quite bland at the moment, and I realise they require some further work. Some of my plans for the app going forward are:-

Introducing client-side templating : eg Mustache/Dust.js

Add some effects and transitions using jQuery

Improve the visual look of the screens (through css and images)

I'm indecisive on the best way forward. My main aim is that I want changes to be easy to manage, and that's why I did mockup screens first as per the recommendation in the Getting Real book by 37Signals.

I'm currently in the process of gathering feedback for the mockup screens.

From a programming point of view, which of the 3 steps above, would be a good logical step forward considering my requirement of making changes easy to manage?

I should point out that i am very new to programming and development, and this is the first time i am learning programming. Some terms may not make sense to me and you may have to elaborate.


问:
Do you use unit tests at work? What benefits do you get from them?
I had planned to study and apply unit testing to my code, but after talking with my colleagues, some of them suggested to me that it's not necessary and it has a very little benefit. They also claim that only a few companies actually do unit testing with production software.

I am curious how people have applied unit testing at work and what benefits they are getting from using them, e.g., better code quality, reduced development time in the long term, etc.

答:
Costs: Slower to code, Learning Curve, Developer Inertia

Benefits: Generally I found myself writing better code when I tested first - SOLID wise...

But IMHO, the largest benefit I think, is reliability in larger systems that change frequently.  Good unit testing will save your butt (did mine) when you release multiple versions and can eliminate a big chunk of costs associated with manual QA processes.  It will not guarantee bug free code of course but it will catch some hard-to-predict ones.  In large complex systems, this can be a very large benefit indeed.


问:
Does mobile based (Android) development, benefit from Object Oriented Programming?
My development on Android is based on scientific programs and while I'm building these most of the code is in one or two long classes. When I come to deploy these programs I try to decouple everything and use classes and objects like I would on a Java desktop application.

However reading guide Designing for Performance | Android Developers about  Internal Getters/Setters it seems OO is not a good approach.

My question is what is best approach when designed Android applications, should I still use lots of classes with getters/setters and lots of object passing around. This seems counter intuitive thinking about the architecture of Android, but it also does not seem right to have lots of code in long classes.

I have looked at source codes from other projects and these seem to follow the OO approach.

My applications involve heavy image processing and time and performance is important.

I am more of a science researcher than a programmer so thanks in advance for any help.

答:
This is kinda nonsense. If, for example, you want 10-15% better performance, sure go NDK or drop OO design principes. But it if you want easy to write, maintainable, and easy to understand code, then ignore the performance hype.

Bottom line is performance tweaking is a job done after you build an app, not during. Droid is usually fast enough to use the standard SKD as is.


问:
UML representation of specific factory pattern
I have to create an UML class diagram from the following example code (Perl). I don't think that the standard factory pattern match in my case or I don't understand it correctly. I don't have AbstractFactory and ConcreteFactory but a single Factory.

What does this example looks like in UML class diagram?

Edit: This is only a very flat and simple example. The real application has many "Types" with totally different workflows.
The class diagramm is to get an overview over the hole structure. Not realy for internal workflow like sequence diagrams does.

```<code>package Module::Factory;
sub new { bless { type => $_[1] }, $_[0]; }
sub create {
    my( $self, $name ) = @_;
    my $object = "Module::Types::$self->{type}"->new( $name );
    return( $object );
}

package Module::Types::Test1;
sub new { bless { name => $_[1] }, $_[0]; }
sub test {
    my( $self ) = @_;
    say "Hello, $self->{name}.";
    return( $self );
}

package Module::Types::Test2;
sub new { bless { name => $_[1] }, $_[0]; }
sub test {
    my( $self ) = @_;
    say "Bye, $self->{name}.";
    return( $self );
}

# even more Module::Types::TestN packages...

package main;
foreach my $type ( qw( Test1 Test2 ) ) {
    my $factory = Module::Factory->new( $type );
    foreach my $name ( qw( World John Peter ) ) {
        my $object = $factory->create( $name );
        $object->test();
    }
}
</code>```

答:
You can draw an UML sequence diagram out of this easily, but a class diagramm won't tell you much, except for some logical errors.

Let's draw up a sequence diagram first:

Now, let's remove Factory for a moment, what do we have?

Hmm, are we sure we're missing something?

Basically all your Factory module does is, it shortens a namespace into its last part.

Also, what kind of interface is App dependent of?

it is dependent on Factory's interface of creating objects by a name

it is dependent of Test's interface, as it calls that for its actual work.

Factory is dependent of

Perl's reflection system, and

TestModule's interface.

Usually, an Abstract Factory is called an Abstract Factory, because it sits on top of an object 'family', all sharing the same interface. It can be, that a Factory pattern is used to decide between two related "families", all providing the same interface, but, for example, one being a Swing UI component library, the other being an AWT UI component library (or Motif and GTK), or a "real" implementation and a mock-up implementation for testing.

So, with this one class, it's not obvious what are you using the factory for. Are you trying to switch namespaces to a mock-up version  for testing?

You can draw your class system based on this (you see who is dependent on who and who is associated to who - dependent if knows about it, associated if has to know about it beforehand in order to be able to call) but I doubt it's the final solution.


答:
Honestly, as Nassim Nicholas Taleb writes in his book The Black Swan: 'we just can't predict'. Mainly due to the unknown-unknowns. It is generally best to communicate this very fact, the fact that you can't predict, instead of communicating an estimate.

As Taleb writes: it is better to be broadly right, than precisely wrong. So be sure to communicate the fact that you have hard times estimating, and use things like 'learning curves in new tech' as one of the arguments. This means that the range of your estimate will be big: 'this project wil cost between 100k and 500k.'

By saying such a thing, the one asking you to estimate something realizes that things are not so simple.


问:
Does unit testing lead to premature generalization (specifically in the context of C++)?

Preliminary notes

I'll not go into the distinction of the different kinds of test there are, there are already a few questions on these sites regarding that.

I'll take what's there and that says: unit testing in the sense of "testing the smallest isolatable unit of an application" from which this question actually derives

The isolation problem

What is the smallest isolatable unit of a program. Well, as I see it, it (highly?) depends on what language you are coding in.

Micheal Feathers talks about the concept of a seam: [WEwLC, p31]

A seam is a place where you can alter behavior in your program without editing in that place.

And without going into the details, I understand a seam -- in the context of unit testing -- to be a place in a program where your "test" can interface with your "unit".

Examples

Unit test -- especially in C++ -- require from the code under test to add more seams that would be strictly called for for a given problem.

Example:

Adding a virtual interface where non-virtual implementation would have been sufficient

Splitting -- generalizing(?) -- a (smallish) class further "just" to facilitate adding a test.

Splitting a single-executable project into seemingly "independent" libs, "just" to facilitate compiling them independently for the tests.

The question

I'll try a few versions that hopefully ask about the same point:

Is the way that Unit Tests require one to structure an application's code "only" beneficial for the unit tests or is it actually beneficial to the applications structure.

Is the code generalization that is needed to make it unit-testable useful for anything but the unit tests?

Does adding unit tests force one to generalize unnecessarily?

Is the shape unit tests force on code "always" also a good shape for the code in general as seen from the problem domain?

I remember a rule of thumb that said don't generalize until you need to / until there's a second place that uses the code. With Unit Tests, there's always a second place that uses the code -- namely the unit test. So is this reason enough to generalize?

答:
testing the smallest isolatable unit of an application

this is true, but if you take it too far it doesn't give you much, and it costs a lot, and I believe that it is this aspect that is promoting the use of the term BDD to be what TDD should have been all along - the smallest isolatable unit is what you want it to  be.

For example, I once debugged a network class that had (among other bits) 2 methods: 1 to set the IP address, another to set the port number. Naturally, these were very simple methods and would pass the most trivial test easily, but if you set the port number and then set the ip address, it would fail to work - the ip setter was overwriting the port number with a default. So you had to test the class as a whole to ensure correct behaviour, something I think the concept of TDD is missing but BDD gives you. You don't really need to test each tiny method, when you can test the most sensible and smallest area of the overall application - in this case the networking class.

Ultimately there is no magic bullet to testing, you have to make sensible decisions about how much and at what granularity to apply your limited test resources to. The tool-based approach that auto--generates stubs for you doesn't do this, its a blunt force approach.

So given this, you do not need to structure your code in a certain way to achieve TDD, but the level of testing you do achieve will depend upon the structure of your code - if you have monolithic GUI that has all its logic tightly bound to the GUI structure, then you're going to find it harder to isolate those pieces, but you can still write a unit test where 'unit' refers to the GUI and all the back-end DB work is mocked. This is an extreme example, but it shows you can still do automated testing on it.

A side-effect of structuring your code to make it easier to test smaller units does help you define the application better, and that allows you to replace parts easier. It also helps when coding as it'll be less likely that 2 devs will be working on the same component at any given time - unlike a monolithic app that has intermingled dependencies that breaks everyone else's work come merge time.


问:
What are the advantages of myBatis over Hibernate?
I've done some research on my own and understand the basic concept. But some insights can only be gained through actual experience.

What are the advantages of myBatis that would make it worth learning a new framework?

In what case would you avoid using it?

答:
Since the question refers to my comment, here's what I had in mind writing it.

First of all, it is derived from the context of your original question. In other circumstances I could give a different advice. The point that made me suggest MyBatis is this:

...we encountered some performance problems.

We decided to drop hibernate in favor of plain Jdbc to gain database performance...

In one of past projects, our team has been considering moving from Hibernate for the reasons like you describe. Similar to you, we were going to switch to JDBC, but colleagues from another project recommended us MyBatis. Team decided to give it a try, while keeping JDBC as a fallback option in the case if things go wrong.

At that moment, I knew nothing about MyBatis but had enough experience with JDBC to be sure it will do the job. Despite this, I had been strongly supporting idea of trying MyBatis, main reason being that per my past experience, amount of boilerplate code we would have to write with JDBC would be just daunting.

To be fair, I like JDBC for it being simple to understand, reliable and for giving good feel of control over database interaction, but the price one pays for it is really high. My fingers start aching every time I recall how much boilerplate I had to type with JDBC.

Anyway, we tried MyBatis and it worked as advertised. That's why I wrote the comment you ask about.

In case if you expect me to give a detailed overview of the technology, or somehow praise its superiority - sorry I can't do that. If I could - I'd already write that in a separate answer to your original question, instead of giving short comment. I mentioned I knew nothing about MyBatis back then - well I still have quite little knowledge of it sorry. Transition from Hibernate was done by other team members and it did not impact the code I've been working on. I only recalled key takeaways (based on which I made my comment), namely that 1) MyBatis resolved the issues we had with Hibernate, 2) it did not introduce issues of its own and 3) it allowed us to avoid writing boilerplate code I was expecting in case if we switch to JDBC. That's all.


答:
Separate major training and research time from development time. Break the project into multiple sub projects that have happy endings. Make sure you create a proof of concept after the training.

If you are new to the technology, you will never get close to the actual development time. Raise this as a risk at the beginning of the project and be generous in your estimate. This applies to core technologies you and your team are not familiar with.


问:
Choosing colors for application
What is the best way to choose colors for LoB app, i need to style TreeView, dropdown's, textboxes and a pivot grid, so i need a bunch of colors, tried Kuler but it gives only 6 colors.

So the question is how to do it without designer?

PS. It's a silverlight app.

答:
Talking as an ex-graphic designer - ask yourself carefully if you really need more than 6 colours. Using too many colours is likely to make things look like a mess. There is a reason why tools like Kuler don't suggest large numbers of colours.

If you absolutely require (which IMHO is unlikely) more than 6 then use them as base colours and make lighter/darker variations (something like this or this online tool will do this - a google for colour scheme or colour wheel and you'll find plenty of tools like this out there).

Title: Choosing colors for application


问:
Are unit tests really that useful?
I just graduated with a degree in CS and I currently have a job as a Junior .NET Developer (C#, ASP.NET, and web forms). Back when I was still in university, the subject of unit testing did get covered but I never really saw the benefits of it. I understand what it's supposed to do, namely, determine whether or not a block of code is fit for use. However, i've never actually had to write a unit test before, nor did I ever feel the need to.

As I already mentioned, I'm usually developing with ASP.NET web forms, and recently I've been thinking of writing some unit tests. But I've got a few questions about this.

I've read that unit testing often happens through writing "mocks". While I understand this concept, I can't seem to figure out how I'm supposed to write mocks for websites that are completely dynamic, and where almost everything depends on data that comes from a database. For example: I use lot's of repeaters who have ItemDataBound events etc. (again depending on data that is "unknown").

So question number 1: Is writing unit tests for ASP.NET web forms something that is done often, and if it is: how do I resolve the "dynamic environment" issue?

When I'm developing I go through a lot of trial-and-error. That doesn't mean I don't know what I'm doing, but I mean that I usually write some code, hit Ctrl F5 and see what happens. While this approach does the job most of the time, sometimes I get the feeling that I'm being a little clueless (because of my little experience). I sometimes waste a lot of time like this as well.

So, question number 2: Would you guys advise me to start writing unit tests? I think it might help me in the actual implementation, but then again I feel like it might slow me down.

答:
I want to add a new side (actually, a rather old one) to this: unit tests aren't that useful if your code is well-designed.

I know most of the programmers don't do program design anymore, I still do, and I found unit tests to be a rather time-consuming necessity to fit into a TDD culture, but so far, I have met only 1-2 minor bugs per thousands of lines of tests of my code - not just what I wrote, but what official testers wrote as well.

I guess you won't do program design anymore either - the current folks will pressure you into a mold not to do it - but perhaps it's worth to remember that unit test is a very-very low efficiency method compared to design.

This is a dijsktraian argument: unit test can only be executed against a program which is detailed enough to run.

If you draw flowcharts / state/action diagrams, sequence diagrams, object inventories (and last AND least, class diagrams) for your code before actually writing it, you'll be able to kill off most of the potentially threatening bugs just by tracing around your lines and checking your names.

Nowadays class diagrams are generated from code, containing hundreds, sometimes thousands of classes and are completely unusable - anything containing more than 15 elements is beyond human recognition.

You have to know what 10+-5 classes matter or what you do right now, and be able to check your code from multiple viewpoints, each diagram representing EXACTLY the viewpoints you're looking at, and you'll kill off thousands of bugs on paper.

Checking in a dynamic code if types are met (with just simply showing input/output types on a flowchart and connecting them with a pencil or different color),

checking if all states are handled (by checking the fullness of your conditions),

tracing the lines to make sure everything gets an end (every flowchart should be a fully-defined deterministic finite state automat, for the mathematically minded

ensuring that certain components have nothing to do with each other (by extracting all their dependencies) (good for security)

simplifying code by converting dependencies into associations (dependencies come from what classes do the member methods use)

checking names, looking for common prefixes, erasing synonyms
etc...

there's just so much easier...

Also, I found out that my applications are more useable, if they come directly from use cases... if the use cases are written well (ACTOR verb subject, Maintainer requests to open cash machine)... That

I've did code with 95+% of code coverages. Of course, I do unit tests sometimes, esp. for boundary checks in calculations, but I'm yet to meet serious regressions (serious: doesn't get wiped out in 24 hours) for not using unit tests even for refactorings.

Sometimes I don't do a single line of code for 3-4 days straight, just drawing. Then, in one day, I type in 1500-2000 lines. By the next day, they're mostly production ready. Sometimes unit tests are written (with 80+% of coverage), sometimes (in addition) testers are asked to try to break it, every single time, some people are asked to review it by looking at it.

I'm yet to see those unit tests finding anything.

I wish design-thinking would come in place of TDD... but TDD is so much easier, it's like going with a sledgehammer... designing needs thinking, and you're away for the keyboard most of the time.

Title: Are unit tests really that useful?


答:
Estimate how long it will take to do a similar project using familiar tech.
Multiply by 4.
Add some learning time.

If the estimate is too short you will look naive and arrogant.  if the estimate is too large you will look ignorant and incompetent.  Choose wisely.


问:
How to get developers to do code reviews in a timely manner
The company I work for requires all code to be reviewed by other developers before it is committed.  The members of my team are often frustrated because the other developers are too busy coding to do a review, especially if it is very long.  How do you incentivize other developers to do timely code reviews?

(We use git-svn so we are able to continue coding while waiting for a review.  However, I still find it frustrating when I have to wait a long time before I can commit my code.)

答:
Look at how facebook does it with their own app, called phabricator: http://phabricator.org/

They basically commit on a per issue basis, and for each issue, the code is shown, which is to be reviewed by someone. The code doesn't go into their main repository until the reviewer said it's ok to do so.

I guess it makes it more fun.

Also, perhaps a code should be assigned to two people: one who does it and one who reviews it.

Albeit perhaps your teammates don't believe in this review thingy.

Personally, in lack of reviewers, I used unit tests for lower-level functions and "the janitor test" for all the rest: the janitor test is called that way, because even the janitor should be able to understand your code.

I usually removed some minor parts, like block / function scope brackets, visibility notations, sometimes even types, and showed it to managers, domain experts, mates, whoever requested the code: "is this what you want?"

Also, going there personally and not leaving until reviewing is done helps.

Or, in case you're not fine with the team, or they're not fine with you, you know, "if you can' change the company, change company"...


答:
Depends, I used FPA (Function Point Analysis) most of the time, but we were into this "enterprizey web development", I mean, you know, Forbes 500 web companies.

There the task can be always divided into two parts: one, which fits FPA really well: you have input interfaces, output interfaces, internal logical files (aka. database tables / types to be exported), and you have these complex, unknown systems.

In the easy version, the complex task is a component already written, it's just hard and unknown to interface with it.

The hard version is when it needs to be written, then pilot-based estimations, COCOMO, whatever.

Two things, however, of importance:

Every kind of estimation system has to have a calibration time for your organization. You never develop alone, at least there's a customer waiting for your code (or you wouldn't be so desperate about this, writing code for your own sake). The question is not "how fast can it be developed?", but "how fast can it be developed with you all?"

Once I had a manager who read that Black Swan novel and was maniac about it. He was telling us that it's impossible to estimate, and I was doing my usual precise to +-10% estimations relentlessly...


答:
At a couple of previous employers, we rotated who was on Code Review on a daily basis. Usually 3 people shared a CR day and each CR had to be signed off by two of the reviewers. This made sure that when it was your day, you knew that CR was expected of you, regardless of your other projects. So every five days or so, it was your turn and you could adjust your development tasks accordingly.

Currently, we have a Team Lead do a cursory CR on their team's code. Depending on which area of the application has been updated, after the CR is completed, it can be bumped up to the Global Review Team, where we check for things that have a global impact on the application(s), instead of things that are related to a single feature. When there is a large Review to be done, we usually break it up between a few people so no one person has to deal with changes across a ridiculous number of files.

That said, we are only ever reviewing code that's been committed to the current Dev branch / variant. The code has to pass Code Review, Global Review, DB Review and UI Review (each as needed) before it can be promoted to the next (e.g. Alpha) environment.

Finally, we agree to an SLA on how quickly Reviews are turned around. Hardly anything's in queue for more than 48 hours and most reviews are done in less than 24 hours.

Title: How to get developers to do code reviews in a timely manner

Body:
The company I work for requires all code to be reviewed by other developers before it is committed.  The members of my team are often frustrated because the other developers are too busy coding to do a review, especially if it is very long.  How do you incentivize other developers to do timely code reviews?

(We use git-svn so we are able to continue coding while waiting for a review.  However, I still find it frustrating when I have to wait a long time before I can commit my code.)


问:
binary representation in Python and keeping leading zeros
I wanted to use the base64 Python library to encode a sequence of binary digits into base 64. Would it be possible to do it without converting to a string? If not, what is the best way to do it, assuming that my string of 1/0 digits may not be an integer multiple of 8, it may even be an odd number.

In addition, I have the following question: is it possible to assign a specific binary string to a variable? For example,

```<code>x = 0b00010101010
y = 0b1110000
</code>```

I want x to hold the three initial zeros, and I would like to be able to concatenate these to to obtain

```<code>z = 0b000101010101110000
</code>```

答:
In Python, the 0b binary representation notation is just another way of writing integers. So there is no difference, for example, between 0b11 and 0b0011 - they both represent the integer 3.

Also, base64 encoding is designed for input data in 8-bit groups. The encoding is designed so that the decoder may determine exactly the number of bytes that were used in the original data. However, this granularity extends only to 8-bit groups and does not extend down to the actual bit level.

One approach might be to encode your data with the first byte representing the number of bits, and then the following bytes representing the actual bits themselves. Your decoder could use this information to extract the exact number of bits you originally stored (with leading or trailing zeros, if you like).


问:
Should I use switch statements or long if...else chains?
Often when I hear about the switch statement, its put off as a way to replace long if...else chains. But it seems that when I use the switch statement I'm writing more code that I would be just writing if...else. You also have other issues like keeping all variables for all calls in the same scope.

Here's some code that represents the flow I normally write (thanks to diam)

```<code>String comment;   // The generated insult.
int which = (int)(Math.random() * 3);  //  Result is 0, 1, or 2.

if (which == 0) {
    comment = "You look so much better than usual.";
} else if (which == 1) {
    comment = "Your work is up to its usual standards.";
} else if (which == 2) {
    comment = "You're quite competent for so little experience.";
} else {
    comment = "Oops -- something is wrong with this code.";
}
</code>```

Then they want me to replace that with this:

```<code>String comment;   // The generated insult.
int which = (int)(Math.random() * 3);  //  Result is 0, 1, or 2.

switch (which) {
    case 0:
             comment = "You look so much better than usual.";
    break;
    case 1:
             comment = "Your work is up to its usual standards.";
    break;
    case 2:
             comment = "You're quite competent for so little experience.";
    break;
    default:
             comment = "Oops -- something is wrong with this code.";
}
</code>```

Seems like a lot more code in a much more awkward syntax. But is there really an advantage to using the switch statement?

答:
For this particular situation, it seems to me that both if and case are poor choices. I'd use a simple array:

```<code>String comments[] = {
    "You look so much better than usual.",
    "Your work is up to its usual standards.",
    "You're quite competent for so little experience."
};

String comment = comments[(int)(Math.random() * 3)];
</code>```

As a side note, you should generally compute the multiplier based on the size of the array rather than hard-coding the 3.

As to when you would use a case/switch, the difference from a cascade of if statements (or at least one major difference) is that switch can semi-automatically optimize based on the number and density of values, whereas a cascade of if statements leaves the compiler with little choice but to generate code as you've written it, testing one value after another until it finds a match. With only three real cases, that's hardly a concern, but with a sufficient number it can/could be significant.

Body:
For this particular situation, it seems to me that both if and case are poor choices. I'd use a simple array:

String comments[] = {
    "You look so much better than usual.",
    "Your work is up to its usual standards.",
    "You're quite competent for so little experience."
};

String comment = comments[(int)(Math.random() * 3)];

As a side note, you should generally compute the multiplier based on the size of the array rather than hard-coding the 3.

As to when you would use a case/switch, the difference from a cascade of if statements (or at least one major difference) is that switch can semi-automatically optimize based on the number and density of values, whereas a cascade of if statements leaves the compiler with little choice but to generate code as you've written it, testing one value after another until it finds a match. With only three real cases, that's hardly a concern, but with a sufficient number it can/could be significant.


答:
The company I work for requires all code to be reviewed by other developers before it is committed. The members of my team are often frustrated...

Unless you're doing mission critical software or critical patches to production release candidate code, there are no compelling reasons to rigidly stick with particular type of code reviews.

The idea behind your company requirement sounds reasonable on a surface (100% reviewed code) but the means they decided to use are counterproductive - because as you point out, these lead to developers being frustrated.

Walking in your shoes, I would first point the management that post-commit code reviews are considered equally as respectable as pre-commit ones. These terms are searchable on the web - if needed, find there references to backup this. One does not necessarily need pre-commit reviews to get 100% reviewed code.

Based on above, I would next suggest them to drop micromanagement attitude and let developers try the way that feels more convenient to them. Pre- or post-commit reviews are best left for programmers to choose. If company knows better than programmers, why don't they write the code themselves?


问:
Do you estimate all user stories in iteration zero?
After our product backlog is created and prioritized, are we meant to briefly estimate all the stories in the product backlog?  I assume they have to be in order to create a product burndown chart, however if you have a lot of stories this could take a long time initially.

Additionally, should a user story have acceptance criteria when added to the backlog or are those criteria added when the story transfers from the product backlog to the sprint backlog? It would be harder to estimate without them.

答:
I've never seen anyone estimate the entire product backlog. Typically what happens is that the product backlog is prioritized on an going basis by the Product Owner. Scrum has an ongoing activity known as Backlog Refinement in which the Product Owner and Development Team review Product Backlog Items and add sufficient details to implement the items, estimates, and reorder as necessary (perhaps due to a greater understanding of the complexity or technical dependencies). By Sprint Planning, a good number of Product Backlog Items are refined and the team pulls a sufficient number into the Sprint, based on its priority in the Product Backlog.

The acceptance criteria should be added by the Product Owner before estimation. Since acceptance criteria are based on the business needs (both the functional needs as well as any non-functional or quality attributes associated with the Product Backlog Item), the Product Owner is in the appropriate position to associate these needs with each Product Backlog Item. If there is any additional work that the team feels is necessary to successfully complete the item, they can add it during the discussion of the estimate to ensure that all necessary work is documented and included in the estimate. The team can then include the work necessary to not only complete but also verify and validate the completion of the item in the estimate.

Also, I've never seen a "product burndown chart". The burndown chart is typically for an individual sprint, not for the entire project. On Day 1 of the sprint, the burndown chart reflects the value carried into the sprint. As you implement items from the Sprint Backlog, the chart is updated to reflect the remaining value to implement in the sprint. I don't see why you can't have a product burndown chart based on the refined Product Backlog Item, but as Product Backlog Items are added, refined, and removed, the chart will fluctuate - this should happen far more regularly than changing scope as defined in a Sprint Backlog.


问:
How do CDNs protect failover sites from DDoS attacks?
I'm in the design process for a Java web app that I will probably end up deploying to Google App Engine (GAE). The nice thing about GAE is that I really don't have to worry about fortifying my app from the dreaded DDoS attack - I just specify a "billing ceiling", and if my traffic peaks up to this ceiling (DDoS or otherwise), GAE will just shut my app down. In other words, GAE will essentially scale to any amount until you simply can't afford to keep the app running any longer.

So I'm trying to plan a contingency whereby, if I do hit this billing ceiling and GAE shuts my app down, my web app domain DNS settings "fail over" to another, non-GAE IP address. Some initial research has shown that certain CDNs like CloudFlare offer services for this exact situation. Basically, I just keep my DNS settings with them, and they provide an API I can hit to automate a failover procedure. Thus, if I detect that I'm at 99% my billing ceiling for my GAE app, I can hit this CloudFlare API, and CloudFlare will dynamically change my DNS settings to point away from the GAE servers to some other IP address.

My initial contingency would be to failover to a "read-only" (static content only) version of my web app hosted somewhere else, maybe by GoDaddy or Rackspace.

But then it suddenly dawned on me: if DDoS attacks target the domain name, what difference does it make if I rollover from my GAE IP address to my (say) GoDaddy IP address? In essence, the failover wouldn't do anything other than allows the DDoS attackers to bring down my backup/GoDaddy site!

In other words, DDoS attackers coordinate an attack on my web app, hosted by GAE, at www.blah-whatever.com, which is really an IP address of 100.2.3.4. They cause my traffic to spike to 98% my billing ceiling, and my custom monitor triggers a CloudFlare failover from 100.2.3.4 to 105.2.3.4. The DDoS attackers don't care! They're still launching an attack against www.blah-whatever.com! The DDoS attack continues!

So I ask: what protection do CDNs like CloudFlare offer so that - when you need to fail over to another DNS - you aren't at risk for the same, continued DDoS attack? If such protection exists, are there any technical restrictions (e.g. read-only, etc.) that are placed on the failover site? If not, what good are they?! Thanks in advance!

答:
They don't protect against DDoS attacks when in this configuration. A CDN doesn't "protect" against a DDoS attack -- they just mitigate its effects by having lots of hardware and bandwidth to throw at the problem. When the CDN changes the DNS settings to point directly at your server, the CDN is no longer handling requests for your website -- the clients never see the IP of the CDN, so the CDN can no longer offer you protection.

As far as "what good are they" -- DDoS attacks are not the point of using a CDN. The point of using a CDN is to decrease the latency between when someone requests a large chunk of data from one of your web servers and that person getting the data, by shortening the geographical distance between the server and the client. It's a perf optimization you can make; but it's really not designed to provide security from DDoS.


问:
When are multimethods useful in practice?
The Common Lisp Object System (CLOS) supports multiple dispatch (multimethods).  When is this a useful feature in practice?  I'm not just looking for an example of hypothetical functionality that would be easier to implement with multiple dispatch[1].  I'm looking for examples of where it's useful in real software, for any value of real that means it would  get written for something other than just an example.

[1] In programming tutorials, are examples contrived more often than not?

答:
You can use them for generalized setters.

Instead of writing

```<code>(defmethod set-[specific-property] ((obj obj-type)) ())
</code>```

for each [specific-property] setter that you want, you can use a single generic function to dispatch:

```<code>(defmethod set- ((prop (eql :foreground)) (obj window)) ())

(defmethod set- ((prop (eql :background)) (obj t)) ())
</code>```

etc...

Body:
You can use them for generalized setters.

Instead of writing

(defmethod set-[specific-property] ((obj obj-type)) ())

for each [specific-property] setter that you want, you can use a single generic function to dispatch:

(defmethod set- ((prop (eql :foreground)) (obj window)) ())

(defmethod set- ((prop (eql :background)) (obj t)) ())

etc...


问:
How to motivate co-workers to write unit-tests?
We're working on a large product which has been in production for about 5 years. The codebase is.. erm.. working. Not really well but it is working. New features are thrown into production and tested with a small QA. Bugs are fixed, etc. But no one, except me, is writing unit-tests. No one uses the power of "tracking" down bugs by writing unit tests to ensure this special bug (test case) would never, ever occur again.

I've talked to management. I've talked to developers. I've talked to everyone in the whole company. Everybody says: "Yep, we must write more unit-tests!" That was about a year ago. Since then I have forced introduction of pre-commit code review (Gerrit) and continuous integration (Jenkins).

I held some meetings about unit-tests and I also showed the benefits of writing unit-tests. But no one seems to be interested.

Q1: How do I motivate my fellow co-workers to write unit-tests?

Q2: How do I stay motivated to follow my personal code quality standards? (Sometimes it' s really frustrating!)

PS:
Some frustrating facts (reached in 1 year):

Total unit-tests: 1693

Total "example unit-tests": around 50

Done by me: 1521

Edit: Am I expecting too much? Its my first working place and I'm trying to do my best.

Edit 2: Based upon all answers I've made a small checklist for myself. I've talked to two developer in private and we had a good and honest talk.

One of them told me, like Telastyn said, that he is really uncomfortable with unit-tests. He said that he would like to be "more professional" but he needs a kickstart.   He also said that our unit-test meeting with all developers (around 9-11) was good, but it was too crowdy. Meh. Some critics for me, but I'll learn from that. (see answers below concering tdd kata meetings!)

The other one said that he is not interested in writing unit-tests. He thinks that his work is good enough for his salary. He don't want to put more effort in. I was quite speechless. Typical 9-5 "worker".

Next week I'm going to talk to the other developers.

Thanks for your great answers (so far!) and your support. I really appreciate it! I'ved learned a lot, thank you very much!

答:
This seems like a big case of lead by example.

There are two inherent aspects of human nature you are fighting:

Creative people don't like process.

Most people don't like external negative judgments on their quality.

It is very hard to fight this with lecturing, management declarations, or even logic.  You have to win taking advantage of an alternative aspect of human nature.

People mimic the behavior of the best employees

If the best employees use TDD and it works, the process will expand.  If they don't, it won't.  If you need to convince anyone, it's the top 1 or 2 employees.


问:
How to enter flow experience for SW development?
What are your strategies to improve the flow experience when doing work?</p>

答:
This is an interesting concept for me. One reason I got into software development a couple of years ago is that I found it could be a 'peak experience' where one pleasantly loses track of time. But I experienced less and less of this as time went on, I suppose because the amount of stuff I seemed to NEED to know looked limitless. But I want to recapture the peak experience. It's important for my quality of life.

I found a helpful chart in Czikszentmihalyi's book 'Finding Flow". I probably can't post it here (though it's easily found on Google) but the essence of it is that to increase your chance of enjoyable 'flow' experiences, your current challenge should be somewhat balanced with your current skill level. Of course you want to always be learning new things in I.T., but too high a challenge could send you into an anxious or worried mood. Too low a challenge could send you into boredom or even apathy.

I had experienced a ton of boredom and apathy in my previous I.T. career (not s/w development). It was a kind of bottoming-out experience that forced me to explore how I could make work better. Having once gotten a charge out of a big Perl project, I decided to explore Java.

Speaking of having a clear goal, I got plenty of that from the programming  classes I then took at a local university. The goals were mostly set for me. Of course the external discipline helped me focus: I needed to read and understand a particular chapter in a book by a certain date and time. Or I had to produce a working s/w project by that time. Maybe something about having someone else to please was at work. It's harder to set one's own goals, so I wouldn't mind working in an office again on a development team soon, for the extra external discipline that should bring. I suppose we can't all be entirely self-directed.

Back to answering your question. In working on my own, I got best results by taking my laptop (since stolen, ugh) to a coffee shop, listening to my own carefully-selected music (this one is good, if you're interested: http://en.wikipedia.org/wiki/Soundsystem_01) on headphones while I worked. It helped drown out local conversations. Lack of unwelcome distraction was/is VERY important to me. Plus I think being in a public place was good for me as I couldn't just decide to take a nap or watch TV. Plus it helped motivate me if the problem I was trying to solve with code was in a domain that already interested me.

Also I just realized that it's cool to write mobile phone software because you can always whip out your phone and show people (or yourself) what you've been working on. I do kind of get a charge out of that, which is motivating.