问:
When there's no TCO, when to worry about blowing the stack?
Every single time there's a discussion about a new programming language targetting the JVM, there are inevitably people saying things like:

"The JVM doesn't support tail-call optimization, so I predict lots of exploding stacks"

There are thousands of variations on that theme.

Now I know that some language, like Clojure for example, have a special recur construct that you can use.

What I don't understand is: how serious is the lack of tail-call optimization? When should I worry about it?

My main source of confusion probably comes from the fact that Java is one of the most succesful languages ever and quite a few of the JVM languages seems to be doing fairly well.  How is that possible if the lack of TCO is really of any concern?

答:
"The JVM doesn't support tail-call optimization, so I predict lots of exploding stacks"

Anyone who says this either (1) doesn't understand tail-call optimization, or (2) doesn't understand the JVM, or (3) both.

I'll start with the definition of tail-calls from Wikipedia (if you don't like Wikipedia, here's an alternative):

In computer science, a tail call is a subroutine call that happens inside another procedure as its final action; it may produce a return value which is then immediately returned by the calling procedure

In the code below, the call to bar() is the tail call of foo():

```<code>private void foo() {
    // do something
    bar()
}
</code>```

Tail call optimization happens when the language implementation, seeing a tail call, doesn't use normal method invocation (which creates a stack frame), but instead creates a branch. This is an optimization because a stack frame requires memory, and it requires CPU cycles to push information (such as the return address) onto the frame, and because the call/return pair is assumed to require more CPU cycles than an unconditional jump.

TCO is often applied to recursion, but that's not its only use. Nor is it applicable to all recursions. The simple recursive code to compute a factorial, for example, cannot be tail-call optimized, because the last thing that happens in the function is a multiplication operation.

```<code>public static int fact(int n) {
    if (n <= 1) return 1;
    else return n * fact(n - 1);
}
</code>```

In order to implement tail call optimization, you need two things:

A platform that supports branching in addition to subtroutine calls.

A static analyzer that can determine whether tail call optimization is possible.

That's it. As I've noted elsewhere, the JVM (like any other Turing-complete architecture) has a goto. It happens to have an unconditional goto, but the functionality could easily be implemented using a conditional branch.

The static analysis piece is what's tricky. Within a single function, it's no problem. For example, here's a tail-recursive Scala function to sum the values in a List:

```<code>def sum(acc:Int, list:List[Int]) : Int = {
  if (list.isEmpty) acc
  else sum(acc + list.head, list.tail)
}
</code>```

This function turns into the following bytecode:

```<code>public int sum(int, scala.collection.immutable.List);
  Code:
   0:   aload_2
   1:   invokevirtual   #63; //Method scala/collection/immutable/List.isEmpty:()Z
   4:   ifeq    9
   7:   iload_1
   8:   ireturn
   9:   iload_1
   10:  aload_2
   11:  invokevirtual   #67; //Method scala/collection/immutable/List.head:()Ljava/lang/Object;
   14:  invokestatic    #73; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
   17:  iadd
   18:  aload_2
   19:  invokevirtual   #76; //Method scala/collection/immutable/List.tail:()Ljava/lang/Object;
   22:  checkcast   #59; //class scala/collection/immutable/List
   25:  astore_2
   26:  istore_1
   27:  goto    0
</code>```

Note the goto 0 at the end. By comparison, an equivalent Java function (which must use an Iterator to imitate the behavior of breaking a Scala list into head and tail) turns into the following bytecode. Note that the last two operations are now an invoke, followed by an explicit return of the value produced by that recursive invocation.

```<code>public static int sum(int, java.util.Iterator);
  Code:
   0:   aload_1
   1:   invokeinterface #64,  1; //InterfaceMethod java/util/Iterator.hasNext:()Z
   6:   ifne    11
   9:   iload_0
   10:  ireturn
   11:  iload_0
   12:  aload_1
   13:  invokeinterface #70,  1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
   18:  checkcast   #25; //class java/lang/Integer
   21:  invokevirtual   #74; //Method java/lang/Integer.intValue:()I
   24:  iadd
   25:  aload_1
   26:  invokestatic    #43; //Method sum:(ILjava/util/Iterator;)I
   29:  ireturn
</code>```

Tail call optimization of a single function is trivial: the compiler can see that there is no code that uses the result of the call, so it can replace the invoke with a goto.

Where life gets tricky is if you have multiple methods. The JVM's branching instructions, unlike those of a general-purpose processor such as the 80x86, are confined to a single method. It's still relatively straightforward if you have private methods: the compiler is free to inline those methods as appropriate, so can optimize tail calls (if you're wondering how this might work, consider a common method that uses a switch to control behavior). You can even extend this technique to multiple public methods in the same class: the compiler inlines the method bodies, provides public bridge methods, and internal calls turn into jumps.

But, this model breaks down when you consider public methods in different classes, particularly in light of interfaces and classloaders. The source-level compiler simply does not have enough knowledge to implement tail-call optimizations. However, unlike "bare-metal" implementations, the *JVM( does have the information to do this, in the form of the Hotspot compiler (at least, the ex-Sun compiler does). I don't know whether it actually performs tail-call optimizations, and suspect not, but it could.

Which brings me to the second part of your question, which I'll rephrase as "should we care?"

Clearly, if your language uses recursion as its sole primitive for iteration, you care. But, languages that need this feature can implement it; the only issue is whether a compiler for said language can produce a class that can call and be called by an arbitrary Java class.

Outside of that case, I'm going to invite downvotes by saying that it's irrelevant. Most of the recursive code that I've seen (and I've worked with a lot of graph projects) is not tail-call optimizable. Like the simple factorial, it uses recursion to build state, and the tail operation is combination.

For code that is tail-call optimizable, it's often straightforward to translate that code into an iterable form. For example, that sum() function that I showed earlier can be generalized as foldLeft(). If you look at the source, you'll see that it's actually implemented as an iterative operation. Jörg W Mittag had an example of a state machine implemented via function calls; there are lots of efficient (and maintainable) state machine implementations that do not rely on function calls being translated into jumps.

I'll finish with something completely different. If you Google your way from footnotes in the SICP, you might end up here. I personally find that a much more interesting place than having my compiler replace JSR by JUMP.

Body:
"The JVM doesn't support tail-call optimization, so I predict lots of exploding stacks"

Anyone who says this either (1) doesn't understand tail-call optimization, or (2) doesn't understand the JVM, or (3) both.

I'll start with the definition of tail-calls from Wikipedia (if you don't like Wikipedia, here's an alternative):

In computer science, a tail call is a subroutine call that happens inside another procedure as its final action; it may produce a return value which is then immediately returned by the calling procedure

In the code below, the call to bar() is the tail call of foo():

private void foo() {
    // do something
    bar()
}

Tail call optimization happens when the language implementation, seeing a tail call, doesn't use normal method invocation (which creates a stack frame), but instead creates a branch. This is an optimization because a stack frame requires memory, and it requires CPU cycles to push information (such as the return address) onto the frame, and because the call/return pair is assumed to require more CPU cycles than an unconditional jump.

TCO is often applied to recursion, but that's not its only use. Nor is it applicable to all recursions. The simple recursive code to compute a factorial, for example, cannot be tail-call optimized, because the last thing that happens in the function is a multiplication operation.

public static int fact(int n) {
    if (n <= 1) return 1;
    else return n * fact(n - 1);
}

In order to implement tail call optimization, you need two things:

A platform that supports branching in addition to subtroutine calls.

A static analyzer that can determine whether tail call optimization is possible.

That's it. As I've noted elsewhere, the JVM (like any other Turing-complete architecture) has a goto. It happens to have an unconditional goto, but the functionality could easily be implemented using a conditional branch.

The static analysis piece is what's tricky. Within a single function, it's no problem. For example, here's a tail-recursive Scala function to sum the values in a List:

def sum(acc:Int, list:List[Int]) : Int = {
  if (list.isEmpty) acc
  else sum(acc + list.head, list.tail)
}

This function turns into the following bytecode:

public int sum(int, scala.collection.immutable.List);
  Code:
   0:   aload_2
   1:   invokevirtual   #63; //Method scala/collection/immutable/List.isEmpty:()Z
   4:   ifeq    9
   7:   iload_1
   8:   ireturn
   9:   iload_1
   10:  aload_2
   11:  invokevirtual   #67; //Method scala/collection/immutable/List.head:()Ljava/lang/Object;
   14:  invokestatic    #73; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
   17:  iadd
   18:  aload_2
   19:  invokevirtual   #76; //Method scala/collection/immutable/List.tail:()Ljava/lang/Object;
   22:  checkcast   #59; //class scala/collection/immutable/List
   25:  astore_2
   26:  istore_1
   27:  goto    0

Note the goto 0 at the end. By comparison, an equivalent Java function (which must use an Iterator to imitate the behavior of breaking a Scala list into head and tail) turns into the following bytecode. Note that the last two operations are now an invoke, followed by an explicit return of the value produced by that recursive invocation.

public static int sum(int, java.util.Iterator);
  Code:
   0:   aload_1
   1:   invokeinterface #64,  1; //InterfaceMethod java/util/Iterator.hasNext:()Z
   6:   ifne    11
   9:   iload_0
   10:  ireturn
   11:  iload_0
   12:  aload_1
   13:  invokeinterface #70,  1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
   18:  checkcast   #25; //class java/lang/Integer
   21:  invokevirtual   #74; //Method java/lang/Integer.intValue:()I
   24:  iadd
   25:  aload_1
   26:  invokestatic    #43; //Method sum:(ILjava/util/Iterator;)I
   29:  ireturn

Tail call optimization of a single function is trivial: the compiler can see that there is no code that uses the result of the call, so it can replace the invoke with a goto.

Where life gets tricky is if you have multiple methods. The JVM's branching instructions, unlike those of a general-purpose processor such as the 80x86, are confined to a single method. It's still relatively straightforward if you have private methods: the compiler is free to inline those methods as appropriate, so can optimize tail calls (if you're wondering how this might work, consider a common method that uses a switch to control behavior). You can even extend this technique to multiple public methods in the same class: the compiler inlines the method bodies, provides public bridge methods, and internal calls turn into jumps.

But, this model breaks down when you consider public methods in different classes, particularly in light of interfaces and classloaders. The source-level compiler simply does not have enough knowledge to implement tail-call optimizations. However, unlike "bare-metal" implementations, the *JVM( does have the information to do this, in the form of the Hotspot compiler (at least, the ex-Sun compiler does). I don't know whether it actually performs tail-call optimizations, and suspect not, but it could.

Which brings me to the second part of your question, which I'll rephrase as "should we care?"

Clearly, if your language uses recursion as its sole primitive for iteration, you care. But, languages that need this feature can implement it; the only issue is whether a compiler for said language can produce a class that can call and be called by an arbitrary Java class.

Outside of that case, I'm going to invite downvotes by saying that it's irrelevant. Most of the recursive code that I've seen (and I've worked with a lot of graph projects) is not tail-call optimizable. Like the simple factorial, it uses recursion to build state, and the tail operation is combination.

For code that is tail-call optimizable, it's often straightforward to translate that code into an iterable form. For example, that sum() function that I showed earlier can be generalized as foldLeft(). If you look at the source, you'll see that it's actually implemented as an iterative operation. Jörg W Mittag had an example of a state machine implemented via function calls; there are lots of efficient (and maintainable) state machine implementations that do not rely on function calls being translated into jumps.

I'll finish with something completely different. If you Google your way from footnotes in the SICP, you might end up here. I personally find that a much more interesting place than having my compiler replace JSR by JUMP.


问:
Is there a certain way that I have to include a library and its license?
I know this may be a dumb question, but I'm only 15 so I don't really know how the legal part of it works. When I choose a .dll to be included in my project, Visual Studio only includes the .dll file with my project (of course) so I just copy the license and stick it in a folder called licenses.

But now, I'm going to be making a program for a contest so I need to make sure I have the licenses done right or I'll get disqualified. So is there any specific location I have to keep the licenses in my project, is there a way for Visual Studio to automatically copy the license the way it does with .dll files and is there anything else I have to watch out for legally?

PS: If it matters, the libraries I'm planning on using right now are WriteableBitmapEx and AvalonDock

Thanks

答:
I don't know if there's a standard way to include licenses.  Libraries are easy, in that if it's not included the correct way the application won't work.

Licenses are fuzzier, because each license can declare how users have to declare the component's usage.

In your specific cases, the two libraries use different licenses: Microsoft Public License and new BSD license.  So, you should pay attention to the details in the license about binary and source releases and act appropriately.

How you deliver licenses or notifications can vary.  I've seen it done through releases notes that can be as simple as a text file in the file system that gets delivered with your binary files.  I've also seen About boxes in client applications display this type of information.  Have also seen this written as part of log file output when a service starts.

From my experience the "how" of the legal commitments can vary.  As long as you can show that you supply the copyright notice, etc, it can be as simple as including some text files and referencing them in the release notes.

Hope this helps.

ContentLicense: CC BY-SA 3.0


问:
Unit testing to prove balanced tree
I've just built a self-balancing tree (red-black) in Java (language should be irrelevant for this question though), and I'm trying to come up with a good means of testing that it's properly balanced.

I've tested all the basic tree operations, but I can't think of a way to test that it is indeed well and truly balanced.  I've tried inserting a large dictionary of words, both pre-sorted and un-sorted.  With a balanced tree, those should take roughly the same amount of time, but an unbalanced tree would take significantly longer on the already-sorted list.  But I don't know how to go about testing for that in any reasonable, reproducible way.  (I've tried doing millisecond tests on these, but there's no noticeable difference - probably because my source data is too small.)

Is there a better way to be sure that the tree is really balanced?  Say, by looking at the tree after it's created and seeing how deep it goes?  (That is, without modifying the tree itself by adding a depth field to each node, which is just wasteful if you don't need it for anything other than testing.)

答:
One way to do this would be to create a method on your tree that measures the depth of the tree at a given node. You don't have to store the value, and if you use such a getDepth() method only for testing, then there's no extra overhead for normal tree operations. The getDepth() method would recursively traverse its child nodes and return the maximum depth found.

Once you have that, you can then check that your whole tree is balanced by recursing over each node of the tree, and verifying a condition something like:

```<code>Math.abs(getDepth(left) - getDepth(right)) <= 1
</code>```

Title: Unit testing to prove balanced tree

Body:
One way to do this would be to create a method on your tree that measures the depth of the tree at a given node. You don't have to store the value, and if you use such a getDepth() method only for testing, then there's no extra overhead for normal tree operations. The getDepth() method would recursively traverse its child nodes and return the maximum depth found.

Once you have that, you can then check that your whole tree is balanced by recursing over each node of the tree, and verifying a condition something like:

Math.abs(getDepth(left) - getDepth(right)) <= 1


问:
When are Getters and Setters Justified?
Getters and setters are often criticized as being not proper OO. On the other hand, most OO code I've seen has extensive getters and setters.

When are getters and setters justified? Do you try to avoid using them? Are they overused in general?

If your favorite language has properties (mine does) then such things are also considered getters and setters for this question. They are the same thing from an OO methodology perspective. They just have nicer syntax.

Sources for Getter/Setter Criticism (some taken from comments to give them better visibility):

http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html

http://typicalprogrammer.com/?p=23

http://c2.com/cgi/wiki?AccessorsAreEvil

http://www.darronschall.com/weblog/2005/03/no-brain-getter-and-setters.cfm

http://www.adam-bien.com/roller/abien/entry/encapsulation_violation_with_getters_and

http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html

To state the criticism simply: Getters and Setters allow you to manipulate the internal state of objects from outside of the object. This violates encapsulation. Only the object itself should care about its internal state.

And an example

Procedural version of code:

```<code>struct Fridge
{
    int cheese;
}

void go_shopping(Fridge fridge)
{
     fridge.cheese += 5;
}
</code>```

Mutator version of code:

```<code>class Fridge
{
     int cheese;

     void set_cheese(int _cheese) { cheese = _cheese; }
     int get_cheese() { return cheese; }
 }

void go_shopping(Fridge fridge)
{
     fridge.set_cheese(fridge.get_cheese() + 5);
}
</code>```

The getters and setters made the code much more complicated without affording proper encapsulation. Because the internal state is accessible to other objects we don't gain a whole lot by adding these getters and setters.

The question has been previously discussed on Stack Overflow:

https://stackoverflow.com/questions/565095/java-are-getters-and-setters-evil

https://stackoverflow.com/questions/996179

答:
My approach is this -

When I expect to diddle with the data later on, a getter/setter is justified. Also, if change is happening, I often push the data into a getter/setter.

If it's a POD structure, I leave the slots available.

On a more abstract level, the question is "who manages the data", and that depends on the project.

ContentLicense: CC BY-SA 4.0

Title: When are Getters and Setters Justified?

ContentLicense: CC BY-SA 2.5


问:
Should I make up my own HTTP status codes? (a la Twitter 420: Enhance Your Calm)
I'm currently implementing an HTTP API, my first ever.

I've been spending a lot of time looking at the Wikipedia page for HTTP status codes, because I'm determined to implement the right codes for the right situations. Listed on that page is a code with number 420, which is a custom code that Twitter used to use for rate limiting.

There is already a code for rate limiting, though. It's 429.

This led me to wonder why they would set a custom one, when there is already a use case. Is that just being cute? And if so, then which circumstances would make it acceptable to return a different status code, and what, if any problems may clients have with it?

I read somewhere that Mozilla doesn't implement the joke 418: I’m a teapot response, which makes me think that clients choose which status codes they implement. If that's true, then I can imagine Twitter's funny little enhance your calm code being problematic.

Unless I'm mistaken, and we can appropriate any code number to mean whatever we like, and that only convention dictates that 404 means not found, and 429 means take it easy.

答:
This question delves into the issue a bit. But the thing is, while you can technically create any status code you want, creating a status code outside of the traditional scope of status code meanings only makes your API more obtuse and arcane to others. Unless that is the point, and the API you are creating is so utterly amazing that everyone will gladly change their coding to follow your lead so what does it matter anyway right?

It boils down to this: Any standard can be broken. But if you break it what do you gain or lose by doing so?

In general, in cases where you can do something different but the standards imply standards, it is best to adhere to the standards unless there is a very strong and compelling reason to veer away from established standards. In the case of Twitter’s 420: Enhance Your Calm they are creating a response code that clearly speaks to a unique situation they face. Which is slowing down requests without denying service.

OwnerDisplayName: Max Bucknell

OwnerDisplayName: JakeGould


答:
The whole of the Internet is built on conventions. We call them RFCs. While nobody will come and arrest you if you violate an RFC, you do run the risk that your service will not interoperate with the rest of the world. And if that happens, you run the risk of your startup not getting any customers, your business getting bad press, your stockholders revolting, your getting laid off permanently, etc.

HTTP status codes have their own IANA registry, each one traceable back to the RFC (or in one case, I-D) that defined it.

In the particular case of Twitter's strange 420 status code versus the standard 429 status code defined in RFC 6585, the most likely explanation is that the latter was only recently defined; the RFC dates to April 2012. We see that Twitter only uses 420 in the previous deprecated version 1 of its API; the current API version 1.1 actually uses the 429 status code. So it's clear that Twitter needed a status code for this and defined their own; once a standard one was available they switched to it.

Best practice, of course, is to stick as closely to the standards as possible. When you read RFCs, you will almost always find words like "MUST" and "SHOULD"; these have specific meanings when you are building your application, which you can find in RFC 2119.

Title: Should I make up my own HTTP status codes? (a la Twitter 420: Enhance Your Calm)

Body:
I'm currently implementing an HTTP API, my first ever.

I've been spending a lot of time looking at the Wikipedia page for HTTP status codes, because I'm determined to implement the right codes for the right situations. Listed on that page is a code with number 420, which is a custom code that Twitter used to use for rate limiting.

There is already a code for rate limiting, though. It's 429.

This led me to wonder why they would set a custom one, when there is already a use case. Is that just being cute? And if so, then which circumstances would make it acceptable to return a different status code, and what, if any problems may clients have with it?

I read somewhere that Mozilla doesn't implement the joke 418: I’m a teapot response, which makes me think that clients choose which status codes they implement. If that's true, then I can imagine Twitter's funny little enhance your calm code being problematic.

Unless I'm mistaken, and we can appropriate any code number to mean whatever we like, and that only convention dictates that 404 means not found, and 429 means take it easy.

OwnerDisplayName: Michael Hampton


答:
Having getters and setters does not in itself break encapsulation.  What does break encapsulation is automatically adding a getter and a setter for every data member (every field, in java lingo), without giving it any thought. While this is better than making all data members public, it is only a small step away.

The point of encapsulation is not that you should not be able to know
or to change the object's state from outside the object, but that you
should have a reasonable policy for doing it.

Some data members may be entirely internal to the object, and should
have neither getters nor setters.

Some data members should be read-only, so they may need getters but
not setters.

Some data members may need to be kept consistent with each other. In
such a case you would not provide a setter for each one, but a single
method for setting them at the same time, so that you can check the
values for consistency.

Some data members may only need to be changed in a certain way, such
as incremented or decremented by a fixed amount. In this case, you
would provide an increment() and/or decrement() method, rather
than a setter.

Yet others may actually need to be read-write, and would have both a getter
and a setter.

Consider an example of a class Person.  Let's say a person has a name, a social security number, and an age.  Let's say that we do not allow people to ever change their names or social security numbers.  However, the person's age should be incremented by 1 every year.  In this case, you would provide a constructor that would initialize the name and the SSN to the given values, and which would initialize the age to 0.  You would also provide a method incrementAge(), which would increase the age by 1.  You would also provide getters for all three.  No setters are required in this case.

In this design you allow the state of the object to be inspected from outside the class, and you allow it to be changed from outside the class.  However, you do not allow the state to be changed arbitrarily.  There is a policy, which effectively states that the name and the SSN cannot be changed at all, and that the age can be incremented by 1 year at a time.

Now let's say a person also has a salary.  And people can change jobs at will, which means their salary will also change.  To model this situation we have no other way but to provide a setSalary() method!  Allowing the salary to be changed at will is a perfectly reasonable policy in this case.

By the way, in your example, I would give the class Fridge the putCheese() and takeCheese() methods, instead of get_cheese() and set_cheese().  Then you would still have encapsulation.

```<code>public class Fridge {
  private List objects;
  private Date warranty;

  /** How the warranty is stored internally is a detail. */
  public Fridge( Date warranty ) {
    // The Fridge can set its internal warranty, but it is not re-exposed.
    setWarranty( warranty );
  }

  /** Doesn't expose how the fridge knows it is empty. */
  public boolean isEmpty() {
    return getObjects().isEmpty();
  }

  /** When the fridge has no more room... */
  public boolean isFull() {
  }

  /** Answers whether the given object will fit. */
  public boolean canStore( Object o ) {
    boolean result = false;

    // Clients may not ask how much room remains in the fridge.
    if( o instanceof PhysicalObject ) {
      PhysicalObject po = (PhysicalObject)o;

      // How the fridge determines its remaining usable volume is a detail.
      // How a physical object determines whether it fits within a specified
      // volume is also a detail.
      result = po.isEnclosedBy( getUsableVolume() );
    }

     return result;
  }

  /** Doesn't expose how the fridge knows its warranty has expired. */
  public boolean isPastWarranty() {
    return getWarranty().before( new Date() );
  }

  /** Doesn't expose how objects are stored in the fridge. */
  public synchronized void store( Object o ) {
    validateExpiration( o );

    // Can the object fit?
    if( canStore( o ) ) {
      getObjects().add( o );
    }
    else {
      throw FridgeFullException( o );
    }
  }

  /** Doesn't expose how objects are removed from the fridge. */
  public synchronized void remove( Object o ) {
    if( !getObjects().contains( o ) ) {
      throw new ObjectNotFoundException( o );
    }

    getObjects().remove( o );

    validateExpiration( o );
  }

  /** Lazily initialized list, an implementation detail. */
  private synchronized List getObjects() {
    if( this.list == null ) { this.list = new List(); }
    return this.list;
  }

  /** How object expiration is determined is also a detail. */
  private void validateExpiration( Object o ) {
    // Objects can answer whether they have gone past a given
    // expiration date. How each object "knows" it has expired
    // is a detail. The Fridge might use a scanner and
    // items might have embedded RFID chips. It's a detail hidden
    // by proper encapsulation.
    if( o implements Expires && ((Expires)o).expiresBefore( today ) ) {
      throw new ExpiredObjectException( o );
    }
  }

  /** This creates a copy of the warranty for immutability purposes. */
  private void setWarranty( Date warranty ) {
    assert warranty != null;
    this.warranty = new Date( warranty.getTime() )
  }
}
</code>```

Title: When are Getters and Setters Justified?

Body:
Getters and setters are often criticized as being not proper OO. On the other hand, most OO code I've seen has extensive getters and setters.

When are getters and setters justified? Do you try to avoid using them? Are they overused in general?

If your favorite language has properties (mine does) then such things are also considered getters and setters for this question. They are the same thing from an OO methodology perspective. They just have nicer syntax.

Sources for Getter/Setter Criticism (some taken from comments to give them better visibility):

http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html

http://typicalprogrammer.com/?p=23

http://c2.com/cgi/wiki?AccessorsAreEvil

http://www.darronschall.com/weblog/2005/03/no-brain-getter-and-setters.cfm

http://www.adam-bien.com/roller/abien/entry/encapsulation_violation_with_getters_and

http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html

To state the criticism simply: Getters and Setters allow you to manipulate the internal state of objects from outside of the object. This violates encapsulation. Only the object itself should care about its internal state.

And an example

Procedural version of code:

```<code>struct Fridge
{
    int cheese;
}

void go_shopping(Fridge fridge)
{
     fridge.cheese += 5;
}
</code>```

Mutator version of code:

```<code>class Fridge
{
     int cheese;

     void set_cheese(int _cheese) { cheese = _cheese; }
     int get_cheese() { return cheese; }
 }

void go_shopping(Fridge fridge)
{
     fridge.set_cheese(fridge.get_cheese() + 5);
}
</code>```

The getters and setters made the code much more complicated without affording proper encapsulation. Because the internal state is accessible to other objects we don't gain a whole lot by adding these getters and setters.

The question has been previously discussed on Stack Overflow:

https://stackoverflow.com/questions/565095/java-are-getters-and-setters-evil

https://stackoverflow.com/questions/996179

Body:
Having getters and setters does not in itself break encapsulation.  What does break encapsulation is automatically adding a getter and a setter for every data member (every field, in java lingo), without giving it any thought. While this is better than making all data members public, it is only a small step away.

The point of encapsulation is not that you should not be able to know
or to change the object's state from outside the object, but that you
should have a reasonable policy for doing it.

Some data members may be entirely internal to the object, and should
have neither getters nor setters.

Some data members should be read-only, so they may need getters but
not setters.

Some data members may need to be kept consistent with each other. In
such a case you would not provide a setter for each one, but a single
method for setting them at the same time, so that you can check the
values for consistency.

Some data members may only need to be changed in a certain way, such
as incremented or decremented by a fixed amount. In this case, you
would provide an increment() and/or decrement() method, rather
than a setter.

Yet others may actually need to be read-write, and would have both a getter
and a setter.

Consider an example of a class Person.  Let's say a person has a name, a social security number, and an age.  Let's say that we do not allow people to ever change their names or social security numbers.  However, the person's age should be incremented by 1 every year.  In this case, you would provide a constructor that would initialize the name and the SSN to the given values, and which would initialize the age to 0.  You would also provide a method incrementAge(), which would increase the age by 1.  You would also provide getters for all three.  No setters are required in this case.

In this design you allow the state of the object to be inspected from outside the class, and you allow it to be changed from outside the class.  However, you do not allow the state to be changed arbitrarily.  There is a policy, which effectively states that the name and the SSN cannot be changed at all, and that the age can be incremented by 1 year at a time.

Now let's say a person also has a salary.  And people can change jobs at will, which means their salary will also change.  To model this situation we have no other way but to provide a setSalary() method!  Allowing the salary to be changed at will is a perfectly reasonable policy in this case.

By the way, in your example, I would give the class Fridge the putCheese() and takeCheese() methods, instead of get_cheese() and set_cheese().  Then you would still have encapsulation.

public class Fridge {
  private List objects;
  private Date warranty;

  /** How the warranty is stored internally is a detail. */
  public Fridge( Date warranty ) {
    // The Fridge can set its internal warranty, but it is not re-exposed.
    setWarranty( warranty );
  }

  /** Doesn't expose how the fridge knows it is empty. */
  public boolean isEmpty() {
    return getObjects().isEmpty();
  }

  /** When the fridge has no more room... */
  public boolean isFull() {
  }

  /** Answers whether the given object will fit. */
  public boolean canStore( Object o ) {
    boolean result = false;

    // Clients may not ask how much room remains in the fridge.
    if( o instanceof PhysicalObject ) {
      PhysicalObject po = (PhysicalObject)o;

      // How the fridge determines its remaining usable volume is a detail.
      // How a physical object determines whether it fits within a specified
      // volume is also a detail.
      result = po.isEnclosedBy( getUsableVolume() );
    }

     return result;
  }

  /** Doesn't expose how the fridge knows its warranty has expired. */
  public boolean isPastWarranty() {
    return getWarranty().before( new Date() );
  }

  /** Doesn't expose how objects are stored in the fridge. */
  public synchronized void store( Object o ) {
    validateExpiration( o );

    // Can the object fit?
    if( canStore( o ) ) {
      getObjects().add( o );
    }
    else {
      throw FridgeFullException( o );
    }
  }

  /** Doesn't expose how objects are removed from the fridge. */
  public synchronized void remove( Object o ) {
    if( !getObjects().contains( o ) ) {
      throw new ObjectNotFoundException( o );
    }

    getObjects().remove( o );

    validateExpiration( o );
  }

  /** Lazily initialized list, an implementation detail. */
  private synchronized List getObjects() {
    if( this.list == null ) { this.list = new List(); }
    return this.list;
  }

  /** How object expiration is determined is also a detail. */
  private void validateExpiration( Object o ) {
    // Objects can answer whether they have gone past a given
    // expiration date. How each object "knows" it has expired
    // is a detail. The Fridge might use a scanner and
    // items might have embedded RFID chips. It's a detail hidden
    // by proper encapsulation.
    if( o implements Expires && ((Expires)o).expiresBefore( today ) ) {
      throw new ExpiredObjectException( o );
    }
  }

  /** This creates a copy of the warranty for immutability purposes. */
  private void setWarranty( Date warranty ) {
    assert warranty != null;
    this.warranty = new Date( warranty.getTime() )
  }
}


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

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

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

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

答:
I disagree with "don't mock objects that you don't own" when your are unit testing.

Mocks purpose of existence is the fact that there will be modules, libraries, classes we will not own.

My suggestion for your scenario is mock the web service call.

Setup the mock in such a way that it returns data back to your module.

Make sure you cover all scenario eg when the data returned back is null, when the data returned back is valid etc.

And for the code that you own, your responsibility as a developer is to ensure that the code you are authoring performs as expected in all scenarios.


问:
Is curl something that's not expected to be installed on servers
Is curl something that's not expected to be installed on servers?
I'm working for a small development shop and 99% of the problems that I'm having is regarding curl. Most of the projects that I'm working on involves calling a web API. Most web API's suggests using curl by default since you have to pass in a POST data in the request. Every time I complain to my senior that the server that I'm working on doesn't have curl installed the excuse that I'm always getting is that curl is not needed you can always use file_get_contents.

So the question: is curl something that's not expected to be installed on servers that runs PHP, should I always develop using file_get_contents and not curl? Are there any advantages of using file_get_contents over curl or vise versa?

If it helps, the context here is wordpress plugins, shopify apps, drupal modules and other bits of code that a lot of people can install.

答:
The only way to be sure is to test features that you need. For example, in php, you can use Zend Framework's http client which comes with a socket adapter and a curl adapter. The you can test if curl module was available, if not then just use the socket adapter.

Using file_get_contents() for Api calls is not very convenient if you want to check status code and http headers and there's a whole lot more options you can set with curl.


问:
Confusion about inheritance
I know I might get downvoted for this, but I'm really curious.

I was taught that inheritance is a very powerful polymorphism tool, but I can't seem to use it well in real cases.

So far, I can only use inheritance when the base class is an abstract class.

Examples :

If we're talking about Product and Inventory, I quickly assumed that a Product is an Inventory because a Product must be inventorized as well. But a problem occured when user wanted to sell their Inventory item. It just doesn't seem to be right to change an Inventory object to it's subtype (Product), it's almost like trying to convert a parent to it's child.

Another case is Customer and Member. It is logical (at least for me) to think that a Member is a Customer with some more privileges. Same problem occurred when user wanted to upgrade an existing Customer to become a Member.

A very trivial case is the Employee case. Where Manager, Clerk, etc can be derived from Employee. Still, the same upgrading issue.

I tried to use composition instead for some cases, but I really wanted to know if I'm missing something for inheritance solution here.

My composition solution for those cases :

Create a reference of Inventory inside a Product. Here I'm making an assumption about that Product and Inventory is talking in a different context. While Product is in the context of sales (price, volume, discount, etc), Inventory is in the context of physical management (stock, movement, etc).

Make a reference of Membership instead inside Customer class instead of previous inheritance solution. Therefor upgrading a Customer is only about instantiating the Customer's Membership property.

This example is keep being taught in basic programming classes, but I think it's more proper to have those Manager, Clerk, etc derived from an abstract Role class and make it a property in Employee.

I found it difficult to find an example of a concrete class deriving from another concrete class.

Is there any inheritance solution in which I can solve those cases?

Being new in this OOP thing, I really really need a guidance.

Thanks!

答:
Maybe it would help if we implemented one of the above into a inheritance coding case.

Let's expand on item 2.

Customer's a basic object. Let says it has the following properties:

```<code>Customer {
customer_number,
debt,
name,
age.
}
</code>```

Creating a customer (Constructor):

```<code>Customer(customer_number, debt, name, age){...}
</code>```

It can buy:

```<code>//Purchase item means adding to the customer's debt to the store.
buy(Object o)
{
    debt = debt + o.price;
}
</code>```

Return:

```<code>//Return item means reducing the customer's debt (adding credit), minus a 10% restocking fee.
return(Object o)
{
    debt = debt - o.price * 0.9;
}
</code>```

It can do things like, print name, store debt/credit etc.

```<code>double get_debt()
{
    return debt;
}
</code>```

It has a minimal memory footprint as an object as it only contains four initialised properties, and basic level function.

But now we want to expand the Customer class into a Member class, it has new benefits to being a member, you have status points. And you don't have to pay a restocking fee. So everytime you buy something as a Member object, this gets automatically functioned.

```<code>Member extends Customer {
    status_points;
}
</code>```

You would want the ability to create a Member from scratch, or from an existing customer. Super calls the parent's method/constructor.

```<code>Member(customer_number, debt, name, age, new_status_points) {
    super(customer_number, debt, name, age);
    status_points = new_status_points);
}

Member(Customer a, new_status_points){
    super(a.customer_name, a.debt, a.name, a.age);
    status_points = new_status_points;
}
</code>```

Member's buy function changes (super calls the parent class):

```<code>@Override
buy(Object o)
{
    super.buy(o);
    status_points = status_points + o.price / 10;
}
</code>```

Member's return function with the member's bonus of no return fee.

```<code>@Override
return(Object o)
{
   debt = debt - o.price;
   status_points = status_points - o.price / 10;
}
</code>```

Member also has an addition function, printing their status level.

```<code>print_status()
{
    if(status_level < 1000)
    {
         Print("Bronze");
    }
    else if(status_level < 5000)
    {
         Print("Silver");
    }
    else
    {
         Print("Gold");
    }
}
</code>```

So extra functionality is added without having to recode and retest the basics.

Title: Confusion about inheritance

Body:
Maybe it would help if we implemented one of the above into a inheritance coding case.

Let's expand on item 2.

Customer's a basic object. Let says it has the following properties:

Customer {
customer_number,
debt,
name,
age.
}

Creating a customer (Constructor):

Customer(customer_number, debt, name, age){...}

It can buy:

//Purchase item means adding to the customer's debt to the store.
buy(Object o)
{
    debt = debt + o.price;
}

Return:

//Return item means reducing the customer's debt (adding credit), minus a 10% restocking fee.
return(Object o)
{
    debt = debt - o.price * 0.9;
}

It can do things like, print name, store debt/credit etc.

double get_debt()
{
    return debt;
}

It has a minimal memory footprint as an object as it only contains four initialised properties, and basic level function.

But now we want to expand the Customer class into a Member class, it has new benefits to being a member, you have status points. And you don't have to pay a restocking fee. So everytime you buy something as a Member object, this gets automatically functioned.

Member extends Customer {
    status_points;
}

You would want the ability to create a Member from scratch, or from an existing customer. Super calls the parent's method/constructor.

Member(customer_number, debt, name, age, new_status_points) {
    super(customer_number, debt, name, age);
    status_points = new_status_points);
}

Member(Customer a, new_status_points){
    super(a.customer_name, a.debt, a.name, a.age);
    status_points = new_status_points;
}

Member's buy function changes (super calls the parent class):

@Override
buy(Object o)
{
    super.buy(o);
    status_points = status_points + o.price / 10;
}

Member's return function with the member's bonus of no return fee.

@Override
return(Object o)
{
   debt = debt - o.price;
   status_points = status_points - o.price / 10;
}

Member also has an addition function, printing their status level.

print_status()
{
    if(status_level < 1000)
    {
         Print("Bronze");
    }
    else if(status_level < 5000)
    {
         Print("Silver");
    }
    else
    {
         Print("Gold");
    }
}

So extra functionality is added without having to recode and retest the basics.


答:
The first thing that I'm going to suggest is that you take a few moments to read some of the other questions and answers on inheritance vs. composition that are here on Stack Exchange. There are several linked on the sidebar, for example.

I'll just address your first example:

Inventory shouldn't inherit from Product.(Are you selling an inventory? How do I take that home?)

Neither should Product inherit from Inventory. How is a salable item, such as a laptop, a list of things for sale?

Your composition solution for this one seems kind of backwards to me, as well. I would think of an Inventory as having information on (Holding references to) many different Products. It might also hold information that the Product itself does not know. (How many XYZ_Laptop_Products are in stock? How many are we getting in next week?)

BTW, for a concrete example, XYZ_Laptop_Product might inherit from Electronic_Product, which might inherit from Product. Then again, you might only have one Product class, and the only ways in which a laptop differs from a pair of socks are the stock number, price, and description fields.

Title: Confusion about inheritance

Body:
I know I might get downvoted for this, but I'm really curious.

I was taught that inheritance is a very powerful polymorphism tool, but I can't seem to use it well in real cases.

So far, I can only use inheritance when the base class is an abstract class.

Examples :

If we're talking about Product and Inventory, I quickly assumed that a Product is an Inventory because a Product must be inventorized as well. But a problem occured when user wanted to sell their Inventory item. It just doesn't seem to be right to change an Inventory object to it's subtype (Product), it's almost like trying to convert a parent to it's child.

Another case is Customer and Member. It is logical (at least for me) to think that a Member is a Customer with some more privileges. Same problem occurred when user wanted to upgrade an existing Customer to become a Member.

A very trivial case is the Employee case. Where Manager, Clerk, etc can be derived from Employee. Still, the same upgrading issue.

I tried to use composition instead for some cases, but I really wanted to know if I'm missing something for inheritance solution here.

My composition solution for those cases :

Create a reference of Inventory inside a Product. Here I'm making an assumption about that Product and Inventory is talking in a different context. While Product is in the context of sales (price, volume, discount, etc), Inventory is in the context of physical management (stock, movement, etc).

Make a reference of Membership instead inside Customer class instead of previous inheritance solution. Therefor upgrading a Customer is only about instantiating the Customer's Membership property.

This example is keep being taught in basic programming classes, but I think it's more proper to have those Manager, Clerk, etc derived from an abstract Role class and make it a property in Employee.

I found it difficult to find an example of a concrete class deriving from another concrete class.

Is there any inheritance solution in which I can solve those cases?

Being new in this OOP thing, I really really need a guidance.

Thanks!


问:
OOP PHP make separate classes or one
I'm studying OOP PHP and working on a small personal project but I have hard time grasping some concepts. Let's say I have a list of items, each item belongs to subcategory, and each subcategory belongs to category.

So should I make separate classes for category (with methods to list all categories, add new category, delete category), class for subcategories and class for items? Or should I make creating, listing and deleting categories as methods for item class?

Both category and subcategory are very simple and basically consist of ID, Name and parentID (for subcategory).

答:
As categories and subcategories form a tree structure, it will be quite inconvenient to represent that as members of an item. It becomes really convoluted if there is a non-zero chance that some day a subcategory might arise that has subcategories of its own.

What I gather from your description, the only difference between a category and a subcategory is that a category does not have a parent. In that case, I would model category and subcategory as one class (called Category), where the top-level categories are identified by the fact that the parentID field is NULL/empty.

This leads to the advise to use two separate classes, Item and Category. An Item can belong to a Category without knowing if it is a top-level category or a subcategory further down the tree.

Title: OOP PHP make separate classes or one


答:
If you search around for inheritance from concrete classes, you will find that you are not alone in your question.

In fact, in the large majority of cases, inheritance trees are only 2 or 3 levels deep and only the leaf classes (those that are not used as base class) tend to be concrete.

Inheritance is mostly a powerful tool because it can bring common interfaces or abstractions to light.

Title: Confusion about inheritance


问:
Not assigning Bugs to a specific user
My question: Is there a benefit to NOT assigning a Bug to a particular developer? Leaving it to the team as-a-whole?

Our department has decided to be more Agile by not assigning Bugs/Defects to individuals. Using Team Foundation Server 2012, we'll place all Bugs in a development team's "Area" but leave the "Assigned To" field blank.
The idea is that the team will create a Task work item which will be assigned to an individual and the Task will link to the Bug. The Team as a whole will therefore take responsibility for the Bug, not an individual, aligning to Scrum - apparently.

I see the down side. The reporting tools built into TFS become less useful when you cannot sort by assigned vs unassigned, let alone sorting by which user Bugs are assigned.

Is there a benefit I'm not seeing? Besides encouraging teamwork by putting the responsibility on the team-as-a-whole instead of an individual?

答:
If there are multiple team members that are capable of working in each area of the software, then one advantage of not assigning issues to individual developers is that you don't have to think explicitly about the possibility that certain developers would get overloaded with issues, because they are the natural choice for most of them. Instead, the workload tends to get distributed more evenly over the whole team, because everybody picks up what he thinks he can handle.

To keep the reporting tools more useful, I would recommend against creating separate Task work items. Instead, when a developer starts to work on a Bug, he should assign the Bug to himself to make it clear that he is working on that item.

Title: Not assigning Bugs to a specific user


问:
MVC Design Pattern to Combine Multiple Models for use
In my design, I have multiple models and each model has a controller. I need to use all the models to process some operation. Most examples I see are pretty simple with 1 view, 1 controller, and 1 model. How would you get all these models together?

Only ways I can think of are

1) Have a top-level controller which has a reference to every controller. Those controllers will have a getter/setter function for their model.

Does this violate MVC because every controller should have a model?

2) Have an Intermediate class to combine every model into a one model. Then you create a controller for that new super model.

Do you know of any better ideas? Thanks.

答: You started from the wrong idea that there is a one-to-one relation between controllers and models in MVC. There is no such requirement. In fact, an MVC controller should use as many classes from the MVC model as it needs to perform its operations.</p>


答:
The idea is that the team will create a Task work item which will be assigned to an individual and the Task will link to the Bug.

So there will be an individual assigned to the bug and thus the only question is if that information is put in the bug tracking system or not.

You are in the situation where you have several systems handling related things and you wonder where to put things which could be set in several.  Having redundant information is bad (it has a tendency to desynchronize itself, especially if the link is manual), but not having the needed information where it is needed is often worse.

The question is now about the purposes of a bug tracking system.  For the team, it is a way to manage bugs.  But it also often a way to communicate with the requester and if you are using it that way, not filling fields in the bug tracking system (let it be assignee, planning information, suggested work-arounds or whatever) will break that communication and leaves the impression that the bug is ignored, especially if the information is now available only in a system which is not accessible by the requester.  And if the bug system is used to track who has the right to access customer data under NDA related to the bug, you'll have to fill it.

TLDR: that will depend on what you are using your bug tracking system for, in the flows I'm familiar with, it would not be wise.

Title: Not assigning Bugs to a specific user

Body:
My question: Is there a benefit to NOT assigning a Bug to a particular developer? Leaving it to the team as-a-whole?

Our department has decided to be more Agile by not assigning Bugs/Defects to individuals. Using Team Foundation Server 2012, we'll place all Bugs in a development team's "Area" but leave the "Assigned To" field blank.
The idea is that the team will create a Task work item which will be assigned to an individual and the Task will link to the Bug. The Team as a whole will therefore take responsibility for the Bug, not an individual, aligning to Scrum - apparently.

I see the down side. The reporting tools built into TFS become less useful when you cannot sort by assigned vs unassigned, let alone sorting by which user Bugs are assigned.

Is there a benefit I'm not seeing? Besides encouraging teamwork by putting the responsibility on the team-as-a-whole instead of an individual?


问:
Writing generic code when your target is a C compiler
I need to write some algorithms for a PIC micro controller. AFAIK, the official tools support either assembler or a subset of C.

My goal is to write the algorithms in a generic and reusable way without losing any runtime or memory performance. And if possible, I would like to do this without increasing the development time much and compromising the readability and maintainability much either.

What I mean by generic and reusable is that I don't want to commit to types, array sizes, number of bits in a bit field etc. All these specifications, IMHO, point to C++ templates, but there's no compiler for it for my target. C macro metaprogramming is another option, but, again my opinion, that greatly reduces readability and increases development time.

I believe what I'm looking for is a decent C++ to C translator, but I'd like to hear anything else that satisfies the above requirements. Maybe a translator from another high-level language to C that produces very efficient code, maybe something else.

Please note that I have nothing against C, I just wish templates were available in it.

答:
Unless you have at least 3 use-cases where the algorithms will be used with different types and sizes, you are not going to do good job of the genericity anyway. So don't bother too much.

I'd recommend writing it in plain C using custom typedefs for all types (except things that are obviously size_t, int or such) and #defines for any relevant sizes. Than you can adjust the algorithms easily by changing those definitions. You can put the definitions in one header that you can easily override for the use-cases.

You can also use the C's poor man's template system, the preprocessor. Like define a macro, that will get a type and expand to definition of the function for that type. Or define the parameters to expand, include a header/source to define the functions and undefine the parameters again. The later does not convolute diagnostics as much and is probably easier to manage.

Something like:

sort.h:

```<code> void sort_##SORT_TYPE(SORT_TYPE *begin, SORT_TYPE *end);
</code>```

IIRC you'll need some wrapper macro to get the definition expanded appropriate number of times.

sort.c:

```<code> void sort_##SORT_TYPE(SORT_TYPE *begin, SORT_TYPE *end)
 {
     // whatever
     if(SORT_LESS(i, j)) // ...
     // ..
 }
</code>```

using:

```<code> #define SORT_TYPE int
 static inline int less(int x, int y) { return x < y; }
 #define SORT_LESS less
 #include "sort.h"
 #include "sort.c" // you only do this in a .c file
 #undef SORT_TYPE
 #undef SORT_LESS
</code>```

Body:
Unless you have at least 3 use-cases where the algorithms will be used with different types and sizes, you are not going to do good job of the genericity anyway. So don't bother too much.

I'd recommend writing it in plain C using custom typedefs for all types (except things that are obviously size_t, int or such) and #defines for any relevant sizes. Than you can adjust the algorithms easily by changing those definitions. You can put the definitions in one header that you can easily override for the use-cases.

You can also use the C's poor man's template system, the preprocessor. Like define a macro, that will get a type and expand to definition of the function for that type. Or define the parameters to expand, include a header/source to define the functions and undefine the parameters again. The later does not convolute diagnostics as much and is probably easier to manage.

Something like:

sort.h:

 void sort_##SORT_TYPE(SORT_TYPE *begin, SORT_TYPE *end);

IIRC you'll need some wrapper macro to get the definition expanded appropriate number of times.

sort.c:

 void sort_##SORT_TYPE(SORT_TYPE *begin, SORT_TYPE *end)
 {
     // whatever
     if(SORT_LESS(i, j)) // ...
     // ..
 }

using:

 #define SORT_TYPE int
 static inline int less(int x, int y) { return x < y; }
 #define SORT_LESS less
 #include "sort.h"
 #include "sort.c" // you only do this in a .c file
 #undef SORT_TYPE
 #undef SORT_LESS


问:
Good example of complex code using TDD
What would be a good example of the use of TDD in large, real-life, complex, projects?  All the examples I've seen so far are toy projects for the purpose of a book or a paper...

Can you name an open-source project that heavily uses TDD? Preferably in C++ but I can read Java and C# or other similar languages.

答:
JUnit was developed 100% test-driven. In fact, it was developed 100% test-driven in JUnit, which as Kent Beck has said a couple of times was a truly mindbending exercise.

I believe Sun's ZFS filesystem was developed test-driven.

The ikj interpreter for the Ioke programming language (JVM), the ikc interpreter for the Ioke programming language (CLI), the entire Ioke core and standard library, and in fact the language itself was developed 100% test-driven (actually behavior-driven).

Title: Good example of complex code using TDD


问:
Multiple Instantiate of 1 class affects memory?
I am currently struggling with memory handling. I have an if statement and each case instantiate a new object from a class. Does this affect the memory allocation in java?

```<code>switch()
{
case 1:
test t1 = new test();

case 2:
test t2 = new test();

case 3:
test t3 = new test();

case 4:
test t4 = new test();

case 5:
test t5 = new test();

case 6:
test t6 = new test();

}
</code>```

答:
No, it doesn't.

Each time your case is executed, exactly one object is allocated (except if you pass in an unhandled value, in which case nothing happens). The fact that there are a lot of new statements in your code doesn't change that; what counts is how often an allocation statement is executed, not when its byte code is loaded.


答: In MVC, Model View and Controller are independent modules. The Controller have ultimate power to determine which Model has to be sent to View to serve the request.

Title: MVC Design Pattern to Combine Multiple Models for use

Body:
In my design, I have multiple models and each model has a controller. I need to use all the models to process some operation. Most examples I see are pretty simple with 1 view, 1 controller, and 1 model. How would you get all these models together?

Only ways I can think of are

1) Have a top-level controller which has a reference to every controller. Those controllers will have a getter/setter function for their model.

Does this violate MVC because every controller should have a model?

2) Have an Intermediate class to combine every model into a one model. Then you create a controller for that new super model.

Do you know of any better ideas? Thanks.


问:
Who controls the npm registry?
NPM's docs say that anyone can call npm-publish and add his own NPM package to the "official" registry.

Who controls this registry?

How reliable is it for production deployment scenarios?

What's preventing people from spamming this registry? Is there any moderation/QA process?

答:
The Handling Module Name Disputes page explains a particular case: what should be done if you want to use for your package a name which is already in use by a not valuable or never updated package. According to this page, if you can't resolve the dispute with the original author, you should email i@izs.me (Isaac Z. Schlueter, the lead developer of npm).

For a more general case of registry control (spam, abuse), the community itself should deal with the issues.

There is a gentle way to deal with minor issues (for example a person who believes that his Hello World is extremely valuable for the community, thus polluting the registry): if nobody downloads the package, statistics would be an excellent indicator that other people should think twice before downloading it.

For more serious problems, contact Isaac.

How reliable is it for production deployment scenarios?

Do you talk about the scenario where third-party packages are updated from npm through continuous deployment?

In this scenario, the problem of something going wrong is minor:

Continuous deployment updates the third-party package on server 1,

Tests are run,

Test results turn red,

The original version is restored; the server 1 may come back online now,

No other servers would be updated. It's now up to the developer to go and see why tests failed.

Title: Who controls the npm registry?


问:
Advise how to write a simple test for this javascript snippet?
I'm trying to start unit testing (not using any testing frameworks) for my javascripts.

Here's one example of it.

```<code>var obj = {};

obj.disableBtn = function ($btn, style) {
  $btn.attr('disabled','disabled').addClass('disabled').removeClass(style);
};
</code>```

The use case is as such:

```<code>obj.disableBtn($('.submit'), 'btn-blue');
</code>```

What it does is simply add the disabled attribute, add the disabled class, and remove the btn-blue style.

Please advise how would a typical test case look like in this case.

I have a little knowledge on testing using assert(), but have no idea how to go about it when it involves verifying the result on HTML elements.

答:
I appreciate that you do assert()'s. They're simple and powerful, and non-magical.

You can test anything that is readable by code. Think "if I can if this, then I can assert it".

If you want to write a test for something that updates markup, then the question is 'how can I with code get the information I want to test?'.

If you're using jQuery (it seems so) then have you test get the button with the selector $('.myButton'). How would you write and if to check the property of this button? I think you can do that. Then use the same code in your assert. You're closer than you think, you can do it!


问:
Good fix vs Quick fix
Let's start from this principle: quality is a feature that you can't add to a project in the middle of the development process.

This is the scenario: two weeks to go live with my project and, one of the developers added a specific method used only for one web application to our framework (Our framework is a bounce of java classes used to extract content from MongoDB, Alfresco, mySql and it's used by web applications). I'm the team leader and I told him to generalize the method to keep the framework to keep reusable but he said "no, I prefer don't do that because there are a lot of bugs that need to be fixed". The manager is agree with him and of course I'm not.

Is it better to made extra effort to keep a framework free from any specific implementation (probably used only by one web application) or just add the methods because it works?

So, my question is: is it correct to write code that only works or is better to write code that works but it doesn't sucks (i.e. adding embedded value, specific methods, extra classes, add column to database, etc)? How is it possible to justify the extra time (to be honest, this kind of fix requires 10 minutes extra to write a good generic code) to the management? How is possible to argue it's the right way to write code to young developers and PM? in general, good fix or quick fix?

Ah, 10 minutes after I get the email from PM, he asked me why on a url of application 2 there was the name of application 1 during the login?

I like to quote Jeff Atwood: "Don't leave "broken windows" (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is discovered. "

Excerpt From: Hyperink. "How-To-Stop-Sucking-And-Be-Awesome-Instead." iBooks.

答:
The answers to a lot of those questions start "All else being equal...".

If you have two weeks to go to ship, then your manager will have a lot of tough calls between dropping buggy features, patching the bugs in a hurry, or sticking to the ideal of a clean, well-developed application framework and possibly delivering late or over budget. Ultimately what matters is that the customers are happy and pay up, so I think you have to trust his judgement. What might appear to be 10 minutes extra work to you to stick to the design might not just be 10 minutes for a junior; what might appear to you to be great reusable code might appear to be gold-plating to the client. The quote from Jeff Attwood is all well and good, but if you have more broken windows than you have time to fix then you have to prioritise the ones that the rain is pouring through...

Of course when he takes the opposite view to you, you then need to be the one that speaks up for revisiting all the quick fixes and ensuring regression testing once the immediate deadlines are passed.

Title: Good fix vs Quick fix


问:
Is throwing an error in unpredictable subclass-specific circumstances a violation of LSP?
Let's say I wanted to create a Java List<String> (see spec) implementation that uses a complex subsystem, such as a database or file system, for its store so that it acts as a persistent collection rather than an in-memory one.

So here's a skeleton implementation:

```<code>class DbBackedList implements List<String> {
  private DbBackedList() {}
  /** Returns a list, possibly non-empty */
  public static getList() { return new DbBackedList(); }
  public String get(int index) {
    return Db.getTable().getRow(i).asString();  // may throw DbExceptions!
  }
  // add(String), add(int, String), etc. ...
}
</code>```

My problem lies with the fact that the underlying DB API may encounter connection errors that are not specified in the List interface that it should throw.

My problem is whether this violates Liskov's Substitution Principle (LSP).

In his paper on LSP, Bob Martin actually gives an example of a PersistentSet that violates LSP. The difference is that his newly-specified Exception there is determined by the inserted value and so is strengthening the precondition. In my case the connection/read error is unpredictable and due to external factors and so is not technically a new precondition, merely an error of circumstance, perhaps like OutOfMemoryError which can occur even when unspecified.

In normal circumstances, the new Error/Exception might never be thrown. (The caller could catch if it is aware of the possibility, just as a memory-restricted Java program might specifically catch OOME.)

Is this therefore a valid argument for throwing an extra error and can I still claim to be a valid java.util.List (or pick your SDK/language/collection in general) and not in violation of LSP?

Edit: This argument might be more palatable if you consider a FileBackedList (more reliable "connection") rather than a DbBackedList.

If this does indeed violate LSP and thus not practically usable, I have provided two less-palatable alternative solutions as answers that you can comment on, see below.

Footnote: Use Cases

In the simplest case, the goal is to provide a familiar interface for cases when (say) a database is just being used as a persistent list, and allow regular List operations such as search, subList and iteration.

Another, more adventurous, use-case is as a slot-in replacement for libraries that work with basic Lists, e.g if we have a third-party task queue that usually works with a plain List:

new TaskWorkQueue(new ArrayList<String>()).start() which is susceptible to losing all it's queue in event of a crash, if we just replace this with:

new TaskWorkQueue(new DbBackedList()).start() we get a instant persistence and the ability to share the tasks amongst more than one machine.

In either case, we could either handle connection/read exceptions that are thrown, perhaps  retrying the connection/read first, or allow them to throw and crash the program (e.g. if we can't change the TaskWorkQueue code).

答:
To start with, your DBException hardly qualifies as Error:

subclasses of Error... are abnormal conditions that should never occur.

Note also that if you expect DBException to be thrown in overridden get, it must be unchecked one. Otherwise, your code won't compile, per JLS 8.4.8.3. Requirements in Overriding and Hiding:

A method that overrides or hides another method, including methods that implement abstract methods defined in interfaces, may not be declared to throw more checked exceptions than the overridden or hidden method...

With above said, it looks like yes, it would violate LSP - because as a user of Java Collections Framework, I would not expect List.get to throw runtime exception for any kind problem other than "programming mistakes", that is for something that is possible to avoid by changing the code (note, no matter how you change code, database connection won't be guaranteed).

If you look at the IndexOutOfBoundsException specified for List.get, it reads like one that programmer can avoid by preliminary bounds check:

if the index is out of range (index < 0 || index >= size())

Another runtime exception documented for Collections, including List, is ConcurrentModificationException and per API docs, it is also expected to be dealt with by correcting the code that caused it:

ConcurrentModificationException should be used only to detect bugs.

More detailed explanation for what I expect is provided in JCF Design FAQ. It addresses UnsupportedOperationException, but if you take a look at prior examples of IOOBE and CME, the reasoning fits these as well:

Won't programmers have to surround any code that calls optional operations with a try-catch clause in case they throw an UnsupportedOperationException?

It was never our intention that programs should catch these exceptions: that's why they're unchecked (runtime) exceptions. They should only arise as a result of programming errors, in which case, your program will halt due to the uncaught exception.

Suming up, if I wanted to expose database backed data as List (or any Collection for that matter) in a way that would be least confusing for users of my API, I would probably wrap that data into some helper object that would expose DB related exceptions only when used "outside" of collection context - that is, when client code would try to access the data expected to be stored "inside" the wrapper, not when collections of wrappers are carried over the client code.

For a concrete example how this could be done, take a look at java.util.concurrent.Future which wraps results of an asynchronous computation in a way that doesn't expose "internal", wrapped exceptions when carried over in collections.


答:
You may be confusing classes, which implement behaviour, and class instances, which can hold data which distinguishes one instance of a class from another.

For the simple situation you describe, you can create one basic category class, which defines the behaviours of

Having a name.

Having an id.

Containing a (possibly empty) list of items.

Having a (possibly empty) list of subcategories.

*Having a name" means allowing the name to be read and (optionally) updated.  Same for the lists.

You could also give it a parent id but this is not necessary if you always start from your top level category and work down - it depends on how you traverse the structure.  For the moment, let's assume you don't need it...

Anyway, having created this class, you then create successive instances of the class, giving each a name, adding items and subcategories etc.

Can you see that the behaviour for each instance is consistent?  Each instance may have a unique id, but the act of retrieving or updating that property is the same for all instances.

Now, if you do need your subcategories to know what their parent is, at this point I would consider having two different classes - one for top level categories and another for subcategories.  While having one class and leaving the "parent" property empty in top level categories sounds simple, it opens the potential for error, while also burdening top-level categories with surplus fields and methods that they will (or should) never use.  Consider these conflicting statements:

A top-level category should never have a parent

A sub-category always has a parent

You make a category a sub-category by giving it a parent

You can tell a top-level category because it has no parent

How do you avoid accidentally giving a top level category a parent?  Or accidentally removing the parent of a subcategory?  How do you detect these errors, after they have happened?  The only way to tell a top-level from a sub category is the thing you just broke!

On the other hand, if you have separate classes for top categories and sub-categories, then you can have a top-level category class which simply doesn't have a parent field or any parent-related methods, and a sub-category class which must have these.  You never accidentally try to find out the parent of a top-level category because that is something only sub-categories can have.

Of course, now you have the problem of the shared behaviour of top-level and sub-categories.  Once answer is to have a simpler category class from which they both inherit.  Another is to define a category interface and have both the top and sub category classes implement it.  Either way, code which only cares about general category behaviour can treat them both the same.

As for making category management the responsibility of items, I think you have that upside down.  Categories need to know something about items, because they contain them.  In most situations, items do not need to know anything about categories.  Categories are rarely essential properties of items; making your item implementation aware of categories means that if you change your category design, you have to also change your item design.  This is called tight coupling, which is generally seen as bad practice.  It may seem counter-intuitive at first, but it is generally better to design the different components of a system to know the least amount possible about other components, while exposing as little as possible about their own internal details.  This is known as separation of concerns (or "loose coupling").

As a final note, do consider if the id fields are necessary.  If these categories are stored in a database, it may be necessary if this part of your code might also change the category names.  But do remember that the "Bars" subcategory of "Bike Parts" can be uniquely identified as "/Bike Parts/Bars" and thus completely distinct from "/Venues/Bars".  Even if the numerical id is there in the DB, you might not want it in your web code - or not everywhere, anyway.  Consider whether you would want external sites linking to http://yoursite.com/Venues/Bars or http://yoursite.com/cat3/cat21.

If you haven't thought as far as persistence yet - or if the category structure would not be stored in a database - I would try implementing this without the ids, first.

Title: OOP PHP make separate classes or one

Body:
I'm studying OOP PHP and working on a small personal project but I have hard time grasping some concepts. Let's say I have a list of items, each item belongs to subcategory, and each subcategory belongs to category.

So should I make separate classes for category (with methods to list all categories, add new category, delete category), class for subcategories and class for items? Or should I make creating, listing and deleting categories as methods for item class?

Both category and subcategory are very simple and basically consist of ID, Name and parentID (for subcategory).


答: The LSP basically says the answer to "Will code that correctly uses this interface do the wrong thing if used with your implementation of it?" should be no.  Throwing new and different exceptions may cause code that thought it was handling all exceptions to fail when a new and unexpected exceptions show up.  If it is possible to map exceptions to ones already provided by the interface then that is a possible path to go down, but they have to map cleanly in the intent they are trying to communicate though. You don't want to map to a fatal error from a nonfatal error and vice versa.</p>

Title: Is throwing an error in unpredictable subclass-specific circumstances a violation of LSP?

Body:
Let's say I wanted to create a Java List<String> (see spec) implementation that uses a complex subsystem, such as a database or file system, for its store so that it acts as a persistent collection rather than an in-memory one.

So here's a skeleton implementation:

```<code>class DbBackedList implements List<String> {
  private DbBackedList() {}
  /** Returns a list, possibly non-empty */
  public static getList() { return new DbBackedList(); }
  public String get(int index) {
    return Db.getTable().getRow(i).asString();  // may throw DbExceptions!
  }
  // add(String), add(int, String), etc. ...
}
</code>```

My problem lies with the fact that the underlying DB API may encounter connection errors that are not specified in the List interface that it should throw.

My problem is whether this violates Liskov's Substitution Principle (LSP).

In his paper on LSP, Bob Martin actually gives an example of a PersistentSet that violates LSP. The difference is that his newly-specified Exception there is determined by the inserted value and so is strengthening the precondition. In my case the connection/read error is unpredictable and due to external factors and so is not technically a new precondition, merely an error of circumstance, perhaps like OutOfMemoryError which can occur even when unspecified.

In normal circumstances, the new Error/Exception might never be thrown. (The caller could catch if it is aware of the possibility, just as a memory-restricted Java program might specifically catch OOME.)

Is this therefore a valid argument for throwing an extra error and can I still claim to be a valid java.util.List (or pick your SDK/language/collection in general) and not in violation of LSP?

Edit: This argument might be more palatable if you consider a FileBackedList (more reliable "connection") rather than a DbBackedList.

If this does indeed violate LSP and thus not practically usable, I have provided two less-palatable alternative solutions as answers that you can comment on, see below.

Footnote: Use Cases

In the simplest case, the goal is to provide a familiar interface for cases when (say) a database is just being used as a persistent list, and allow regular List operations such as search, subList and iteration.

Another, more adventurous, use-case is as a slot-in replacement for libraries that work with basic Lists, e.g if we have a third-party task queue that usually works with a plain List:

new TaskWorkQueue(new ArrayList<String>()).start() which is susceptible to losing all it's queue in event of a crash, if we just replace this with:

new TaskWorkQueue(new DbBackedList()).start() we get a instant persistence and the ability to share the tasks amongst more than one machine.

In either case, we could either handle connection/read exceptions that are thrown, perhaps  retrying the connection/read first, or allow them to throw and crash the program (e.g. if we can't change the TaskWorkQueue code).


问:
Fastest way to check if two square 2D arrays are rotationally and reflectively distinct
The best idea I have so far is to rotate first array by {0, 90, 180, 270} degrees and reflect it horizontally or/and vertically. We basically get 16 variations [1] of first array and compare them with second array. if none of them matches the two arrays are rotationally and reflectively distinct.

I am wondering if there is more optimal solution than this brute-force approach?

[1]

```
0deg, no reflection
0deg, reflect over x
0deg, reflect over y
0deg, reflect over x and y
90deg, no reflection
...
```

答:
You might consider calculating a checksum for an array and compare the checksums of two arrays.

Checksums are order-independent; if two arrays have different checksums, they definitely cannot have the same elements in a different (e.g. rotated) arrangement.

If you have to compare arrays many times, you can cache the sums and save on re-calculation.


答:
I wouldn't worry too much about inheritance.  Polymorphism is more about interfaces than inheritance.  (Okay, sometimes a class will do the job and the interface is redundant, but in that case the class is really doing an interface's job in addition to a class's job.)

I find myself using inheritance in two cases:

In the first, I'm writing a new class, and an old class already does about half the work of the new one.  So I inherit from the old class and my new one is half written.  More commonly, I notice that I've got a bunch of classes with duplicate code.  So I pull that code into a single class and make all the others inherit from it.  (In most languages you can ony inherit from one other class, so you have to be a bit careful about this.)

In the second I have a class that does the job, but in some cases its calculations are wrong.  So I create a new class that inherits from the first and overrides the wrong (in this one case) method.  (Alternatively, you could make the first class more flexible.  Pick the method that gives you the cleanest code.  Some languages make inheritance easier than others.)

I'm sure there are other reasons, but for me, those are the most common.

Title: Confusion about inheritance


答:
MVC is better viewed as a logical rather than physical construct.

You are free to create a model out of other models or take the repository (if you have one) in its entirety as the model if you need to. Some frameworks for example promote the use of viewmodels for such purposes when you wish to create a single model that is consumed by the view.

Likewise in the view, you can create multiple views based on the viewmodel. Whilst the code for this may sit in one physical view, logically they are different.

If you find yourself passing round the same model for everything, this might indicate that you have a god object which is obviously best avoided.


答:
The best way to handle this is to actually write your algorithms in a language independent pseudo code.  Then, you can create a reference implementation in a language of choice, like C, carefully noting the edge cases that make this implementation tied to a particular memory model, data type model, byte sizes, bit handling capabilities, loop exit conditions weirdness ( think floating point ) types size overflow, etc. etc.

The reason this is a good strategy is that you will never achieve true portability with any known set of language tools, compilers, cross compilers, diagramers, prototypers.  It is just not truly tractable.

Once you have created a few reference implementations, ideally in very diverse languages ( think Lisp or Prolog ) you will be able to more fully identify, understand and anticipate how your code will adapt to different platforms; and learn how to write pseudo code, move carefully toward an implementation and track the edge cases and dependencies.

You should maintain the artifacts as you go down this implementation path, as these, like the high level pseudo code will help you to architect an alternate reference implemenation, suited to an arbitrary future platform.

This approach lets you arbitrarily add and subtract dependencies , weighing their utility against their possible future lock-in effects.  IE, if you decide to use a virtual memory subsystem , like the JVM, you will basically have to rewrite and refactor everything if you ever decide to implement the same pseudo code on an embedded processor....

Title: Writing generic code when your target is a C compiler

Body:
I need to write some algorithms for a PIC micro controller. AFAIK, the official tools support either assembler or a subset of C.

My goal is to write the algorithms in a generic and reusable way without losing any runtime or memory performance. And if possible, I would like to do this without increasing the development time much and compromising the readability and maintainability much either.

What I mean by generic and reusable is that I don't want to commit to types, array sizes, number of bits in a bit field etc. All these specifications, IMHO, point to C++ templates, but there's no compiler for it for my target. C macro metaprogramming is another option, but, again my opinion, that greatly reduces readability and increases development time.

I believe what I'm looking for is a decent C++ to C translator, but I'd like to hear anything else that satisfies the above requirements. Maybe a translator from another high-level language to C that produces very efficient code, maybe something else.

Please note that I have nothing against C, I just wish templates were available in it.


问:
Are "Compile to JavaScript" Frameworks Hostile to Continuous Integration?
Lately we've been looking at ways to improve automated testing and related tooling of our enterprise-level GWT web app. I've realized that in some ways, GWT is a bit hostile to automated testing, mainly because of the nature of the long GWT compile times from Java to JS. This makes unit testing somewhat challenging, but it also puts some roadblocks up for testing in a CI environment. I've also found out that some of our build and deployment processes are somewhat complicated due to the nature of GWT's compile process.

Is this a general problem for "compile to JS" frameworks for webapps? I don't have much experience with them, but I can see some potential problems for automated testing and continuous integration and deployment. Some issues I see:

Long build and compile times preventing quick deployments

Language the app is developed in != JS, preventing good unit testing

Obfuscated JS in the actual app makes it more like a executable than a web app

Are these issues present in other similar frameworks, or is this more a GWT issue?

答:
We factor our GWT code out into "core" and "gwt" projects.  The "core" project contains 100% pure Java, non-GWT code, and can be unit tested easily using regular JUnit.

How long does your build take?  Ours, with about 100 classes takes 1-2 minutes, barely noticeable.

With regards to your initial question -- I treat "compile to JavaScript" much the same as "compile to bytecode" or "compile to machine code", don't see why it would affect continuous integration.


答:
Divide your square into 8 smaller triangles.
compute a hash/checksum on each of these triangles.
This only requires one iteration over the entire square.

Now, in order for some symmetry to be present,
some of these triangles must be equal, and thus their hash values.
So, if all has values are different, you are done.

Otherwise, compare the triangles with the same hash values only.
This saves you some time, but it is of course a bit trickier to implement.

Title: Fastest way to check if two square 2D arrays are rotationally and reflectively distinct

Body:
The best idea I have so far is to rotate first array by {0, 90, 180, 270} degrees and reflect it horizontally or/and vertically. We basically get 16 variations [1] of first array and compare them with second array. if none of them matches the two arrays are rotationally and reflectively distinct.

I am wondering if there is more optimal solution than this brute-force approach?

[1]

```
0deg, no reflection
0deg, reflect over x
0deg, reflect over y
0deg, reflect over x and y
90deg, no reflection
...
```


答:
Once a team member decides to take on the task to fix the bug, every one should know. Otherwise, you could end up with multiple devs fixing the same problem. If something comes up, take yourself off of the task.

Management has to buy into the idea regardless of reporting. If Team A is comfortable with Developer X never fixing bugs, that's fine as long as they don't turn-around and blame poor team performance on this fact.

The philosophy is all well and good, but there has to be some management oversight. This is important when there is a certain bug no one wants to fix (too complicated, bad legacy code, or one of those "sometimes" bugs.). Either prompt for volunteers or assign it.

The goal is to get things done. You can't use "we're agile" as a reason for failure.

Title: Not assigning Bugs to a specific user


问:
How would you model an objects representing different phases of an entity life cycle?
I believe the scenario is common mostly in business workflows - for example: loan management

the process starts with a loan application, then there's the loan offer, the 'live' loan, and maybe also finished loans.

all these objects are related, and share many fields

all these objects have also many fields that are unique for each entity

the variety of objects maybe large, and the transformation between the may not be linear (for example: a single loan application may end up as several loans of different types)

How would you model this?

some options:

an entity for each type, each containing the relevant fields (possibly grouping related fields as sub entities) - leads to duplication of data.

an entity for each object, but instead of duplicating data, each object has a reference to it's predecessor (the loan doesn't contain the loaner details, but a reference to the loan application) - this causes coupling between the object structure, and the way it was created. if we change the loan application, it shouldn't effect the structure of the loan entity.

one large entity, with fields for the whole life cycle - this can create 'mega objects' with many fields. it also doesn't work well when there's a one to many or many to many relation between the phases.

答:
I'd start with one object with all the shared date in it.  All the other objects should have a reference to it so they can get that shared data.  Further, it would have references, direct or, sometimes, indirect, to all the other objects.  It could serve as the object representing all the related loans and associated documents.

Each of the other objects would contain, in addition to a reference to the shared data object, references to the other object to which they're closely related:  predecessor object, successor object or objects, and anything else that might be of interest.

It should now be possible to start with any object and quickly track down all the relevant information, none of which is stored twice.