问:
Write once, run anywhere. Is it still relevant?
Since Oracle bought Sun and Apple have decided not to continue developing their JVM, is the "write once and run everywhere" model still relevant or has web services/SOA reduced it to an edge case?</p>

答:
Whatever the fate of the JVM, "write once, run anywhere" is still extraordinarily relevant. The WAY you achieve that goal -- using a VM or translating down to a machine-specific language -- is irrelevant. In 2010 the desktop is still a VERY hot topic and apps are very much alive. What's all the buzz about iPhone anyway? They're client-side apps, and if you can cover more platforms at once -- whether you do it with Java or something like Python in Titanium (sadly, no Python for iOS, if I understand correctly) -- you save money, development time, and ultimately have more left over to buy sushi.

That said, native apps have their place, [[[even if] you write:them] likeThis];

Later: Since you did mention WS in this, you're probably talking about the server-side. It's still relevant: being able to change server platforms gives a technology company flexibility as prices and performance of server OSes vary through time. So many things are write-once run anywhere on the server-side now, though: Rails, PHP. But still, very relevant.


问:
Keeping binary search tree balanced
I am educating myself on algorithms and data structures. For that, I am doing a simple program that would read lines like this:

```<code>bdhj 168.24
dahf 42.88
dhfa 128.92
</code>```

First column represents an account name (and it needn't have to be 4 characters), and second represents value to add (or remove if value is negative) to that account. I have a huge test data that I could profile different algorithms. I tried keeping this information in linked list and dynamic arrays and some mixture of that two so far. Although dynamic arrays were good at allowing binary search, inserting elements requires a call to memmove (since I am inserting sorted) and it takes a lot of time. I want to try binary search trees for this program, however, I don't have any idea how to keep search tree balanced. I tried google search, but couldn't find any explanations about a algorithm I could use, or any pointers at all. Could you give pointers and/or sources that I could check?

答:
There are some self-balanced trees such as Red-Black tree and AVL tree. For more information see:

Wikipedia: Self-balancing binary search tree

Wikipedia: Red–Black tree

Wikipedia: AVL tree

or Chapter 13 of CRLS book

ContentLicense: CC BY-SA 3.0

Title: Keeping binary search tree balanced


问:
Standardized Data Structure Interface
I want to work with a variety of data structures (arrays, singly/doubly linked lists, sorted structures, etc.) on a plug-and-play basis. For example, I want to be able to easily swap in and out the sorted list and the array (which is re-sorted after every insertion/deletion), to test which one has better performance.

In every language I know of, the public interface to such data structures is very inconsistent. So changing the implementation requires a lot of work.

Is there a language, or a language-agnostic design pattern, that makes it easy to define a generic public interface that works with any data structure?

Of course, I understand how different performance would be (e.g., binary search in a sorted array vs linear search in a regular array). All I ask is that the performance of the data structure doesn't degrade asymptotically or by a large constant factor due to the use of the standard interface.

Example problem: iterate through the container of numbers, find the two numbers that are nearest  each other, and remove the pair of them. (If several pairs are equal distance, pick an arbitrary pair).

I'd like the code to solve the problem to be unchanged as I switch in and out different containers.

答:
Its called Table in most systems:

OO systems that provide the concept of an Interface support swapping out implementations transparently. Java specifically does this Collection <- List <- ArrayList, LinkedList, etc.

C++ supports this as well. Python supports this. C would not support this directly.

Dependency Injection in the languages that support this would making plugging concrete implementations in and out configurable as well.

Java: For a extremely generalized interface Guava has the Table
interface and enough specific implementations to cover almost all
cases.

Lua really on has one collection type and that is Table.

A Table interface can serve all the general purposes of an Associative Array as well as a random access normal Array if you just use numbers for the keys.

Title: Standardized Data Structure Interface


问:
foreach($items as &$item) considered harmful?
Is it considered bad practice to pass items in a PHP array by reference instead of by value?

Relevant documentation: http://php.net/manual/en/control-structures.foreach.php

答:
No, it isn't considered bad practice. If it was bad in any way, then it wouldn't exist in the first place.

What is bad is when programmers misuse references or use them where they aren't needed.

You cannot answer simply whether it's bad or good to use or avoid references. You'll always get a few guys in "don't use references" camp that will provide a disaster scenario where your code blows up, and then you'll have another camp of people showing benchmark results with and without references.

Bottom line: use them where appropriate. Don't rely on random blogs that invent a bogus scenario where references are bad, especially if that scenario has no real world application.


答: Also there is a generic programming style, which allows to split data and algorithms. For more details see also C++ Standard Template Library</p>

Title: Standardized Data Structure Interface

Body:
I want to work with a variety of data structures (arrays, singly/doubly linked lists, sorted structures, etc.) on a plug-and-play basis. For example, I want to be able to easily swap in and out the sorted list and the array (which is re-sorted after every insertion/deletion), to test which one has better performance.

In every language I know of, the public interface to such data structures is very inconsistent. So changing the implementation requires a lot of work.

Is there a language, or a language-agnostic design pattern, that makes it easy to define a generic public interface that works with any data structure?

Of course, I understand how different performance would be (e.g., binary search in a sorted array vs linear search in a regular array). All I ask is that the performance of the data structure doesn't degrade asymptotically or by a large constant factor due to the use of the standard interface.

Example problem: iterate through the container of numbers, find the two numbers that are nearest  each other, and remove the pair of them. (If several pairs are equal distance, pick an arbitrary pair).

I'd like the code to solve the problem to be unchanged as I switch in and out different containers.


问:
Event driven design and separation of core/UI logic
I am new to event driven development, and I feel lost when I try to implement events that should pass the core/UI boundary.

In my program I have the following (example in c#):

```<code>UI.RuleForm   Core.RuleList     UI.ResultForm
Cell 1        Rule 1
Cell 2        Rule 2
Cell 3        Rule 3
</code>```

What I want is:
when a RuleForm cell changes, it will update the corresponding rule in RuleList. And when the RuleList changes, the resultFrom will be recalculated from the rules.

My current thought is that, in order to keep core logic separated from UI logic (i.e. core should know nothing about UI), core should then only generate events, but not processing events generated by others.

So I have to create some kind of UI.RuleListWrapper which can process RuleForm change events, updating Core.RuleList. RuleList in term should fire OnChange events that UI.ResultForm can use.

So in summary, my questions are:

I want to know if my reasoning and purposed implementation is okay or not, which probably means: should a core module be able to process events generated by outside UI
Is my separation some kind of "mysophobia", or has it been done before.
Are there other better approaches?

答:
To keep concerns separate the core should not respond to UI events.  That doesn't mean it can't respond to other events, generated say by the UI event handlers.

Keeping abstractions completely isolated is a difficult problem; sometimes there is only so much you can do.  You may need to make the core interface aware of the existence of the UI, for example.  But that doesn't mean it needs to know how the UI works.  That can be taken care of by the UI/presentation layer.


问:
Building software frontend for hardware that does not yet exist
Our task is to build a software frontend to control a hardware device that does not yet exist. We should start development about half a year before the first prototype is available, the project is timeboxed to one year. It is yet unclear what the hardware and the embedded software will be capable of. There're no specified interfaces yet. This will have an impact on the design of the client software.

There're only few things we really can build as long as the interfaces aren't specified in detail.

Sure, you'll probably just say: Write a mock. But this isn't an easy task and a whole mock could turn out to be a whole project by itself.

I'm thinking of writing an adapter layer in which I can plug in any device later on, as long as it has the promised capabilities.

But I'd like to hear advice from you, on how to tackle such projects and avoid possible pitfalls. To what things should we pay special attention? How should we advance on such a project?

Additional information:
We're creating the software project SCRUM-like, but not traditional. We'll make a good deal of upfront design to establish a clear vision, in order to hit the desired targets and minimize the number of iterations.

Also, we have a clear vision on what the hardware/embedded software is supposed to deliver, we just don't know how they're gonna go about it yet and if they can implement the functional requirements at all. We've started a document to collect the interfaces we'd like to have for the client software (because whoever specifies first, wins, g). We also have a rather clear vision of how the client should look like to deliver the best business value, but it is yet unclear if the hardware can support our concepts and it will probably take some time into the project before we know for sure. Yet, we should start development asap.

答:
You don't give a hint as to what the hardware will do, so I will assume it is none of the devices that require you to conform to a specification (such as a network adapter).

In the most general case, I'd start with a fully specified API for accessing the envisioned hardware as per the functional specifications. Once you have your API approved, you can move on to implementing the mock hardware as a software only library. This will give you great advantage even after the hardware is done, because you can debug quite a bit of your clients without ever needing the hardware - a lot simpler that messing with a hardware device. This will give you two products to maintain: the real library, and an emulation library; but the effort will be worth it.

Once the hardware is ready, you can start removing a lot of code from your library, and offload the processing to your hardware. Your library will then change into an adapter layer: converting the hardware implementation into the API you've implemented in software. If your API matches the hardware perfectly, the library will be an extremely thin shim - perhaps something that serializes the parameters, sends them off to the hardware, and reads the results. Or it can turn out to be nothing like what the actual hardware will be, so there will be quite a bit of code in your library, maintaining non-trivial client side state that is used to drive the hardware.


答:
C++'s STL has something along these lines - all collections support iterators which you can use to access the members, and the iterator is a standard class itself, so has the operations you want.

So you can walk an array using begin() to end(), and you can swap the array for a list without any issues.

However, some collections support different operations - although you can sort both array, list and queue, you can't sort a map or set (they're already sorted). This just means some operations don't make sense for some collections.

Look at the algorithms section of the STL for a set of operations that apply to every different type of STL collection.

Title: Standardized Data Structure Interface


答: You should research the Adapter Pattern. Using the Adapter Pattern, you'd define an interface, IContainer, that provides all the required operations, such as indexing, sorting, etc. You would then create different implementations of your IContainer interface, such as ArrayContainer, LinkedListContainer, and so on. Next, using a technique such as Dependency Injection, you could write your algorithms around your IContainer interface, thereby decoupling your code from any one particular container type. This would allow you to substitute and measure the performance of different kinds of containers.

Title: Standardized Data Structure Interface


答:
What I want is: when a RuleForm cell changes, it will update the corresponding rule in RuleList. And when the RuleList changes, the resultFrom will be recalculated from the rules.

My current thought is that, in order to keep core logic separated from UI logic (i.e. core should know nothing about UI), core should then only generate events, but not processing events generated by others.

So I have to create some kind of UI.RuleListWrapper which can process RuleForm change events, updating Core.RuleList. RuleList in term should fire OnChange events that UI.ResultForm can use.

Look up "data binding" in .NET.  That seems to be what you're after.  It's handled differently depending on whether you do WinForms or WPF, but the concepts are the same.

Your idea on the approach you need to take is basically right, however you probably don't need a RuleListWrapper class (at least not in this specific case).  Through data binding your cell changes will automatically update the corresponding rule.  Then your rule can raise a property change event to be handled by your result form.

Specifically, look up the System.ComponentModel.INotifyPropertyChanged interface for your rules.  If you're using WinForms, look up BindingSource for the UI, and for WPF just look up the built-in binding syntax.

Title: Event driven design and separation of core/UI logic

Body:
I am new to event driven development, and I feel lost when I try to implement events that should pass the core/UI boundary.

In my program I have the following (example in c#):

```<code>UI.RuleForm   Core.RuleList     UI.ResultForm
Cell 1        Rule 1
Cell 2        Rule 2
Cell 3        Rule 3
</code>```

What I want is:
when a RuleForm cell changes, it will update the corresponding rule in RuleList. And when the RuleList changes, the resultFrom will be recalculated from the rules.

My current thought is that, in order to keep core logic separated from UI logic (i.e. core should know nothing about UI), core should then only generate events, but not processing events generated by others.

So I have to create some kind of UI.RuleListWrapper which can process RuleForm change events, updating Core.RuleList. RuleList in term should fire OnChange events that UI.ResultForm can use.

So in summary, my questions are:

I want to know if my reasoning and purposed implementation is okay or not, which probably means: should a core module be able to process events generated by outside UI
Is my separation some kind of "mysophobia", or has it been done before.
Are there other better approaches?


问:
How relaxed (or not) should a sprint be?
What should be the attitude towards getting stories done that are assigned to a sprint? Obviously you want to prioritize getting them done in the sprint, but to me the whole point of agile is to be dynamic: You don't want to deliberately procrastinate or make it "ok" to miss finishing user stories in a sprint, but at the same time when unexpected things come up, and those stories do not get completed and are pushed to the next sprint, you don't want the feeling that you did something wrong. That shouldn't be a scary or negative experience, should it?

Are negative/scary experiences acceptable for missed sprint commitments?  Should developers be held accountable for missed sprint commitments when unexpected tasks come up that must be dealt with (Eg. production support)?

答:
It really depends on your timeline.

Sometimes you will NEED to get all the stories done, or most of them anyway.  While Agile does provide some flexibility, you will also need to get the project done, possibly on a tight timeline..  So, having most of the stories done will let you get your project done in time.

With that said, though, stuff is going to come up that will prevent you from getting every story done, every sprint.

If the product is on a timeline and key stories are missed, that coudl make the product late.  The product being late in some cases can hurt a company's competitive position.  So in that case, you might WANT it to be a negative experience to have stories missing - it might make you get it all done the next time.


答:
That shouldn't be a scary or negative experience, should it?

If it happens once or twice, no, then it shouldn't be a negative experience. If it happens regularly, you have a problem. The team is then always overcomitting. Get better at estimation and think twice about what you commit for a sprint, but don't become anxious.

Relaxed sprints mean you had an undercommittment.

Unrelaxed sprints mean you had an overcommittment.

I just deliver what I commit and try to get better at committing. Only under special circumstances would I move a story to the next sprint. I prefer to have slight pressure every day than to have a hell of pressure shortly before some deadlines.

Title: How relaxed (or not) should a sprint be?

Body:
What should be the attitude towards getting stories done that are assigned to a sprint? Obviously you want to prioritize getting them done in the sprint, but to me the whole point of agile is to be dynamic: You don't want to deliberately procrastinate or make it "ok" to miss finishing user stories in a sprint, but at the same time when unexpected things come up, and those stories do not get completed and are pushed to the next sprint, you don't want the feeling that you did something wrong. That shouldn't be a scary or negative experience, should it?

Are negative/scary experiences acceptable for missed sprint commitments?  Should developers be held accountable for missed sprint commitments when unexpected tasks come up that must be dealt with (Eg. production support)?


答:
You should absolutely aim to get items done within a sprint.

One of the main benefits of SCRUM is that it gives the project a 'heartbeat'.

You prioritise, pick items off a list, you deliver them, you demo them, you reflect how they went, then you do it again in preditable cycles.

All of the planning, estimations and prioritisation are based off of this concept.  That we can and will commit do X points within the sprint, and can, over time, establish a velocity from that we can use for better planning.

If you are too casual over the content and commitments of your sprints then SCRUM just breaks down in my opinion and you lose a lot it's benefits.

Of course the real world will sometimes have something to say about this, but that should be the exception rather than the rule....


问:
Can C++ be used as a server-side web development language?
I'd like to get into web development using C++ as the "scripting language" on the server-side.  My server infrastructure is *nix based, so doing web development in C++ on Azure is not applicable and C++/CLI ASP.NET is also not applicable.

Separate from legacy CGI applications, can web development be done using C++ ?

答:
It appears Microsoft thinks it can too. Check out Casablanca which is a new set of tooling for (it appears) Azure using C++.

Casablanca is a project to start exploring how to best support C++
  developers who want to take advantage of the radical shift in software
  architecture that cloud computing represents.

Here’s what you get with Casablanca:

Support for accessing REST services from native code on Windows Vista, Windows 7, and Windows 8 Consumer Preview by providing asynchronous C++ bindings to HTTP, JSON, and URIs

A Visual Studio extension SDK to help you write C++ HTTP client side code in your Windows 8 Metro style app

Support for writing native-code REST for Azure, including Visual Studio integration

Convenient libraries for accessing Azure blob and queue storage from native clients as a first class Platform-as-a-Service (PaaS)
  feature

A consistent and powerful model for composing asynchronous operations based on C++ 11 features

A C++ implementation of the Erlang actor-based programming model

A set of samples and documentation


答:
Based on my experience - Like anything else in agile, we adapt to a continuous feedback system including the estimation.

It is OK to miss a deadline for the first sprint (beginning of the project) but you LEARN from that what went wrong (under-estimation, not knowing the team strengths etc). Then you take the feedback and feed it to the next sprint and you get a better estimate.

From my experience, It has been 11 months on my new agile project we rarely miss the deadline now if at all we miss it. But we did miss the deadline for the first sprint because we did not know the pace and strength of our team members.

Some folks argue that "allocate" more time for the first sprint to overcome the first sprint problem.


答:
The best designed collection framework I have personally worked with, is Scala's, especially combined with the extensions from the Scalaz library.

The Haskell community currently seems to be the frontrunner when it comes to figuring out very general collection interfaces, see e.g. the Data.Traversable or Data.Foldable type classes, zippers, iteratees, enumeratees etc. (A lot of this is also implemented in Scalaz.)

Here's an example how to solve your problem in Scala. Note, I haven't done anything to make this efficient or beautiful, nor have I given any thought to whether this algorithm is sensible or not.

The important feature is that this code is only dependent on operations provided by the Seq trait (zipWithIndex, sorted, foldRight, filterNot), which is very general: it only assumes that the collection has a definite size and that elements may appear multiple times. That's it.

```<code>val s = Seq(5, 1, 9, 2, 6) // our test sequence

val sWithIndex = s zipWithIndex

val rejects = sWithIndex.sorted.foldRight(
  (Int.MaxValue, (
    (Int.MinValue, Int.MinValue), (Int.MinValue, Int.MinValue)))) {
  case ((el, i), (minDist, ((n1, i1), (n2, i2)))) =>
    if(math.abs(n2 - el) <= minDist)
      (math.abs(n2 - el), ((n2, i2), (el, i)))
    else
      (minDist, ((n1, i1), (n2, i2)))
  }._2

val rejectIndices = (rejects._1._2, rejects._2._2)

val result = sWithIndex filterNot { case (_, i) =>
  i == rejectIndices._1 || i == rejectIndices._2 } map (_._1)
// result = List(1, 9, 2)
</code>```

This algorithm is O(n*log n), because sorted is a generic stable sort. You could make it O(n) by using a radix sort, since the elements are known to be integers.

Title: Standardized Data Structure Interface

Body:
The best designed collection framework I have personally worked with, is Scala's, especially combined with the extensions from the Scalaz library.

The Haskell community currently seems to be the frontrunner when it comes to figuring out very general collection interfaces, see e.g. the Data.Traversable or Data.Foldable type classes, zippers, iteratees, enumeratees etc. (A lot of this is also implemented in Scalaz.)

Here's an example how to solve your problem in Scala. Note, I haven't done anything to make this efficient or beautiful, nor have I given any thought to whether this algorithm is sensible or not.

The important feature is that this code is only dependent on operations provided by the Seq trait (zipWithIndex, sorted, foldRight, filterNot), which is very general: it only assumes that the collection has a definite size and that elements may appear multiple times. That's it.

val s = Seq(5, 1, 9, 2, 6) // our test sequence

val sWithIndex = s zipWithIndex

val rejects = sWithIndex.sorted.foldRight(
  (Int.MaxValue, (
    (Int.MinValue, Int.MinValue), (Int.MinValue, Int.MinValue)))) {
  case ((el, i), (minDist, ((n1, i1), (n2, i2)))) =>
    if(math.abs(n2 - el) <= minDist)
      (math.abs(n2 - el), ((n2, i2), (el, i)))
    else
      (minDist, ((n1, i1), (n2, i2)))
  }._2

val rejectIndices = (rejects._1._2, rejects._2._2)

val result = sWithIndex filterNot { case (_, i) =>
  i == rejectIndices._1 || i == rejectIndices._2 } map (_._1)
// result = List(1, 9, 2)

This algorithm is O(n*log n), because sorted is a generic stable sort. You could make it O(n) by using a radix sort, since the elements are known to be integers.


答:
The key is that there needs to be accountability around not getting the stories complete.

That means there should be a solid reason why a story was not complete, and that this reason is accounted for in the project plan going forward so it is not repeated.

This reason needs to be more than a vague "stuff came up."

For example, if a story was not complete because a team member had to work on a production problem, then this possibility needs to be addressed in future iterations -- either by planning for fewer hours from this team member or arranging for other coverage.

If the reason could have been avoided with more diligence or hard work up front, then, yes, this accountability may be a little painful.  Hopefully, the pain is of the "This is what we need to do better next time" variety rather than the "You're not doing your job" variety.


答: It's interesting to see the answers / comments here.  On every agile (type) projects I've worked on, the primary advantage was to spread the deadline pressure over many mini deadlines rather than a deadline death march at the end of a project.  IMO, the sprints should be taken seriously.  Any slips in deadline or functionality delivered should be viewed as potential problems in either project management or development.</p>


答:
I would start two different projects: a mockup of the UI, and a hardware simulator.

The UI-oriented people will work on the mockup, working with customers to determine how the the final product needs to work (just about like if you were developing for already-existing hardware).

The more hardware-oriented people will work on the simulator. At first it'll be relatively simple because you apparently don't know all that much about the final hardware (yet). As you learn more about the planned hardware, you can incorporate what you learn. Likewise, as you learn more from the UI people, you can incorporate what they're learning.

Over time, you "grow" the two closer together -- i.e., the first few mockups probably won't even attempt to fit the intended hardware beyond the general ideas of roughly the intended format factor, intended provision for user input, etc. As you learn more about the real hardware, you tailor your mockup to fit what it's actually going to provide.

One point of this is to learn as much as you can before the first prototype is delivered. Another is to provide feedback to your hardware people, so if what they're designing is going to completely incapable of supporting crucial features for the users, they'll have a chance to re-design more appropriately. In some cases, fixing a major problem can be pretty easy, as long as they know about it soon enough. Much as with software, they sooner they know about a hardware problem, the less expensive it's likely to be to fix it.

Although none of us likes to think in that direction, it also means that if the hardware you get can't possibly do the job, it may well be extremely helpful to your future to have a paper trail where you told them about the problem months ahead of time.

Title: Building software frontend for hardware that does not yet exist

Body:
Our task is to build a software frontend to control a hardware device that does not yet exist. We should start development about half a year before the first prototype is available, the project is timeboxed to one year. It is yet unclear what the hardware and the embedded software will be capable of. There're no specified interfaces yet. This will have an impact on the design of the client software.

There're only few things we really can build as long as the interfaces aren't specified in detail.

Sure, you'll probably just say: Write a mock. But this isn't an easy task and a whole mock could turn out to be a whole project by itself.

I'm thinking of writing an adapter layer in which I can plug in any device later on, as long as it has the promised capabilities.

But I'd like to hear advice from you, on how to tackle such projects and avoid possible pitfalls. To what things should we pay special attention? How should we advance on such a project?

Additional information:
We're creating the software project SCRUM-like, but not traditional. We'll make a good deal of upfront design to establish a clear vision, in order to hit the desired targets and minimize the number of iterations.

Also, we have a clear vision on what the hardware/embedded software is supposed to deliver, we just don't know how they're gonna go about it yet and if they can implement the functional requirements at all. We've started a document to collect the interfaces we'd like to have for the client software (because whoever specifies first, wins, g). We also have a rather clear vision of how the client should look like to deliver the best business value, but it is yet unclear if the hardware can support our concepts and it will probably take some time into the project before we know for sure. Yet, we should start development asap.


答:
If you're planning to write your web application in C++, it would be total waste to then interface it as CGI.

My suggestion would be to build it asynchronous using ASIO (Asynchronous I/O). With that you can build blazing fast web service (combine with nginx as a reverse-proxy and statics server for best effects); Combine that with template library like Wt and you're ready to serve tens of thousands request per second from a single server.

Whether this is practical alternative to dynamic language web framework is another issue.

Title: Can C++ be used as a server-side web development language?

Body:
I'd like to get into web development using C++ as the "scripting language" on the server-side.  My server infrastructure is *nix based, so doing web development in C++ on Azure is not applicable and C++/CLI ASP.NET is also not applicable.

Separate from legacy CGI applications, can web development be done using C++ ?


答:
Example problem: iterate through the container of numbers, find the
  two numbers that are nearest each other, and remove the pair of them.
  (If several pairs are equal distance, pick an arbitrary pair).

Data structures have different interfaces because they do different things. Arrays and linked lists are somewhat comparable in that they both store an ordered collection, but there are important differences even here: you generally don't refer to items in a linked list by index, memory is managed very differently, etc. When you start looking at other structures (heaps, sets, maps, binary trees, etc.) the differences increase and the similarities decrease.

If you're willing to give up some of the advantages of each of the structures you test for the sake of providing a uniform interface, there's nothing to stop you from defining a "List" interface and implementing it using each of the structures you want to test. Any language that supports polymorphism will do the job, and you can easily imagine a set of operations that are common to all the structures (insert, remove, sort, search). Just don't forget that your test conditions will be somewhat contrived -- by forcing the structures you test to conform to a common interface, you'll be ignoring the aspects that differentiate each structure from the group.

Title: Standardized Data Structure Interface


问:
Design pattern for handling a response
Most of the time when I'm writing some code that handles the response for a certain function call I get the following code structure:

example: This is a function that will handle the authentication for a login system

```<code>class Authentication{

function login(){ //This function is called from my Controller
$result=$this->authenticate($username,$password);

if($result=='wrong password'){
   //increase the login trials counter
   //send mail to admin
   //store visitor ip
}else if($result=='wrong username'){
   //increase the login trials counter
   //do other stuff
}else if($result=='login trials exceeded')
   //do some stuff
}else if($result=='banned ip'){
   //do some stuff
}else if...

function authenticate($username,$password){
   //authenticate the user locally or remotely and return an error code in case a login in fails.
}
}
</code>```

Problem

As you can see the code is build on a if/else structure which means a new failure status will mean that I need to add an else if statement which is a violation for the Open Closed Principle.

I get a feeling that the function has different layers of abstraction as I may just increase the login trials counter in one handler, but do more serious stuff in another.

Some of the functions are repeated increase the login trials for example.

I thought about converting the multiple if/else to a factory pattern, but I only used factory to create objects not alter behaviors. Does anyone have a better solution for this?

Note:

This is just an example using a login system. I'm asking for a general solution to this behavior using a well built OO pattern. This kind of if/else handlers appears in too many places in my code and I just used the login system as a simple easy to explain example. My real use cases are to much complicated to post here. :D

Please don't limit your answer to PHP code and feel free to use the language you prefer.

UPDATE

Another more complicated code example just to clarify my question:

```<code>  public function refundAcceptedDisputes() {
        $this->getRequestedEbayOrdersFromDB(); //get all disputes requested on ebay
        foreach ($this->orders as $order) { /* $order is a Doctrine Entity */
            try {
                if ($this->isDisputeAccepted($order)) { //returns true if dispute was accepted
                    $order->setStatus('accepted');
                    $order->refund(); //refunds the order on ebay and internally in my system
                    $this->insertRecordInOrderHistoryTable($order,'refunded');
                } else if ($this->isDisputeCancelled($order)) { //returns true if dispute was cancelled
                    $order->setStatus('cancelled');
                    $this->insertRecordInOrderHistory($order,'cancelled');
                    $order->rollBackRefund(); //cancels the refund on ebay and internally in my system
                } else if ($this->isDisputeOlderThan7Days($order)) { //returns true if 7 days elapsed since the dispute was opened
                    $order->closeDispute(); //closes the dispute on ebay
                    $this->insertRecordInOrderHistoryTable($order,'refunded');
                    $order->refund(); //refunds the order on ebay and internally in my system
                }
            } catch (Exception $e) {
                $order->setStatus('failed');
                $order->setErrorMessage($e->getMessage());
                $this->addLog();//log error
            }
            $order->setUpdatedAt(time());
            $order->save();
        }
    }
</code>```

function purpose:

I am selling games on ebay.

If a customers wishes to cancel his order and gets his money back
(i.e. a Refund) I must open a "Dispute" on ebay first.

Once a dispute is opened I must wait for the customer to confirm that
he agrees to the refund (silly as he's the one who told me to refund,
but that's how it works on ebay).

This functions gets all disputes opened by me and checks their statuses periodically to see if the customer has replied to the dispute or not.

The customer may agree (then I refund) or refuse (then I rollback) or may not respond for 7 days (I close the dispute myself then refund).

答:
As I said in my comments, complex logic doesn't really change anything.

You want to process a disputed order. There are multiple ways of doing that. Disputed order type can be Enum:

```<code>public void ProcessDisputedOrder(DisputedOrder order)
{
   switch (order.Type)
   {
       case DisputedOrderType.Canceled:
          var strategy = new StrategyForDisputedCanceledOrder();
          strategy.Process(order);
          break;

       case DisputedOrderType.LessThan7Days:
          var strategy = new DifferentStrategy();
          strategy.Process(order);
          break;

       default:
          throw new NotImplementedException();
   }
}
</code>```

There are many ways of doing this. You can have inheritance hierarchy of Order, DisputedOrder, DisputedOrderLessThan7Days, DisputedOrderCanceled, etc. This is not nice, but it would also work.

In my example above I look at order type and get relevant strategy for that. You could encapsulate that process into a factory:

```<code>var strategy = DisputedOrderStrategyFactory.Instance.Build(order.Type);
</code>```

This would look at the order type and give you a correct strategy for that type of order.

You might end up with something on the lines of:

```<code>public void ProcessDisputedOrder(DisputedOrder order)
{
   var strategy = DisputedOrderStrategyFactory.Instance.Build(order.Type);
   strategy.Process(order);
}
</code>```

Original Answer, no longer relevant as I thought you were after something simpler:

I see the following concerns here:

Check for banned IP. Checks whether user's IP is in a banned IP range. You will execute this no matter what.

Check if trials exceeded. Checks whether user have exceeded their login attempts. You will execute this no matter what.

Authenticate user. Attempt to authenticate user.

I would do the following:

```<code>CheckBannedIP(login.IP);
CheckLoginTrial(login);

Authenticate(login.Username, login.Password);

public void CheckBannedIP(string ip)
{
    // If banned then re-direct, else do nothing.
}

public void CheckLoginTrial(LoginAttempt login)
{
    // If exceeded trials, then inform user, else do nothing
}

public void Authenticate(string username, string password)
{
     // Attempt to authenticate. On success redirect, else catch any errors and inform the user.
}
</code>```

Currently your example has too many responsibilities. All I did, was encapsulate those responsibilities within methods. Code looks cleaner and you don't have condition statements all over the place.

Factory encapsulates construction of objects. You don't need to encapsulate construction of anything in your example, all you need to do is to separate your concerns.

Title: Design pattern for handling a response

Body:
As I said in my comments, complex logic doesn't really change anything.

You want to process a disputed order. There are multiple ways of doing that. Disputed order type can be Enum:

public void ProcessDisputedOrder(DisputedOrder order)
{
   switch (order.Type)
   {
       case DisputedOrderType.Canceled:
          var strategy = new StrategyForDisputedCanceledOrder();
          strategy.Process(order);
          break;

       case DisputedOrderType.LessThan7Days:
          var strategy = new DifferentStrategy();
          strategy.Process(order);
          break;

       default:
          throw new NotImplementedException();
   }
}

There are many ways of doing this. You can have inheritance hierarchy of Order, DisputedOrder, DisputedOrderLessThan7Days, DisputedOrderCanceled, etc. This is not nice, but it would also work.

In my example above I look at order type and get relevant strategy for that. You could encapsulate that process into a factory:

var strategy = DisputedOrderStrategyFactory.Instance.Build(order.Type);

This would look at the order type and give you a correct strategy for that type of order.

You might end up with something on the lines of:

public void ProcessDisputedOrder(DisputedOrder order)
{
   var strategy = DisputedOrderStrategyFactory.Instance.Build(order.Type);
   strategy.Process(order);
}

Original Answer, no longer relevant as I thought you were after something simpler:

I see the following concerns here:

Check for banned IP. Checks whether user's IP is in a banned IP range. You will execute this no matter what.

Check if trials exceeded. Checks whether user have exceeded their login attempts. You will execute this no matter what.

Authenticate user. Attempt to authenticate user.

I would do the following:

CheckBannedIP(login.IP);
CheckLoginTrial(login);

Authenticate(login.Username, login.Password);

public void CheckBannedIP(string ip)
{
    // If banned then re-direct, else do nothing.
}

public void CheckLoginTrial(LoginAttempt login)
{
    // If exceeded trials, then inform user, else do nothing
}

public void Authenticate(string username, string password)
{
     // Attempt to authenticate. On success redirect, else catch any errors and inform the user.
}

Currently your example has too many responsibilities. All I did, was encapsulate those responsibilities within methods. Code looks cleaner and you don't have condition statements all over the place.

Factory encapsulates construction of objects. You don't need to encapsulate construction of anything in your example, all you need to do is to separate your concerns.


问:
Generating CSRF tokens without using sessions & cookies
I'm writing a library to generate and check CSRF tokens.

I would like to do it without having to use sessions and/or cookies. What I've come up with is this:

A token generated from the current time and a unique token id (unix-timestamp.unique-token-id).

The token would then be hashed using the HMAC method. The returned value would be: hmac-hash.unix-timestamp.unique-token-id. This could then be hidden in a form.

The library would then test the returned token by extracting the HAMC hash, time and unique token id from it and then compare the returned HAMC hash to one generated using the returned time and unique token id.

As long as the HMAC secret on the server stays secret it should be secure or did I missed something?

答:
I as an attacker will resubmit the data with the same token within the n seconds. assuming n is the expiary times. This sounds like a replay attack though.
However I can change the other data of your form fields while keeping the tokens same. as you have no

ContentLicense: CC BY-SA 2.5


答:
When you start having a bunch of if/then/else statements to handle a status, consider the State Pattern.

There was a question on a particular way of using it: Does this implementation of the state pattern make sense?

I'm new to this patter, but I put up the answer anyway to make sure I understand when to use it (Avoid the "all problems look like nails to a hammer.").

Title: Design pattern for handling a response

Body:
Most of the time when I'm writing some code that handles the response for a certain function call I get the following code structure:

example: This is a function that will handle the authentication for a login system

```<code>class Authentication{

function login(){ //This function is called from my Controller
$result=$this->authenticate($username,$password);

if($result=='wrong password'){
   //increase the login trials counter
   //send mail to admin
   //store visitor ip
}else if($result=='wrong username'){
   //increase the login trials counter
   //do other stuff
}else if($result=='login trials exceeded')
   //do some stuff
}else if($result=='banned ip'){
   //do some stuff
}else if...

function authenticate($username,$password){
   //authenticate the user locally or remotely and return an error code in case a login in fails.
}
}
</code>```

Problem

As you can see the code is build on a if/else structure which means a new failure status will mean that I need to add an else if statement which is a violation for the Open Closed Principle.

I get a feeling that the function has different layers of abstraction as I may just increase the login trials counter in one handler, but do more serious stuff in another.

Some of the functions are repeated increase the login trials for example.

I thought about converting the multiple if/else to a factory pattern, but I only used factory to create objects not alter behaviors. Does anyone have a better solution for this?

Note:

This is just an example using a login system. I'm asking for a general solution to this behavior using a well built OO pattern. This kind of if/else handlers appears in too many places in my code and I just used the login system as a simple easy to explain example. My real use cases are to much complicated to post here. :D

Please don't limit your answer to PHP code and feel free to use the language you prefer.

UPDATE

Another more complicated code example just to clarify my question:

```<code>  public function refundAcceptedDisputes() {
        $this->getRequestedEbayOrdersFromDB(); //get all disputes requested on ebay
        foreach ($this->orders as $order) { /* $order is a Doctrine Entity */
            try {
                if ($this->isDisputeAccepted($order)) { //returns true if dispute was accepted
                    $order->setStatus('accepted');
                    $order->refund(); //refunds the order on ebay and internally in my system
                    $this->insertRecordInOrderHistoryTable($order,'refunded');
                } else if ($this->isDisputeCancelled($order)) { //returns true if dispute was cancelled
                    $order->setStatus('cancelled');
                    $this->insertRecordInOrderHistory($order,'cancelled');
                    $order->rollBackRefund(); //cancels the refund on ebay and internally in my system
                } else if ($this->isDisputeOlderThan7Days($order)) { //returns true if 7 days elapsed since the dispute was opened
                    $order->closeDispute(); //closes the dispute on ebay
                    $this->insertRecordInOrderHistoryTable($order,'refunded');
                    $order->refund(); //refunds the order on ebay and internally in my system
                }
            } catch (Exception $e) {
                $order->setStatus('failed');
                $order->setErrorMessage($e->getMessage());
                $this->addLog();//log error
            }
            $order->setUpdatedAt(time());
            $order->save();
        }
    }
</code>```

function purpose:

I am selling games on ebay.

If a customers wishes to cancel his order and gets his money back
(i.e. a Refund) I must open a "Dispute" on ebay first.

Once a dispute is opened I must wait for the customer to confirm that
he agrees to the refund (silly as he's the one who told me to refund,
but that's how it works on ebay).

This functions gets all disputes opened by me and checks their statuses periodically to see if the customer has replied to the dispute or not.

The customer may agree (then I refund) or refuse (then I rollback) or may not respond for 7 days (I close the dispute myself then refund).


答:
This is a prime candidate for the Strategy pattern.

For example, this code:

```<code>if ($this->isDisputeAccepted($order)) { //returns true if dispute was accepted
    $order->setStatus('accepted');
    $order->refund(); //refunds the order on ebay and internally in my system
    $this->insertRecordInOrderHistoryTable($order,'refunded');
} else if ($this->isDisputeCancelled($order)) { //returns true if dispute was cancelled
    $order->setStatus('cancelled');
    $this->insertRecordInOrderHistory($order,'cancelled');
    $order->rollBackRefund(); //cancels the refund on ebay and internally in my system
} else if ($this->isDisputeOlderThan7Days($order)) { //returns true if 7 days elapsed since the dispute was opened
    $order->closeDispute(); //closes the dispute on ebay
    $this->insertRecordInOrderHistoryTable($order,'refunded');
    $order->refund(); //refunds the order on ebay and internally in my system
}
</code>```

Could be reduced to

```<code>var $strategy = $this.getOrderStrategy($order);
$strategy->preProcess();
$strategy->updateOrderHistory($this);
$strategy->postProcess();
</code>```

where getOrderStrategy wraps the order in a DisputeAcceptedStrategy, DisputeCancelledStrategy, DisputeOlderThan7DaysStrategy, etc. each of which know how to handle the given situation.

Edit, to answer question in comments.

could you please elaborate more on your code. What I understood is that getOrderStrategy is a factory method that returns a strategy object depending on the order status, but what are the preProcess() and preProcess() functions. Also why did you pass $this to updateOrderHistory($this)?

You're focussing on the example, which could be completely inappropriate for your case. I don't have enough detail to be sure of the best implementation, so I came up with a vague example.

The one common piece of code you have is insertRecordInOrderHistoryTable, so I chose to use that (with a slightly more generic name) as the central point of the strategy. I pass $this to it, because it is calling a method on this, with $order and a different string per strategy.

So, basically, I envision each of those looking like this:

```<code>public function updateOrderHistory($auth) {
    $auth.insertRecordInOrderHistoryTable($order, 'cancelled');
}
</code>```

Where $order is a private member of the Strategy (remember I said it should wrap the order) and the second argument is different in each class. Again, this might be entirely inappropriate. You might want to move insertRecordInOrderHistoryTable to a base Strategy class and not pass the Authorization class in. Or you might want to do something entirely different, it was just an example.

Likewise, I limited the rest of the differing code to pre- and postProcess methods. This is almost certainly not the best you can do with it. Give it more appropriate names. Split it down into multiple methods. Whatever makes the calling code more readable.

You might prefer to do this:

```<code>var $strategy = $this.getOrderStrategy($order);
$strategy->setStatus();
$strategy->closeDisputeIfNecessary();
$strategy->refundIfNecessary();
$strategy->insertRecordInOrderHistoryTable($this);
$strategy->rollBackRefundIfNecessary();
</code>```

And have some of your Strategies implement empty methods for the "IfNecessary" methods.

Whatever makes the calling code more readable.

Title: Design pattern for handling a response

Body:
This is a prime candidate for the Strategy pattern.

For example, this code:

if ($this->isDisputeAccepted($order)) { //returns true if dispute was accepted
    $order->setStatus('accepted');
    $order->refund(); //refunds the order on ebay and internally in my system
    $this->insertRecordInOrderHistoryTable($order,'refunded');
} else if ($this->isDisputeCancelled($order)) { //returns true if dispute was cancelled
    $order->setStatus('cancelled');
    $this->insertRecordInOrderHistory($order,'cancelled');
    $order->rollBackRefund(); //cancels the refund on ebay and internally in my system
} else if ($this->isDisputeOlderThan7Days($order)) { //returns true if 7 days elapsed since the dispute was opened
    $order->closeDispute(); //closes the dispute on ebay
    $this->insertRecordInOrderHistoryTable($order,'refunded');
    $order->refund(); //refunds the order on ebay and internally in my system
}

Could be reduced to

var $strategy = $this.getOrderStrategy($order);
$strategy->preProcess();
$strategy->updateOrderHistory($this);
$strategy->postProcess();

where getOrderStrategy wraps the order in a DisputeAcceptedStrategy, DisputeCancelledStrategy, DisputeOlderThan7DaysStrategy, etc. each of which know how to handle the given situation.

Edit, to answer question in comments.

could you please elaborate more on your code. What I understood is that getOrderStrategy is a factory method that returns a strategy object depending on the order status, but what are the preProcess() and preProcess() functions. Also why did you pass $this to updateOrderHistory($this)?

You're focussing on the example, which could be completely inappropriate for your case. I don't have enough detail to be sure of the best implementation, so I came up with a vague example.

The one common piece of code you have is insertRecordInOrderHistoryTable, so I chose to use that (with a slightly more generic name) as the central point of the strategy. I pass $this to it, because it is calling a method on this, with $order and a different string per strategy.

So, basically, I envision each of those looking like this:

public function updateOrderHistory($auth) {
    $auth.insertRecordInOrderHistoryTable($order, 'cancelled');
}

Where $order is a private member of the Strategy (remember I said it should wrap the order) and the second argument is different in each class. Again, this might be entirely inappropriate. You might want to move insertRecordInOrderHistoryTable to a base Strategy class and not pass the Authorization class in. Or you might want to do something entirely different, it was just an example.

Likewise, I limited the rest of the differing code to pre- and postProcess methods. This is almost certainly not the best you can do with it. Give it more appropriate names. Split it down into multiple methods. Whatever makes the calling code more readable.

You might prefer to do this:

var $strategy = $this.getOrderStrategy($order);
$strategy->setStatus();
$strategy->closeDisputeIfNecessary();
$strategy->refundIfNecessary();
$strategy->insertRecordInOrderHistoryTable($this);
$strategy->rollBackRefundIfNecessary();

And have some of your Strategies implement empty methods for the "IfNecessary" methods.

Whatever makes the calling code more readable.


问:
How do I link an domain object in memory to its database records without cluttering the domain with database concerns?
Your domain model contains a set of objects. I'm here presenting a side project, but I have a much more complicated work project falling to its knees because I didn't do a good separation of the database and the domain.

In this case, the object is called a CyclingRecord.

Following Onion Architecture, the domain objects know nothing of their persistence. However, each one of those objects corresponds to an entry in a datastore (potentially a database, potentially a file). The row ID is absolutely not part of the domain object and therefore has no business being stored in the domain object.

```<code>data CyclingRecord = CyclingRecord { date :: Day,
                                     distance :: Float,
                                     time :: Integer,
                                     description :: Maybe String }
</code>```

In a language that enforces strong immutability (such as Haskell and Clojure), identity and value are synonymous. Further, there is no reason why you could not record more than a single ride in a day. So, the entire record completely describes a ride.

So, if I edit a record in the Domain, when I pass the edited objects back to the Database Infrastructure, how do I go about notifying the database that it needs to update a particular record instead of deleting an existing record?

(the same idea would need to be extensible so that I can have an application potentially manipulate many records at once and then send them all back to the database. Offline operation or syncing or just avoiding excessive disk activity)

Unless the correct answer is to actually make something like a unique identifier for each ride.  Perhaps a UUID.  Perhaps add a "day counter" to the record.  Make it intrinsically part of a bike ride and then have the database depend on it instead of a separate row ID.

答:
The correct answer is to make something like a unique identifier for each ride.  Entities need identity which, in this case, really is separate from the combination of date, distance, time, and description.  You are saying these things can change, while the identity cannot.

So, give them something immutable -- a UUID, if you like.


答:
Looks like your timestamp should be unique, why not use that as your primary key?  In your persistence logic you can either pre-delete (always delete any records with the same timestamp, then insert) or check to see if a record already exists and insert or update as appropriate.

Alternately, you could use some sort of decorator or companion object to hold the persistence metadata.  Your persistence logic would have to have some way to match the metadata with the cycling record and create or update it when persisting the record.

If you determine you really need a unique ID, why not assign a "ride number"?  That sounds like a reasonable thing to record.  It could be either a sequential number, or you could produce it from the timestamp (e.g., "201205011045" for a ride you took at 10:45 on 1 May 2012).

Title: How do I link an domain object in memory to its database records without cluttering the domain with database concerns?

Body:
Your domain model contains a set of objects. I'm here presenting a side project, but I have a much more complicated work project falling to its knees because I didn't do a good separation of the database and the domain.

In this case, the object is called a CyclingRecord.

Following Onion Architecture, the domain objects know nothing of their persistence. However, each one of those objects corresponds to an entry in a datastore (potentially a database, potentially a file). The row ID is absolutely not part of the domain object and therefore has no business being stored in the domain object.

```<code>data CyclingRecord = CyclingRecord { date :: Day,
                                     distance :: Float,
                                     time :: Integer,
                                     description :: Maybe String }
</code>```

In a language that enforces strong immutability (such as Haskell and Clojure), identity and value are synonymous. Further, there is no reason why you could not record more than a single ride in a day. So, the entire record completely describes a ride.

So, if I edit a record in the Domain, when I pass the edited objects back to the Database Infrastructure, how do I go about notifying the database that it needs to update a particular record instead of deleting an existing record?

(the same idea would need to be extensible so that I can have an application potentially manipulate many records at once and then send them all back to the database. Offline operation or syncing or just avoiding excessive disk activity)

Unless the correct answer is to actually make something like a unique identifier for each ride.  Perhaps a UUID.  Perhaps add a "day counter" to the record.  Make it intrinsically part of a bike ride and then have the database depend on it instead of a separate row ID.


问:
Can the Strategy pattern be implemented without significant branching?
The Strategy pattern works well to avoid huge if...else constructs and make it easier to add or replace functionality. However, it still leaves one flaw in my opinion. It seems like in every implementation there still needs to be a branching construct. It might be a factory or a data file. As an example take an ordering system.

Factory:

```<code>// All of these classes implement OrderStrategy
switch (orderType) {
case NEW_ORDER: return new NewOrder();
case CANCELLATION: return new Cancellation();
case RETURN: return new Return();
}
</code>```

The code after this doesn't need to worry, and there is only one place to add a new order type now, but this section of code still isn't extensible. Pulling it out into a data file helps readability somewhat (debatable, I know):

```<code><strategies>
   <order type="NEW_ORDER">com.company.NewOrder</order>
   <order type="CANCELLATION">com.company.Cancellation</order>
   <order type="RETURN">com.company.Return</order>
</strategies>
</code>```

But this still adds boilerplate code to process the data file - granted, more easily unit testable and relatively stable code, but additional complexity nontheless.

Also, this sort of construct doesn't integration test well. Each individual strategy may be easier to test now, but every new strategy you add is addition complexity to test. It's less than you would have if you hadn't used the pattern, but it's still there.

Is there a way to implement the strategy pattern that mitigates this complexity? Or is this just as simple as it gets, and trying to go further would only add another layer of abstraction for little to no benefit?

答:
Of course not. Even if you use an IoC container, you will have to have conditions somewhere, deciding which concrete implementation to inject. This is the nature of the Strategy pattern.

I don't really see why people think this is a problem. There are statements in some books, like Fowler's Refactoring, that if you see a switch/case or a chain of if/elses in the middle of other code, you should consider that a smell and look to move it to its own method. If the code within each case is more than a line, maybe two, then you should consider making that method a Factory Method, returning Strategies.

Some people have taken this to mean that a switch/case is bad. This is not the case. But it should reside on its own, if possible.


答:
The strategy pattern is used when you're specifying possible behaviors and is best used when designating a handler at startup. Specifying which instance of the strategy to use can be done via a Mediator, your standard IoC container, some Factory like you describe, or simply by using the right one based on context (since often, the strategy is supplied as part of a wider use of the class that contains it).

For this sort of behavior where different methods need to be called based on data, then I'd suggest using the polymorphism constructs supplied by the language at hand; not the strategy pattern.

Title: Can the Strategy pattern be implemented without significant branching?

Body:
The Strategy pattern works well to avoid huge if...else constructs and make it easier to add or replace functionality. However, it still leaves one flaw in my opinion. It seems like in every implementation there still needs to be a branching construct. It might be a factory or a data file. As an example take an ordering system.

Factory:

```<code>// All of these classes implement OrderStrategy
switch (orderType) {
case NEW_ORDER: return new NewOrder();
case CANCELLATION: return new Cancellation();
case RETURN: return new Return();
}
</code>```

The code after this doesn't need to worry, and there is only one place to add a new order type now, but this section of code still isn't extensible. Pulling it out into a data file helps readability somewhat (debatable, I know):

```<code><strategies>
   <order type="NEW_ORDER">com.company.NewOrder</order>
   <order type="CANCELLATION">com.company.Cancellation</order>
   <order type="RETURN">com.company.Return</order>
</strategies>
</code>```

But this still adds boilerplate code to process the data file - granted, more easily unit testable and relatively stable code, but additional complexity nontheless.

Also, this sort of construct doesn't integration test well. Each individual strategy may be easier to test now, but every new strategy you add is addition complexity to test. It's less than you would have if you hadn't used the pattern, but it's still there.

Is there a way to implement the strategy pattern that mitigates this complexity? Or is this just as simple as it gets, and trying to go further would only add another layer of abstraction for little to no benefit?


答:
I think there should be a limit on how many branches are acceptable.

For example, if I have more than eight cases inside of my switch statement, then I re-evaluate my code and look for what I can re-factor. Quite often I find that certain cases can be grouped into a separate factory. My assumption here is that there is a factory that builds strategies.

Either way, you can't avoid this and somewhere you will have to check the state or type of the object you are working with. You will then build a strategy for that. Good old separation of concerns.


答:
The strategy pattern is a good suggestion if you truly want to decentralize your logic, but it seems like indirection overkill for examples as small as yours.  Personally, I would employ the "write smaller functions" pattern, like:</p>

```<code>if($result=='wrong password')
   wrongPassword();
else if($result=='wrong username')
   wrongUsername();
else if($result=='login trials exceeded')
   excessiveTries();
else if($result=='banned ip')
   bannedIp();
</code>```

Title: Design pattern for handling a response

Body:
The strategy pattern is a good suggestion if you truly want to decentralize your logic, but it seems like indirection overkill for examples as small as yours.  Personally, I would employ the "write smaller functions" pattern, like:

if($result=='wrong password')
   wrongPassword();
else if($result=='wrong username')
   wrongUsername();
else if($result=='login trials exceeded')
   excessiveTries();
else if($result=='banned ip')
   bannedIp();


答:
If your database has a unique identifier, there is no reason not to include that as part of the domain model. Even if it does not have any other meaning (e.g. Employee Number, username, email address, automobile VIN, etc.).

Otherwise you have to rely on some other combination of fields or rely on every object to have some unique number assigned to it in the real world.

This is key with updating or deleting data (You can theoretically select a record by any other number of fields exactly as a user would in a search form.). Immutable objects don't have this problem with getting updated.


答:
Persistence independence (or ignorance, I can't remember correct term) is difficult and sometimes impossible to achieve with certain technologies. E.g. (LINQ to SQL in a .NET technology stack is a no-no as it fully relies on the database structure). If that's the case, then you have to accept that and live with it.

There is nothing wrong with adding unique identifier to your domain model. If it makes you happier, than you can create an annotation to denote that annotated attribute isn't part of a domain model.

Regarding checks to see if the object has changed, you can add a timestamp column. This is relatively cheap. You would have to implement object state tracking or choose a persistence framework that can already do that for you.

Alternative to state tracking is to check all properties to see whether they have changed, but this is not enough on its own.

My question to you is whether you can justify such a strong need for complete persistence independence? Seeking perfection is good, but you have to draw a line sometimes.

Finally, the majority of your problems can be partially if not fully solved by existing data persistence frameworks.


问:
Where do you draw the line between quantity and quality?
My manager has talked with me and says that the quality of my work is excellent, but I need to step up the quantity of how much I crank out. I've only been working for a couple of years, so I still feel like I have a lot to learn. Which route do I take (or is there another?):

Quantity: If they want crap, I can give them lots of it.

Quality: Ignore the request, and hope that my productivity will increase with experience.

答:
As other stated in their answers, quality is very important from a technical point of view.

But quality is also very important for motivation. If your boss asks you to make shit, on the long run, it will destruct you. Imagine yourself in a drink answering the question "what do you do?" you won't answer "I write shit for a insane manager" isn't it? But you will think it loudly...

I think that the key in organization is making its employees proud of what they make.

That said, quality can be one of the four factor that you would reduce in order to get to the market. Four factors are resources, time, scope, and quality.

I've once worked on a project where resources was limited, scope vital and deadline fixed to tbe first if january by a contract that would have make that company loose millions every minutes of late.

The decision has been made to do our best but withou considering quality over time & scope.

The application generated enought profit on its first hour of run to paid back past development AND the complete rewrite that was planned afterwards.

Conclusion: quality IS very important, but sometimes, business priorities requires you to reduce it for the well being of the whole organisation.


问:
Writing a company-wide developer's handbook
I work for a small company. The software development arm of the company before I was hired consisted of one self-taught overworked guy. Now that I've been writing software for the company for a few years, I have been tasked with establishing formal company-wide software development practices. We currently have no guidelines, other than

Write code, test it, put it in a .zip file and send it to the client. Bonus points for TDD and version control.

My boss wants me to write a software developer's handbook which defines the general processes, protocols, tools, and guidelines we use to get things done. In other words, he wants a "This is what we do here" book to make it easier to get a new employee familiar with the way we do things, as well as to help my boss understand what his minions are doing and how they do it.

The way I see it, I'm laying a foundation and it needs to be done right. How would you go about choosing topics for such a handbook? Can you provide some example topics?

Side Note: If it matters, we are primarily a Microsoft .NET shop. And we are looking at agile practices such as XP and Scrum, but we may have to heavily modify them to make them work in our company.

答:
I would break it down into sections like

Current staff - names and titles (ideally with photos)

Applications, logins to them, data to know and permission requests to have submitted

Bookmarks to company sites and key external sites relevant to the business

Applications that the company uses for comms, email, conference room booking, sharescreen

Procedures for company related activities such as Expensing receipts, booking travel

Developer Machine Setup.  Describe the process of a setting up a new developers machine in detail.  This is usually 'expected' to only take a day, but often it take 3-5 days in reality.

The development process, how work is tracked, assigned and updated and what tools are used.

How to test, what to test, when to test, where to test.

Coding standards including file naming conventions and language specific standards.

How to handle bugs, where to document them, how to go about fixing them.

deployment process, what are the key things to know for production pushes.

How to document, what to document, When to document.

Where stuff 'is', e.g. location(s) for Code, Data, Standards, Documentation, Links and other assets.

Making it modular will also let you or others update pieces separately, for instance the employees names and positions will change frequently as people come and go.

For each section I'd try hard to write it from a 'newbie' point of view.  Most important will be making sure it really makes sense to a newbie.  Your boss obviously is not the right person to review this as he is not the intended audience.  He's right to want it, just make sure the content doesn't end up being tested by him.  Also a 'newbie' both only has "1 week" as being a newbie... and only has one point of view.  So it's likely (and recommended) that the document will be refined with each new employee.  In fact it's a pretty good task to also assign them for their first week, i.e. "Update the newbie manual".

For Agile/SCRUM:

The hardest part of doing Agile and SCRUM is 'really' doing it.

For reading I would start at http://agilemanifesto.org/ and go from there.

I would also read the well-known http://www.halfarsedagilemanifesto.org/ which adds weight to the fact that you really have to embrace all the aspects for it to work.  If you have to heavily modify Agile for your organizations it's likely that people want the benefits - without using the correct processes.  This fact itself should be presented to ward off any half-assyness.


答:
It sounds like you're going to have to introduce some practices before you document them!

a) Source control - how do you store your sources and do revision control

b) Release management and tracking - how do you do a build, number a release, compare a current release candidate to a prior release

c) Problem management - how do you track bugs in your releases.

These are pretty basic things but they can take a lot of time (and possibly cost money) to implement.

Title: Writing a company-wide developer's handbook

Body:
I work for a small company. The software development arm of the company before I was hired consisted of one self-taught overworked guy. Now that I've been writing software for the company for a few years, I have been tasked with establishing formal company-wide software development practices. We currently have no guidelines, other than

Write code, test it, put it in a .zip file and send it to the client. Bonus points for TDD and version control.

My boss wants me to write a software developer's handbook which defines the general processes, protocols, tools, and guidelines we use to get things done. In other words, he wants a "This is what we do here" book to make it easier to get a new employee familiar with the way we do things, as well as to help my boss understand what his minions are doing and how they do it.

The way I see it, I'm laying a foundation and it needs to be done right. How would you go about choosing topics for such a handbook? Can you provide some example topics?

Side Note: If it matters, we are primarily a Microsoft .NET shop. And we are looking at agile practices such as XP and Scrum, but we may have to heavily modify them to make them work in our company.


答:
Topics that I would include in a developer's handbook:

Roles/positions within the department and their corresponding responsibilities

Developer machine software requirements (i.e. required development environment)

Where and how to access the source code repository

Development tools being used (e.g. IDE)

Coding style/standards

Documentation standards

Testing process

Build process

Deployment process

Support and issue management process

Where to get the most up-to-date version of this handbook

Keep in mind that this handbook should only contain items specific to development, and not company-wide information (which should be in an employee handbook).


问:
Can methods in an OOP language be considered as some kind of closure?
Consider a method m of a class A in an object-oriented language like Java or C++.

In the body of the method m it is possible to reference the member variables of the object on which the method is invoked. These variables are not defined in the method itself but are bound in the moment in which the method is invoked.

Is this the same mechanism used for closures (binding non-local names using the context) or, if not, what are the differences?

In other words, would it be possible to view an object with its methods as a collection of closures (the methods) that are closed over some common data (the object's member variables)?

答:
Yes, a method is a closure, from a different perspective.  A closure is a function with state associated with it, and a method is a function with an object (state) associated with it.  The difference is the paradigm.  In object-oriented programming, a lot of emphasis is placed on the object itself, which the methods are part of.  Whereas in functional programming (where the term "closure" comes from,) the emphasis is on the functions, that happen to have state that they close around.

It's quite possible to emulate objects in a functional language, by creating a list containing several closures that all close around the same state data.  (This is how CLOS creates objects, IIRC.)  And object-oriented that implement closures tend to make them work under the hood by having the compiler create special objects that implement the appropriate interface for the closure.

So yeah, the two concepts are quite equivalent; the only real difference is the paradigm.


问:
Which things instantly ring alarm bells when looking at code?
I attended a software craftsmanship event a couple of weeks ago and one of the comments made was "I'm sure we all recognize bad code when we see it" and everyone nodded sagely without further discussion.

This sort of thing always worries me as there's that truism that everyone thinks they're an above average driver. Although I think I can recognize bad code I'd love to learn more about what other people consider to be code smells as it's rarely discussed in detail on people's blogs and only in a handful of books. In particular I think it'd be interesting to hear about anything that's a code smell in one language but not another.

I'll start off with an easy one:

Code in source control that has a high proportion of commented out
  code - why is it there? was it meant
  to be deleted? is it a half finished
  piece of work? maybe it shouldn't have
  been commented out and was only done
  when someone was testing something
  out? Personally I find this sort of
  thing really annoying even if it's just the odd line here and there, but when you see large blocks interspersed with the rest of the code it's totally unacceptable. It's
  also usually an indication that the rest of
  the code is likely to be of dubious
  quality as well.

答:
getters all over the place make me freak out.

and a special thing: getters delegating to other getters.

this is bad because it means the person who wrote that doesn't understand the basic of object-oriented, which is encapsulation, which means where the data is, the methods that act on that data should be.

delegation is for one method not all the getters. the principle is "tell, dont's ask"; tell one thing to an object to do, don't ask it for one thousand things and then do it yourself.

getters freak me out, cause it means other oop principles are going to be violated hard core.


答:
Use of Source Control

Which source control tool you are using.

Syntax of common commands / tools in the IDE.

Branching / merge strategy.

What should the unit of a commit be?  How long is too long to have a file checked out / not committed?

What level of "doneness" does a commit / check-in denote?  Compiles? Unit tests pass? Reviewed?

What is expected to be included in the notes for a commit / check-in.

Rollback procedures.


问:
Combine jquery/jqueryui/qtip/custom javascript into one minified file
I'm using jQuery, jQueryUi and qTip in my web application alongside custom JavaScript I've written.  All three of the JavaScript libraries I mentioned above are licensed under the MIT license.  From what I've read, I just need to include a copy of the MIT license for each of those libraries in my web application.

Is it OK to put each license as a separate file underneath a "licenses" directory of my project?  So, I would have a licenses directory with "jQuery-MIT-LICENSE.txt", "jQueryUi-MIT-LICENSE.txt" and "qTip-MIT-LICENSE.txt" in it.  Or, do I need to put the licenses right at the top of the JavaScript files?  Confused about where exactly these licenses need to be put in my web application...

What I'm ultimately looking to do is combine all of the JavaScript files into one minified version for faster loading and I want to put the licenses in whatever is the proper place...

答:
JQuery puts this in their minified version, so I would say you would need to include something similar for each library you are including into the file for each library.

/*! jQuery v1.7.1 jquery.com | jquery.org/license */


问:
Is premature optimization really the root of all evil?
A colleague of mine today committed a class called ThreadLocalFormat, which basically moved instances of Java Format classes into a thread local, since they are not thread safe and "relatively expensive" to create. I wrote a quick test and calculated that I could create 200,000 instances a second, asked him was he creating that many, to which he answered "nowhere near that many". He's a great programmer and everyone on the team is highly skilled so we have no problem understanding the resulting code, but it was clearly a case of optimizing where there is no real need. He backed the code out at my request. What do you think? Is this a case of "premature optimization" and how bad is it really?

答:
I've often seen this quote used to justify obviously bad code or code that, while its performance has not been measured, could probably be made faster quite easily, without increasing code size or compromising its readability.

In general, I do think early micro-optimizations may be a bad idea. However, macro-optimizations (things like choosing an O(log N) algorithm instead of O(N^2)) are often worthwhile and should be done early, since it may be wasteful to write a O(N^2) algorithm and then throw it away completely in favor of a O(log N) approach.

Note the words may be: if the O(N^2) algorithm is simple and easy to write, you can throw it away later without much guilt if it turns out to be too slow. But if both algorithms are similarly complex, or if the expected workload is so large that you already know you'll need the faster one, then optimizing early is a sound engineering decision that will reduce your total workload in the long run.

Thus, in general, I think the right approach is to find out what your options are before you start writing code, and consciously choose the best algorithm for your situation. Most importantly, the phrase "premature optimization is the root of all evil" is no excuse for ignorance. Career developers should have a general idea of how much common operations cost; they should know, for example,

that strings cost more than numbers

that dynamic languages are much slower than statically-typed languages

the advantages of array/vector lists over linked lists, and vice versa

when to use a hashtable, when to use a sorted map, and when to use a heap

that (if they work with mobile devices) "double" and "int" have similar performance on desktops (FP may even be faster) but "double" may be a hundred times slower on low-end mobile devices without FPUs;

that transferring data over the internet is slower than HDD access, HDDs are vastly slower than RAM, RAM is much slower than L1 cache and registers, and internet operations may block indefinitely (and fail at any time).

And developers should be familiar with a toolbox of data structures and algorithms so that they can easily use the right tools for the job.

Having plenty of knowledge and a personal toolbox enables you to optimize almost effortlessly. Putting a lot of effort into an optimization that might be unnecessary is evil (and I admit to falling into that trap more than once). But when optimization is as easy as picking a set/hashtable instead of an array, or storing a list of numbers in double[] instead of string[], then why not? I might be disagreeing with Knuth here, I'm not sure, but I think he was talking about low-level optimization whereas I am talking about high-level optimization.

Remember, that quote is originally from 1974. In 1974 computers were slow and computing power was expensive, which gave some developers a tendency to overoptimize, line-by-line. I think that's what Knuth was pushing against. He wasn't saying "don't worry about performance at all", because in 1974 that would just be crazy talk. Knuth was explaining how to optimize; in short, one should focus only on the bottlenecks, and before you do that you must perform measurements to find the bottlenecks.

Note that you can't find the bottlenecks until you have written a program to measure, which means that some performance decisions must be made before anything exists to measure. Sometimes these decisions are difficult to change if you get them wrong (for example, if you choose to write your software in JavaScript instead of C#/Java, your code will have a much lower performance ceiling, which might be fine or frustrating depending on whether you hit that ceiling and how hard it is to overcome it when it is reached). For this reason, it's good to have a general idea of what things cost so you can make reasonable decisions when no hard data is available.

How early to optimize, and how much to worry about performance, depends on the job. When writing scripts that you'll only run a few times, worrying about performance at all is usually a complete waste of time. But if you work for Microsoft or Oracle and you're working on a library that thousands of other developers are going to use in thousands of different ways, it may pay to optimize the hell out of it, so that you can cover all the diverse use cases efficiently. Even so, the need for performance must always be balanced against the need for readability, maintainability, elegance, extensibility, and so on.

OwnerDisplayName: Craig Day

ContentLicense: CC BY-SA 4.0


问:
What are some things you have read that inspired and guided you as a programmer?
For example, being a beginner, I find a lot of inspiration and direction from reading this post by Bryan Woods.</p>

答:
it's a very short list, made of two books :

head first - design patterns

clean code


问:
Write once, run anywhere. Is it still relevant?
Since Oracle bought Sun and Apple have decided not to continue developing their JVM, is the "write once and run everywhere" model still relevant or has web services/SOA reduced it to an edge case?</p>

答:
Yes, it's still relevant.

If you live in a part of the world that has highly available, ultra-fast Internet access, you're lucky.

Even if you're that lucky, and the webservice you wish to use is that lucky, you still have to suffer the issues of latency, and the fallacies of distributed computing.

Just imagine for a moment what it would be like to use something like Photoshop through a browser.

So desktop applications probably aren't going away anytime soon. Which means that if you want to target multiple platforms/architectures, you need to care about write once, run anywhere.

As Yar points out it doesn't terribly matter how you get WORA, whether you use a VM, or cross-translation. The important question is whether or not you wish to target multiple platforms in the first place.

(Historical note: everyone seems to think of Java when they hear "VM", but virtual machines were old news long before Java was on the scene.)


问:
Connecting mobile apps to a web service; What is it called and where do I start?
I have some basic knowledge of iOS development and I want to now start connecting my apps to databases hosted on the internet, so that users will have access to remote / public data that pertains to my app.

My problem is that after searching the internet for some advice, I realised I don't even know what this type of programming is called? From my perusing it doesn't even appear to have a common moniker, and this is making it really difficult for me to find any advice on how to even begin learning to connect my apps to a web database.

So my questions are, what on earth is this discipline called? And, how can I get started in learning it?

答:
There are several options.

A current popular one is your server having a REST API that gives back JSON data.

Then in your app, you can make URL requests that will give back the JSON data (XML is another option). Parse the data and use as needed.

It is not nearly as simple as it sounds to set up the first time, but the key points are:

1) You will need to create a REST API

2) You will need to parse the data in the iphone app


问:
Interpreting gprof profiling output
I am practicing algorithm and data structures. Therefore, I keep profiling my programs. Here is an example output from gprof:

```<code>Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ns/call  ns/call  name
 29.76      2.58     2.58                             _IO_vfscanf_internal
 14.30      3.82     1.24                             ____strtof_l_internal
 11.71      4.84     1.02                             memcpy
  7.84      5.52     0.68  8400000    80.95    80.95  insertorupdate
  5.94      6.03     0.52                             _int_malloc
  5.77      6.53     0.50                             round_and_return
  3.81      6.86     0.33                             _IO_sputbackc
  3.23      7.14     0.28                             strlen
  2.88      7.39     0.25                             __strcmp_ia32
  2.13      7.58     0.19                             __isoc99_scanf
  2.13      7.76     0.19                             fgets
  2.02      7.94     0.18                             _IO_getline_info
  1.27      8.05     0.11                             __mpn_lshift
  1.21      8.15     0.11                             __memchr_sse2_bsf
  0.87      8.23     0.08                             malloc
  ... rest ...
</code>```

But I found it hard to understand what this means. For example, my program takes a lot of time in standard functions, I guess it should be good, right? Because, if one of my functions were consuming most of the time, that could mean I was doing something wrong. But as I say, I am not sure if I am interpreting this correctly, so any suggesting or pointers reading this is welcome.

答:
It's not good nor bad.

Imagine I tell you that I spend 45 minutes to travel from point A to point B. Is it fast? Is it slow? Does it mean I spend too much time? Or not? Until I say what is the point A, what is the point B, and what are my speed expectations, you can't tell anything.

Profiler results are similar. They don't tell you that something is absolutely bad or if your code is perfect performance-wise. They just show you raw results, letting you to interpret and study them.

You may have a valid case where one of your methods will spend a large amount of time doing something, because, well, it is expected to spend a large amount of time, since it has lots of work to do. Or maybe it's a sign that you must optimize this part of the code, because you expected this method to be at least one thousand times faster then it is actually.

Profiling helps by giving you some hints. SQL profilers, in this way, are maybe easy to understand:

If you see that when loading a web page, your web application sends the exact same query with the exact same parameters ten times, there is probably something wrong in your code, because you should do the query only once.

If you see that when loading a web page, a simple query takes 1.2 seconds, while you expected it to take a few milliseconds, there is a good sign that you or your colleagues forgot an index on a table or did something wrong with the query.

In the same way, code profilers:

Show that the same method is called again and again: sometimes, that's what you want. Sometimes, it may indicate a bug.

Show the time spent by a method. Depending on the case, either it's expected, or there is a bug.

This means that the purpose of a profiler is not to tell that your code is good or bad, - this is what requirements and acceptance testing is about -, but to identify the bottlenecks when you fail to met one of the non-functional requirements related to performance.

Title: Interpreting gprof profiling output


问:
Is it an absolute must that we ignore/delete all compiled files before committing?
I am working on a Drupal theme. I am going to be using "intermediary" languages to develop it, ie Stylus for styles, and CoffeeScript for some of the front-end scripts.

I am going to be using a git hosting service to be able to share the code among colleges. I am also going to be using it to update the code locally and then push onto hosting service, to be later pulled by the live drupal site.

This makes things really elegant.

However, I have noticed that a lot of developers tend to .gitignore all compiled code.

If it were a good practice, I would've loved to follow it, if and only if there wasn't this one issue: recompiling all the code that is needed in order for the theme to work out correctly.

This means that when I do a pull, I will have to recompile all the CSS and JavaScript code. Now, if I were to do a pull on the live site, there's a risk that a user goes to the site right at the moment I do the pull. No styles and scripts will be loaded on the user's end, so long as the code hasn't compiled.

Of course, compiling takes about a second, and the user might probably think to him/herself "meh, it was just my internet connection."

But there is also the issue that the server doesn't have the compilers installed to begin with. So now, I would do a pull, but there will be no styles, and no scripts.

Is it an absolute must that I delete all compiled code, or can I go ahead and include them in the commit?

答:
Yes, you must delete all compiled code. Source control is for, well, the source code, not the compiled files. The worst scenario is when developers commit the compiled binaries. Your case is not the same, since you're not committing large binaries which are diff-unfriendly, but still, keep your source control free of everything you don't need to run the application.

What seems wrong in your case is the deployment process. Instead of pushing the code to the production server directly from the source control, you should rather, in the simplest case:

Load the source code,

Compile and/or optimize it,

Push the compiled version to the server.

If your website has lots of visits, you may need a more complicated flow, using two servers, for example:

Load the source code,

Compile and/or optimize it,

Push the compiled version to the staging server,

Run a bunch of tests to ensure that the website is working on staging server,

Forward all the requests to the production server 2,

Once the production server 1 doesn't have any requests, push the compiled version to it,

Forward all the requests to the production server 1,

Once the production server 2 doesn't have any requests, push the complied version to it,

Use server 1 and server 2 again.


问:
Is it good practice to comment with issue number?
I saw many issue numbers from comments of jQuery code. (Actually, there were 69 issue numbers in jQuery code.) I think it would be good practice, but I've never seen any guidelines.

If it is a good practice, what are the guidelines for this practice?

答:
I think it's enough to add the issue number to the commit message when you commit the related fix to your source control system.

For example:

Bug #203: Database connections no longer time out after 30 seconds.

I find that adding issue numbers, developer names or dates that changes have been made in the code just pollutes the codebase and should really be managed externally by your source control system.


答:
Including the issue number in commit messages can be very useful when your source code is wired up with continuous integration. Applications like TeamCity will pull that information out and allow for better reporting.

With the above said I'm not 100% sure it pulls from code comments. Including issue numbers in the code works well if the issue numbers are persisted (e.g. you don't change issue trackers) and you don't have a lot of issues for a given project.

It is probably more helpful if you describe the problem and the solution so the next developer doesn't need to look up the issue number. The compiler or minifier will just remove your comments before the code is released into the wild so there should be no impact on the end result.

Title: Is it good practice to comment with issue number?

Body:
I saw many issue numbers from comments of jQuery code. (Actually, there were 69 issue numbers in jQuery code.) I think it would be good practice, but I've never seen any guidelines.

If it is a good practice, what are the guidelines for this practice?


问:
REST and redirecting the response
I'm developing a RESTful service.  Here is a map of the current feature set:

```<code>POST /api/document/file.jpg    (creates the resource)
GET /api/document/file.jpg     (retrieves the resource)
DELETE /api/document/file.jpg  (removes the resource)
</code>```

So far, it does everything you might expect.  I have a particular use case where I need to set up the browser to send a POST request using the multipart/form-data encoding for the document upload but when it is completed I want to redirect them back to the form.  I know how to do a redirect, but I'm not certain about how the client and server should negotiate this behavior.  Two approaches I'm considering:

On the server check for the multipart/form-data encoding and, if present, redirect to the referrer when the request is complete.

Add a service URI of /api/document/file.jpg/redirect to redirect to the referrer when the request is complete.

I looked into setting an X header (X-myapp-redirect) but you can't tell the browser which headers to use like this.  I manage the code for both the client and the server side so I'm flexible on solutions here.  Is there a best practice to follow here?

答:
This sounds like a pretty classic case of POST/Redirect/GET, and is sort of the expected behavior for web applications. I'd probably make that the default.

If you're not a fan of that approach for whatever reason, consider using AJAX (which means you can use the PUT approach mentioned by @sdg in a comment) with a standard 201 and the response body can contain the flash message to be displayed. The AJAX can do what you need it to do with the flash message, at that point.

Title: REST and redirecting the response