问:
Manuals - How Up To Date?
If you have a product that has been in the market for a long time, but it is still in active development daily - how often should the manuals be updated? If your users are constantly updated to the bleeding edge version due to the fact that your organization sees fit that the latest bug fixes are always in the shipped version. Meaning, you could fix a bug one day and next day it is hitting production.</p>

答:
I would update the manual:

For each major release, and

When important new features become stable and mature enough that you know they're not going to change every five minutes.

Title: Manuals - How Up To Date?


问:
Thoughts on having a generic, reusable grid viewmodel
I'm developing a wpf-based application and I'm currently struggling to find the best way of supporting a recurring scenario in it.

This app uses grids a lot. There are a bunch of features I want in it that are meant to be used in grids, such as drag & drop, multiple row edition, conditional row coloring, etc. But at the same time, I want my data objects to derive from a specific, data-oriented class that is unaware of any UI context and could be used by a single form, with standalone editors.

Therefore, I'd like to have a DataGridViewModel class that will in turn expose two collections: Rows as DataGridRowViewModel and Columns as DataGridColumnViewModel. The row view model would expose a RowData property which will be the actual data object, while the column view model would have a PropertyDescriptor (from System.ComponentModel namespace) that will indicate which data object field the column is meant for.

You can think of the DataGridRowViewModel as a container for the "real" row object.

The goal is to allow separation of concerns between grid-specific functionalities (controlling row height, color, selection, etc) and data-specific functionalities, so that one doesn't need to know about the other. Ideally, a third component will be aware of both and ensure proper communication between the two layers (observing a data field and change the row color under condition x or y, for example).

Does this approach makes any sense? What kind of complications should I expect out of this (binding issues, performance and the likes)?

答:
We're aiming to do something similar in our web-based UI project, so what you're trying to achieve makes perfect sense to me.  The view model should be flat, so binding should be straightforward to achieve.

In our case, we found that we are using lists of data all over our project, but there were only three use cases for the list: "select one of these items" (single select button per row), "select one or more of these items" (checkboxes and a submit button), and "manage this list of items" (Add New button at the top, Edit and Delete buttons per row).  In any case, the columns of data are read only.

We're working to develop a component with a constructor that takes a parameter to describe which type of list is needed and a view model object that has 1-4 columns of display data plus an Id as a reference.  The component will figure out what the list should look like from there.  We made a custom annotation class to decorate the view model with:

```<code>[System.AttributeUsage(System.AttributeTargets.Property)]

public class ListViewColumn : System.Attribute
{
    private string _columnName;
    public int ColumnOrder;
    public string FormatString;

    public ListViewColumn(string columnName)
    {
        _columnName = columnName;
        ColumnOrder = 1;
        FormatString = null;
    }
}
</code>```

Usage:

```<code>    [ListViewColumn("Option Code", ColumnOrder = 1)]
    public string OptionCode { get; set; }

    [ListViewColumn("Version", ColumnOrder = 2)]
    public float Version { get; set; }

    [ListViewColumn("Description", ColumnOrder = 3)]
    public string Description { get; set; }
</code>```

If you were generating a list for the "Select One" metaphor (a class attribute can drive that), this would result in a list that looked similar to the following:

```<code>        Option Code   Version   Description
Select  101-10G       4.2       Whatever this thing is
Select  234-567       4.35      A clear description of this other thing
Select  456-987       2.9       Something completely different
</code>```

Using the same class to generate a "Manage" list would produce the following:

```<code>                                                                 Add New
Option Code   Version   Description
101-10G       4.2       Whatever this thing is                   Edit | Delete
234-567       4.35      A clear description of this other thing  Edit | Delete
456-987       2.9       Something completely different           Edit | Delete
</code>```

ContentLicense: CC BY-SA 3.0

Body:
We're aiming to do something similar in our web-based UI project, so what you're trying to achieve makes perfect sense to me.  The view model should be flat, so binding should be straightforward to achieve.

In our case, we found that we are using lists of data all over our project, but there were only three use cases for the list: "select one of these items" (single select button per row), "select one or more of these items" (checkboxes and a submit button), and "manage this list of items" (Add New button at the top, Edit and Delete buttons per row).  In any case, the columns of data are read only.

We're working to develop a component with a constructor that takes a parameter to describe which type of list is needed and a view model object that has 1-4 columns of display data plus an Id as a reference.  The component will figure out what the list should look like from there.  We made a custom annotation class to decorate the view model with:

[System.AttributeUsage(System.AttributeTargets.Property)]

public class ListViewColumn : System.Attribute
{
    private string _columnName;
    public int ColumnOrder;
    public string FormatString;

    public ListViewColumn(string columnName)
    {
        _columnName = columnName;
        ColumnOrder = 1;
        FormatString = null;
    }
}

Usage:

    [ListViewColumn("Option Code", ColumnOrder = 1)]
    public string OptionCode { get; set; }

    [ListViewColumn("Version", ColumnOrder = 2)]
    public float Version { get; set; }

    [ListViewColumn("Description", ColumnOrder = 3)]
    public string Description { get; set; }

If you were generating a list for the "Select One" metaphor (a class attribute can drive that), this would result in a list that looked similar to the following:

        Option Code   Version   Description
Select  101-10G       4.2       Whatever this thing is
Select  234-567       4.35      A clear description of this other thing
Select  456-987       2.9       Something completely different

Using the same class to generate a "Manage" list would produce the following:

                                                                 Add New
Option Code   Version   Description
101-10G       4.2       Whatever this thing is                   Edit | Delete
234-567       4.35      A clear description of this other thing  Edit | Delete
456-987       2.9       Something completely different           Edit | Delete


问:
Adding centralized logging mechanism to Project (Best Practice)
I want to add a logging mechanism to my project but I am afraid to have logging code spread all over the place.

I thus had the idea of having only one class Logger responsible for writing relevant information into the log, and all the other classes A, B, ... having a Logger object and just calling the corresponding logging function in that one Logger class instead of implementing logging function in classes A, B, directly.

```<code>class A {
  public:
    Logger logger;
    ...
    void foo {
       ...
       logger.log(this);
    }
};

...

class Logger {
  public:
    void log(A a);
    void log(B b);
...

};
</code>```

Is that considered good practice or what is a clean way of doing logging without cluttering the production code?

答:
It's worth the time to learn the log4* library, e.g., for reasons like hierarchical logging, filters, different output formats or targets (files, databases, instant messengers, ...).

But it will not remove the logging statements from your code, just a good starting point. To minimize logging code, you could either try Aspect Oriented Programming, that "weaves" statements into functions that match a specific pattern, or...

You could take advantage of your software architecture: Some architectures allow logging code at central sensitive points, e.g. message dispatchers or Dependency Injection containers etc.
IMHO it's a good idea to centralize exception handling (using a "security facade" pattern). This would make another central point for error logging.

Just some options.


问:
When to have bug triage meetings in SCRUM process?
I was reading an article that explains some solutions to the "unpredictable emergencies" situation during Agile sprints. The article suggests having triage to determine if issues are truly emergencies and if they should be worked on by resources involved in an active sprint:

So solution 1 is: a strong Product Owner who performs triage on all production issues. If it's a real production issue then by all means fix it. But I can guarantee that you'll find a good number of issues that should not be emergencies at all... BTW, a Product Owner performing triage in this way is what James Coplien calls a Firewall in his organizational patterns book.

The article also mentions a "solution 2":

Solution 2: Perform Triage - And Defer The Fix Until At Least The Next Sprint

The one thing the article didn't go into detail on was the triage itself. Are these meetings, properly scheduled? Or are they "cubicle" meetings started on-demand, very informal, to discuss the bug with relevant parties? Who should be involved in these triage meetings/discussions?

My questions are more general. I'm not going to ask everyone here to read the long article itself. The question is generally in regard to bug triage in Agile process.

答:
Triaging is not typically done as a meeting.  Teams do it differently, depending on the product, but on our team, the product owner triages the customer issues, and we rotate another team member as "triager of the day" for issues that testing finds.

The triager's job is not supposed to be debugging, but answering the following questions as efficiently as possible:

Is it a known bug, new bug, or user error?

If a new bug, which software team should be responsible for the fix?

How severe is the impact?  Is there a workaround, is it preventing further testing, etc.

Rough estimate of time to fix.

If the triager needs someone else's expertise, he calls him over.  If the triager feels it's severe enough to put something else on hold, he will have an informal chat about it with the product owner.  Otherwise, it goes into our backlog.  Most of the time, triaging an issue takes maybe 15 minutes and doesn't require involving anyone else.


问:
Decision for Unchecked Exceptions in Scala
As a java programmer, I have always been critical of Unchecked Exceptions. Mostly programmers use it as an en-route to coding easiness only to create trouble later. Also the programs (though untidy) with checked exceptions are much robust compared to unchecked counterparts.

Surprisingly in Scala, there is nothing called Checked Exceptions. All the Java checked and unchecked are unchecked in Scala.

What is the motivation behind this decision? For me it opens wide range of problems when using any external code. And if by chance the documentation is poor, it results in KILL.

答:
Checked exceptions in Java isn't such a bad thing. Of course ADTs may be better option for Scala but in Java, checked exceptions have their place and the tidy code argument is just clueless non-sense no matter how many blogs repeated it. It basically says that you should happily ignore severe and possibly repairable conditions that may happen in your system, because screw type system, pretty code makes your system robust automagically. Such reasoning also explains why so many Java coders voluntarily move their code into XMLs (Spring, Maven, etc. I miss the pretty part here though).

The reason for lack of checked exceptions in Scala given by M. Odersky below http://www.scala-lang.org/old/node/8787.html is unsurprisingly different and makes sense.

The problem with checked exceptions is best demonstrated by the map
  method on lists:

def map[B](f: A => B): List[B]

How to annotate map with @throws? If map does not get a @throws
  annotation itself then presumably you cannot pass it any function that
  has a @throws. That would introduce cumbersome restrictions and
  distinctions for the ways in which map can be used. Things would be
  better if we could state somehow that map throws all exceptions that
  its function argument throws. There are some effect systems that can
  express this, but so far every notation I have seen is too heavy.

Lukas Rytz is doing some research on lightweight effect systems that
  could be used to express the type of map and other common functions in
  a concise and precise way. It's research, so it's at present unclear
  to what degree we will succeed and how much of that can be put into
  Scala. Ideally, we'll be able to add it at some point as an optional
  type system. But it's much too early to make concrete predictions.

Cheers

Not sure but I think Java 8 lambdas are also restricted to unchecked exceptions. Methods in most (all?) new functional interfaces in JDK 8  (java.util.function.*) don't declare unchecked exceptions neither.


答:
The first thing to say is that almost everything a Scrum team works on should be discussed in Sprint Planning meetings in the usual way.  Whether a Story is a bug fix our new feature development, it is at this point that the Product Owner should put it in its place in a prioritised Sprint.

Secondly, disruptions to Sprints do occur - it's just a question of frequency.  If it's an occasional thing, the team as a whole, including its Product Owner should be prepared for the Sprint to suffer, and the PO should be onboard with that before people start working on unexpected tasks.

The main thing you need to consider is: is Scrum right for you?  It may not be.  Novice PO's often go through a phase in the first couple of months of trying to game the system, to somehow get more work out of the team.  I've seen newbie Product Owners describe the absence of a feature they thought of in the shower that morning as an urgent bug, in an effort to get more stuff onto the Sprint that the developers were prepared to commit to.  If this is what's happening, sick with Scrum and break in your new PO as gently add you can.  But if the nature of the team's job is that unexpected bugs, customer queries etc. need to be dealt with virtually every fortnight, I'd suggest that Scrum is not for you.  Kanban is a system of Agile Methodology that is much more flexible, and genuinely values responding to change over following a plan in a way that Scrum doesn't, on a fine enough timescale.  If you find yourself constantly trying to shoehorn emerging priorities into a system that doesn't really allow for that, try a different system.

Title: When to have bug triage meetings in SCRUM process?

Body:
I was reading an article that explains some solutions to the "unpredictable emergencies" situation during Agile sprints. The article suggests having triage to determine if issues are truly emergencies and if they should be worked on by resources involved in an active sprint:

So solution 1 is: a strong Product Owner who performs triage on all production issues. If it's a real production issue then by all means fix it. But I can guarantee that you'll find a good number of issues that should not be emergencies at all... BTW, a Product Owner performing triage in this way is what James Coplien calls a Firewall in his organizational patterns book.

The article also mentions a "solution 2":

Solution 2: Perform Triage - And Defer The Fix Until At Least The Next Sprint

The one thing the article didn't go into detail on was the triage itself. Are these meetings, properly scheduled? Or are they "cubicle" meetings started on-demand, very informal, to discuss the bug with relevant parties? Who should be involved in these triage meetings/discussions?

My questions are more general. I'm not going to ask everyone here to read the long article itself. The question is generally in regard to bug triage in Agile process.


答:
It depends.

Different agile teams have different processes because they have different needs. If you have a few dozen bugs coming in every day, an informal cube meeting is probably not going to cut it. If the majority of the bugs are user inputted, you need someone who just looks for dupes and can judge usability issues. If you're a small group, then stopping by the team lead's desk is good because then you can discuss needs and reproduction scenarios. If you're a few weeks before major scheduled release (yes, they happen in agile sometimes), you might need to triage more often,

What I've seen work best in average sized teams (5-7 devs) on average sized projects (9-18 months) without weird requirements (politics, governmental oversight, super high risk project, etc) is to have the triage meeting alongside your backlog grooming 1-2 days before sprint start. People can come by the team lead with things they think are more urgent (high impact customer issues, bugs blocking another team, data corruption). They then will make a call if the bug is severe enough - or the reporter trustworthy enough - that it shouldn't wait.

Yes, you should try not to interrupt the sprint, but people will do it, so might as well push them towards doing it the least disruptive way.


问:
What method should I use to populate a tree as I'm consuming data that is contained within the tree?
I have a tree that consists of 5 types of nodes - V, W, X, Y, and Z. V represents the root node, and a given tree has exactly one element of type V. A V contains one or more Ws, a W contains one or more Xs, an X contains one of more Ys, and a Y contains one or more Zs:

Looking at this, I decided to model this with the following class structure:

Not shown in the class structure are the data elements that are unique to each type of node along with the methods to access those data elements. However, each node does have a unique set of attributes and operations.

To give a perspective on size, there could be up to thousands of nodes at the Z level. It's going to be much smaller at the W level, as there are almost no cases of 1:1:1:1 mappings from W to Z.

My problem comes when I think about how to build this tree.

The data comes in what can be thought of as a stream. There is a unit that I'll refer to as DataChunk. A DataChunk contains the data for one or more levels of the tree. If the DataChunk contains data for a Z, then it also contains data for a Y, X, and W. However, a DataChunk that contains data for X will contain data for W, but not necessarily Y.

In a stream, the start of a DataChunk is marked off by a sync word. In a set of datagrams, each DataChunk is a single datagram. In a set of files, the DataChunk could be presented as a set of files where 1 file is one DataChunk or 1 file contains multiple DataChunks, each marked by the sync word. The order is not specified.

In order to build the tree, I need to accept a DataChunk and parse information out of it.

One approach would be to have each node accept a DataChunk object, parse the information out, and set its own attributes and then see if it has a matching child to pass the node to. If the corresponding child exists, pass the data chunk to it. If the corresponding child doesn't exist, create it and then pass the data chunk to it. However, this leaves me with a mutable object - after construction, I can pass an arbitrary DataChunk into any node and change the tree. This also appears to be a violation of SRP, as each data node is responsible for not only the data associated with it, but to help build the tree.

Another approach may be to have some kind of Builder approach, but this would balloon my classes to 10 - I would need the node data class and the builder class. It also seems like this would be rather inefficient, since the Builder would essentially be a second tree with a mutable interface that would return the tree structure described above. It doesn't seem performant in terms of time or memory consumption.

I'm also somewhat concerned with flexibility going forward. The tree data model isn't likely to change, but the format of the DataChunk may change or be supplemented with additional formats for the data to use to build the tree. That may be another point to the builder-style approach.

Is there a  data-consuming / tree-building approach that I've overlooked? Would it be preferable to do what appears to be a violation of SRP and present a client with a mutable data structure (assuming they have or construct instances of DataChunk) or go with a more complex builder to present the client with a cleaner interface, but have a more complex code base.

答:
Ok, so here's what I came up with. This contains Java, better get yourself some coffee. The Irish one. (for the same reason)

In a sense, a tree is self similar. After all, a tree is a graph. Each node knows a certain number of other nodes.

Speaking of Nodes:

```<code>import java.util.HashMap;

public class Node <Child extends ICanBeMergedWith<? super Child> & ICanBecomeImmutable> implements ICanBecomeImmutable, ICanBeMergedWith<Node<Child>>
{
    private HashMap<Child, Child> children;
    private String name;
    private boolean mutable;

    public Node(String name)
    {
        this.name = name;
        children = new HashMap<Child,Child>();
        mutable = true;
    }

    public boolean add(Child child)
    {
        if (!mutable)
        {
            return false;
        }

        if(!children.containsKey(child))
        {
            children.put(child, child);
        }
        else
        {
            children.get(child).merge(child);
        }

        return true;
    }

    @Override
    public void merge(Node<Child> other)
    {
        if (!mutable || !equals(other))
        {
            return;
        }

        for(Child child : other.children.values())
        {
            add(child);
        }
    }

    @Override
    public String toString()
    {
        String s = name + ":";
        for (Child child : children.values())
        {
            s += System.getProperty("line.separator") + child.toString().replaceAll("(?m)^", "\t");
        }
        return s;
    }

    @Override
    public void petrify()
    {
        mutable = false;

        for (Child child : children.values())
        {
            child.petrify();
        }
    }

    @Override
    public int hashCode()
    {
        return name.hashCode();
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        if (name == null)
            if (((Node<Child>) obj).name != null)
                return false;
        return name.equals(((Node<Child>) obj).name);
    }
}
</code>```

Sorry for serving that thing up front, but there's no way around it.

Each Node should be able to compare itself to other Nodes. That gives a great advantage, because you can create different objects modelling the same node as you see fit (and as the incoming data stream dictates), then throw it all together and let the objects figure out which of them should be merged together. In Javaland you have to do some shenanigans with equals() and hashCode(). I just copied that together from the web. You have to come up with your own implementation depending on what the actual implementations of X, Y etc. do in your use case. I my case they all just have a name. If two nodes of the same type have the same name, they are equal.

There's a HashMap<Child, Child> children;, which is the list of other known Nodes I was talking about above. Admittedly, a HashSet<Child> could also work, for all we need is some data structure that keeps its children unique, but it's kind of hard to get something back out of a HashSet, which is necessary to add more things to it. Basically speaking, HashMap<Child, Child> is used like a HashSet<Child>, but is more convenient (and faster).

This list is filled via add(Child child) method. If the child is not in the list already, add it as is. If the child is in the list already, that means that this exact child is not necessarily already in the list, but some child that is considered equal, so the incoming child received as parameter is merged into the one that's in the list already. Think of this like placing two folders together that have the name: that doesn't mean they have the same sub folders. To do this, I had to create ICanBeMergedWith<T>, which you can find below, because I am unable to integrate big code blocks into list (editors?!)

As you said this leaves you with a mutable data structure. My initial solution to this was to create a NullObject instance per class. So all the mutating method calls could be either delegated to this within the class or to the NullObject. It turns out that static and generic types do not go well together. I was no able to create a generic inner NullObject singleton. As can be seen above, I went for a simple flag variable that prevents access to the internal data structure. I created ICanBecomeImmutable for that.

These interfaces are just marker interfaces to differentiate between Node<Child> and Child. I think this would all be a lot easier if there were self types (that is, being able to type something to whatever class this is) But for a lack thereof and my lack of skills, this is the solution I came up with. You can explicitly type things, which soon becomes as ugly with Node<Node<Node<V>>>. Or maybe I'm just totally wrong here.

So much for Node. The actual classes a a tad bit simpler, here they are:

V:

```<code>public class V extends Node<W>
{
    public V(String name)
    {
        super(name);
    }
}
</code>```

W:

```<code>public class W extends Node<X>
{
    public W(String name)
    {
        super(name);
    }
}
</code>```

X:

```<code>public class X extends Node<Y>
{
    public X(String name)
    {
        super(name);
    }
}
</code>```

Y:

```<code>public class Y extends Node<Z>
{
    public Y(String name)
    {
        super(name);
    }
}
</code>```

Z:

```<code>public class Z implements ICanBecomeImmutable, ICanBeMergedWith <Z>
{
    @Override
    public String toString()
    {
        return "Z";
    }

    @Override
    public void petrify()
    {
        // nothing to do
    }

    @Override
    public void merge(Z other)
    {
        // whatever
    }
}
</code>```

Only Z is a little different, because it can be known to Node but is not a Node itself. Two empty methods aren't too bad I guess.

Last but not least, the above mentioned interfaces:

interface for merging:

```<code>public interface ICanBeMergedWith<T>
{
    void merge(T other);
}
</code>```

interface for making object immutable:

```<code>public interface ICanBecomeImmutable
{
    void petrify();
}
</code>```

I created a little test application:

```<code>public class Main
{
    public static void main(String[] args)
    {
        // building main tree
        System.out.println("========= main tree ========= ");
        V v1 = new V("v1");

        W w1 = new W("w1");
        W w2 = new W("w2");

        X x1 = new X("x1");
        X x2 = new X("x2");

        Y y1 = new Y("y1");
        Y y2 = new Y("y2");

        v1.add(w1);
        // v1.petrify();
        v1.add(w2);

        w1.add(x1);
        w2.add(x2);

        x1.add(y1);
        // v1.petrify();
        x2.add(y2);

        y1.add(new Z());
        y1.add(new Z());
        y1.add(new Z());
        // v1.petrify();
        y1.add(new Z());
        y2.add(new Z());
        y2.add(new Z());

        System.out.println(v1);
        System.out.println("========= sub tree ========= ");

        // building second tree
        V v2 = new V("v1");  // !!! same name as v1 object, should be merged to one
        W w3 = new W("w2");  // !!! same name as w2 object, should be merged to one
        X x3 = new X("x2");  // !!! same name as x2 object, should be merged to one
        X x4 = new X("x4");
        Y y3 = new Y("y2");  // !!! same name as y2 object, should be merged to one

        v2.add(w3);

        w3.add(x3);
        w3.add(x4);

        x3.add(y3);

        y3.add(new Z());
        y3.add(new Z());
        y3.add(new Z());
        y3.add(new Z());
        y3.add(new Z());

        System.out.println(v2);

        System.out.println("========= merge tree ========= ");

        v1.merge(v2);
        System.out.println(v1);
    }
}
</code>```

There are a few v1.petrify(); scattered around to stop further expansion of the tree.

The output is as follows for me:

```<code>========= main tree =========
v1:
    w1:
        x1:
            y1:
                Z
                Z
                Z
                Z
    w2:
        x2:
            y2:
                Z
                Z
========= sub tree =========
v1:
    w2:
        x2:
            y2:
                Z
                Z
                Z
                Z
                Z
        x4:
========= merge tree =========
v1:
    w1:
        x1:
            y1:
                Z
                Z
                Z
                Z
    w2:
        x2:
            y2:
                Z
                Z
                Z
                Z
                Z
                Z
                Z
        x4:
</code>```

This is where my partial answer ends, because I do not know how the DataChunks look like. What you have to do now is to transform the data into a tree, then merge the tree with the main tree. As far as I could tell. Every DataChunk has to start at some V Node, because it would otherwise be impossible to which parent Node this subtree belongs to. But even if it wasn't, you have the ability now to add and merge Nodes at every level of the tree. When the stream is finished, call petrify() on the rootV Node to prevent any further mutation of the data.

Also, do some more testing.

Something should probably be final. It looks more professional if something is final. No seriously, this is to show that not every detail was thought through entirely. This is to prove that from the types and the stated requirements, this can be possible. Nothing more nothing less.

disclaimer: I don't have much experience with generics so far. Chances are this is the worst horrible nonsense ever. I was about to deem this impossible, when I gave it a last try, typed "super" to create and upper bound and all the red lines disappeared. Magic!

Also: yeah WTF, how dare I post an implementation on programmers.SE?  The thing is: you can do stuff on the whiteboard for sure, but there ain't no result without implementation. And what is supported by the language you choose in the end makes a huge difference on the effort it takes to do the actual implementation. You cannot hit "compile" and the compiler is always right. That's why I went for a concrete implementation.

Body:
Ok, so here's what I came up with. This contains Java, better get yourself some coffee. The Irish one. (for the same reason)

In a sense, a tree is self similar. After all, a tree is a graph. Each node knows a certain number of other nodes.

Speaking of Nodes:

import java.util.HashMap;

public class Node <Child extends ICanBeMergedWith<? super Child> & ICanBecomeImmutable> implements ICanBecomeImmutable, ICanBeMergedWith<Node<Child>>
{
    private HashMap<Child, Child> children;
    private String name;
    private boolean mutable;

    public Node(String name)
    {
        this.name = name;
        children = new HashMap<Child,Child>();
        mutable = true;
    }

    public boolean add(Child child)
    {
        if (!mutable)
        {
            return false;
        }

        if(!children.containsKey(child))
        {
            children.put(child, child);
        }
        else
        {
            children.get(child).merge(child);
        }

        return true;
    }

    @Override
    public void merge(Node<Child> other)
    {
        if (!mutable || !equals(other))
        {
            return;
        }

        for(Child child : other.children.values())
        {
            add(child);
        }
    }

    @Override
    public String toString()
    {
        String s = name + ":";
        for (Child child : children.values())
        {
            s += System.getProperty("line.separator") + child.toString().replaceAll("(?m)^", "\t");
        }
        return s;
    }

    @Override
    public void petrify()
    {
        mutable = false;

        for (Child child : children.values())
        {
            child.petrify();
        }
    }

    @Override
    public int hashCode()
    {
        return name.hashCode();
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        if (name == null)
            if (((Node<Child>) obj).name != null)
                return false;
        return name.equals(((Node<Child>) obj).name);
    }
}

Sorry for serving that thing up front, but there's no way around it.

Each Node should be able to compare itself to other Nodes. That gives a great advantage, because you can create different objects modelling the same node as you see fit (and as the incoming data stream dictates), then throw it all together and let the objects figure out which of them should be merged together. In Javaland you have to do some shenanigans with equals() and hashCode(). I just copied that together from the web. You have to come up with your own implementation depending on what the actual implementations of X, Y etc. do in your use case. I my case they all just have a name. If two nodes of the same type have the same name, they are equal.

There's a HashMap<Child, Child> children;, which is the list of other known Nodes I was talking about above. Admittedly, a HashSet<Child> could also work, for all we need is some data structure that keeps its children unique, but it's kind of hard to get something back out of a HashSet, which is necessary to add more things to it. Basically speaking, HashMap<Child, Child> is used like a HashSet<Child>, but is more convenient (and faster).

This list is filled via add(Child child) method. If the child is not in the list already, add it as is. If the child is in the list already, that means that this exact child is not necessarily already in the list, but some child that is considered equal, so the incoming child received as parameter is merged into the one that's in the list already. Think of this like placing two folders together that have the name: that doesn't mean they have the same sub folders. To do this, I had to create ICanBeMergedWith<T>, which you can find below, because I am unable to integrate big code blocks into list (editors?!)

As you said this leaves you with a mutable data structure. My initial solution to this was to create a NullObject instance per class. So all the mutating method calls could be either delegated to this within the class or to the NullObject. It turns out that static and generic types do not go well together. I was no able to create a generic inner NullObject singleton. As can be seen above, I went for a simple flag variable that prevents access to the internal data structure. I created ICanBecomeImmutable for that.

These interfaces are just marker interfaces to differentiate between Node<Child> and Child. I think this would all be a lot easier if there were self types (that is, being able to type something to whatever class this is) But for a lack thereof and my lack of skills, this is the solution I came up with. You can explicitly type things, which soon becomes as ugly with Node<Node<Node<V>>>. Or maybe I'm just totally wrong here.

So much for Node. The actual classes a a tad bit simpler, here they are:

V:

public class V extends Node<W>
{
    public V(String name)
    {
        super(name);
    }
}

W:

public class W extends Node<X>
{
    public W(String name)
    {
        super(name);
    }
}

X:

public class X extends Node<Y>
{
    public X(String name)
    {
        super(name);
    }
}

Y:

public class Y extends Node<Z>
{
    public Y(String name)
    {
        super(name);
    }
}

Z:

public class Z implements ICanBecomeImmutable, ICanBeMergedWith <Z>
{
    @Override
    public String toString()
    {
        return "Z";
    }

    @Override
    public void petrify()
    {
        // nothing to do
    }

    @Override
    public void merge(Z other)
    {
        // whatever
    }
}

Only Z is a little different, because it can be known to Node but is not a Node itself. Two empty methods aren't too bad I guess.

Last but not least, the above mentioned interfaces:

interface for merging:

public interface ICanBeMergedWith<T>
{
    void merge(T other);
}

interface for making object immutable:

public interface ICanBecomeImmutable
{
    void petrify();
}

I created a little test application:

public class Main
{
    public static void main(String[] args)
    {
        // building main tree
        System.out.println("========= main tree ========= ");
        V v1 = new V("v1");

        W w1 = new W("w1");
        W w2 = new W("w2");

        X x1 = new X("x1");
        X x2 = new X("x2");

        Y y1 = new Y("y1");
        Y y2 = new Y("y2");

        v1.add(w1);
        // v1.petrify();
        v1.add(w2);

        w1.add(x1);
        w2.add(x2);

        x1.add(y1);
        // v1.petrify();
        x2.add(y2);

        y1.add(new Z());
        y1.add(new Z());
        y1.add(new Z());
        // v1.petrify();
        y1.add(new Z());
        y2.add(new Z());
        y2.add(new Z());

        System.out.println(v1);
        System.out.println("========= sub tree ========= ");

        // building second tree
        V v2 = new V("v1");  // !!! same name as v1 object, should be merged to one
        W w3 = new W("w2");  // !!! same name as w2 object, should be merged to one
        X x3 = new X("x2");  // !!! same name as x2 object, should be merged to one
        X x4 = new X("x4");
        Y y3 = new Y("y2");  // !!! same name as y2 object, should be merged to one

        v2.add(w3);

        w3.add(x3);
        w3.add(x4);

        x3.add(y3);

        y3.add(new Z());
        y3.add(new Z());
        y3.add(new Z());
        y3.add(new Z());
        y3.add(new Z());

        System.out.println(v2);

        System.out.println("========= merge tree ========= ");

        v1.merge(v2);
        System.out.println(v1);
    }
}

There are a few v1.petrify(); scattered around to stop further expansion of the tree.

The output is as follows for me:

========= main tree =========
v1:
    w1:
        x1:
            y1:
                Z
                Z
                Z
                Z
    w2:
        x2:
            y2:
                Z
                Z
========= sub tree =========
v1:
    w2:
        x2:
            y2:
                Z
                Z
                Z
                Z
                Z
        x4:
========= merge tree =========
v1:
    w1:
        x1:
            y1:
                Z
                Z
                Z
                Z
    w2:
        x2:
            y2:
                Z
                Z
                Z
                Z
                Z
                Z
                Z
        x4:

This is where my partial answer ends, because I do not know how the DataChunks look like. What you have to do now is to transform the data into a tree, then merge the tree with the main tree. As far as I could tell. Every DataChunk has to start at some V Node, because it would otherwise be impossible to which parent Node this subtree belongs to. But even if it wasn't, you have the ability now to add and merge Nodes at every level of the tree. When the stream is finished, call petrify() on the rootV Node to prevent any further mutation of the data.

Also, do some more testing.

Something should probably be final. It looks more professional if something is final. No seriously, this is to show that not every detail was thought through entirely. This is to prove that from the types and the stated requirements, this can be possible. Nothing more nothing less.

disclaimer: I don't have much experience with generics so far. Chances are this is the worst horrible nonsense ever. I was about to deem this impossible, when I gave it a last try, typed "super" to create and upper bound and all the red lines disappeared. Magic!

Also: yeah WTF, how dare I post an implementation on programmers.SE?  The thing is: you can do stuff on the whiteboard for sure, but there ain't no result without implementation. And what is supported by the language you choose in the end makes a huge difference on the effort it takes to do the actual implementation. You cannot hit "compile" and the compiler is always right. That's why I went for a concrete implementation.


问:
Should I use autoloaders in modules?
Lets say I'm running a PHP app like Magento, PrestaShop.

Now these system have their own complex autoloaders to load controllers based on routes, required classes, models, etc.

Most of the time as a developer I create module to implement some sort of custom functionality. These modules reside in /modules/mymodule/. Some of these modules have their own classes like models, tools, etc.

I want to know if it's good practice to use autoload.php in modules (they opposite being including files manually)? What if there are 20+ modules and all of them have registered an autoloader? Any performance/architecture issues?

The autloader function is a simple one:

```<code>spl_autoload_register(function ($class) {
    include('classes/'.$class.'.php');
});
</code>```

Namespaces are not allowed as of yet (PHP 5.2 support). Class names are usually namespaced.

答:
Okay, first things first: you're running PHP 5.2!? There's not really much reason to stay with that other than having out of date servers, and that means it's either time to switch hosts or update your servers because PHP 5.2 has some major known security holes which aren't ever going to be fixed. This'll also give you access to a bunch of new features, the most relevant to your situation being namespaces, which will actually come up later.

The current best/most common practice for autoloading is PSR-0/PSR-4 which establish clear, consistent conventions for autoloading. This is mostly thanks to the fact that Composer has become such a widely-used part of the PHP toolchain. The main advantage of using consistent autoloading where classnames/namespaces are tied to the file system is that you don't need to have multiple autoloaders registered, you only need one which can do most of the lookup work for you.

So in the case of something using PSR-4, then a class like Namespace\Namespace2\Classname (or Namespace__Namespace2__Classname in the pre-namespace world) maps to a with a path like Namespace/Namespace2/Classname.php, which the autoloader can easily programmatically include for you once. From a performance perspective, it's faster than using require_once*, and from a coding perspective, it means you don't have to remember to add your include/require statements in every file. What's more, you don't have to keep those include statements up to date when you want to rename or move a class--the autoloader takes care of linking everything up for you.

*I should concede that opcode caching makes the speed argument largely irrelevant for the most part

Title: Should I use autoloaders in modules?


问:
Node.js callbacks and this - how it should be solved?
Every JavaScript programmer is familiar with this "problem" (it can be considered as a feature, depending on various conditions) - this is lately binded:

```<code>let foo = {
    bar(){return this;}
};
let _bar = foo.bar;
_bar() === foo.bar(); // false;
</code>```

_bar() evaluates to global object or undefined depending on presence of 'use strict' directive and foo.bar() evaluates to foo.

Node.js have a convention of providing "error first" callbacks.

My question is - what should be set by library as this of callback? EventEmitter instances set this to emitter instance and it would be most obvious solution for me - but I couldn't find popular libraries using this pattern.

Native Array instances methods use pattern Array.prototype.method = function(fn, thisArg=null){} with last argument being this context. It seems to be good solution for constant-length methods, but for variadic functions it have edge cases with this set to an instance of function.

Speaking outside of Node, jQuery use $.ajax({context: thisArg}) to set this argument of callback.

So what would be the best solution for eg. class abstracting away implementation details of user?

```<code>User.getUserByLogin('nick', function(err, user) {
     // user is User instance
     user.updateUser({name: 'new name'}, function(err){
         // what SHOULD be `this` here?
     });
});
</code>```

答:
My general first recommendation about this, is don't use it, it makes programs harder to read with no real upside. The primary exception being constructor functions.

In a library you can just leave this of a callback being global/undefined, anything you would pass as a this value may as well be passed as another parameter.


问:
Where should I put an API request in MVC?
I'm building a web application using a MVC pattern. Following this kind of architecture we can see that all the methods used to interact with database are implemented in the model.

But what happen if I have to call a service exposed by others on web? For example, I would like to access the Facebook API in order to get all the follower of my page, so, where I put these methods?

Obviously the view is not a good idea because this module is dedicated to the presentation, the controller should not be used to retrieve data but the model is usually dedicated only to the interaction with database.

So, can you give me some hint about that? And please, can you tell me if I'm making some mistakes about the MVC architecture?

答:
Part of the difficulty with any discussion of MVC is that different groups have co-opted it to mean different things. The implementation of MVC used in, say, a Rails app, would be almost unrecognisable to someone writing a Swing app. To the extent that MVC is still a well-defined thing, it's more of a set of guiding principles (separate the core application from its visual representation, provide flexible mechanisms to allow the two to be plumbed together), that can be implemented in various ways.

Indeed, there's a tendency towards giving different MVC-derived designs different names (see this article by Martin Fowler for some discussion of this), or even to give up on precise naming - for example, AngularJS describes itself as a Model-View-Whatever framework.

So, it's hard to answer without knowing which version of "MVC" you're working with. However, an API request would typically be part of the core application (the part that shouldn't change if you decide to use a different visual representation), which in many implementations would be contained entirely within the model.


问:
Counting lines of text and get color of a specific line in an image
check this picture out before I explain further:

How can I count the amount of lines there are from the yellow line to line #5? OCR sounds like overkill, because I don't really care what the text says.

答:
Rough outline:

scan your image horizontally, pixel-line wise

each pixel line eithers contains only black pixels, or some white/yellow pixels: store this information in a boolean array.

group the pixel line numbers together, each sequence of non-empty lines and each sequence of empty lines form a group. The non-empty line groups represent the word lines, and the empty-line groups represent the space between the word lines.

so what remains is simply counting the groups

To deal with aliasing effects, you will probably have to refine this a little bit, for example, by interpreting pixel lines as empty when they contain only a few number of white pixels, or by expecting a minimum size for any group (see Lars Viklund's comment) . You will have to adapt this to the quality and resolution of your images.


问:
Where in an MVC web application should writing files locally go?
In my web application that uses an MVC framework which has different modules for models, views and controllers I talk to several databases and APIs. Those are implemented as individual models.

A lot of data gets entered by the user accross several different screens. That data goes into the session. Some of that data is meta information that validates the success of the process, and some of it is stuff that I want to keep. That data is supposed to be written to a file in the file system, and the path of that file with some meta-information is stored in a database. After that, a confirmation page will be displayed to the user.

I am now struggling with where to put the writing of the subset of the data that has accumulated in the session to the file in my specific format.

There are several thoughts I have on the matter. I am not sure which one is the most right.

It should be a View because it takes data that is already there in the user's session and presents it in a specific way – the file format (which is XML, but that is not relevant). Formatting and writing the file is implemented there.

Reasoning: The default HTML view that renders data as a website to the user's browser has the webserver's interface set as its STDOUT channel. Likewise would a JSON view that presents stuff in case an API call is made. If we write to a file, the STDOUT of the view that formats the file is set to a local file handle and we write there.

There should be a View to bring the data into my XML format, but a Model to write the data into the file.

Reasoning: Because after writing the file, another website will be displayed. Only one view can be at the end of the chain of things that do stuff in the lifetime of one request handling. But because data is being formatted, a view is appropriate. It just returns the formatted data rather than writing it to a sink (STDOUT).

It should be a Model, because it deals with data.

Reasoning: Models are data sources and data sinks. Although the source-part is absent here there is still a data sink. The fact that it needs to be formatted also is neglegible because if we'd talk to e.g. a RESTful API of some sort we would also first format the data to be either part of a GET request (which is very simple) or maybe a JSON representation as the body of a POST/PUT request.

The code that formats the data into XML is already built as a stand-alone class that is not tied to the webapp yet.

My question is this: Where in the application should I use that class and write the file to disk so I do not break the MVC pattern?

Example cases where this specific process would happen include:

a user feedback/survey form with multiple pages, like the Stack Overflow anual user survey,

an e-commerce order funnel,

back-office data entry that talks to a third party through a file-based API where the "sending" happens asynchronously at a later, unrelated time

答:
None of the above, actually. It is the responsibility of your controller to write the data to file, although I'd recommend writing a specific class for that and just having the controller use that class.

It is not a view because views in MVC are strictly about rendering data in the UI. The data itself should probably be put into a model and that model persisted via the controller.

Think about this in a storage-independent way. If this was data you store in the database, would you do anything besides put the data onto a model and use a repository (or some sort of DAL) to write that model to a database? Probably not. In this case you would gather your data into a model, hand the model off to a repository and then use your XML-formatting class to write the model into a file.


问:
Table with 2 columns that are foreign keys. Only one can be set for every record
I have a table that is connected with 2 other tables like so:

Main table

```<code>ID_1                    | ID_2
//Foreign key of table1  //Foreign key of table2
</code>```

Table1

```<code>ID                   | Some information |More information
//connected with ID_1
</code>```

Table2

```<code>ID                   | Some information | More information
//connected with ID_2
</code>```

So in the main table, ID_1 or ID_2 can be set, but not both. The way it is now (2 foreign keys) aren't working because they're optional.

What would be my options here?

I know I can split it up to 2 tables but that's not how I want it.

Should I make them able to be NULL?

答:
You could invert the direction of the key: have Table1 and Table2 each contain a column that references back to the Main Table and make these non-nullable. This forces the referential integrity that you want, at the cost of making queries a bit more difficult because you cannot start from the Main Table to query. Not impossible, but something to think about.

This is actually quite a common problem in ORM-frameworks with regards to mapping inheritance. The solutions often amount to not enforcing the constraints on the database and instead leaving it to the application code to enforce these rules as a tradeoff. Look into 'table per type' versus 'table per hierarchy' versus 'table per class'.


答:
I had the same problem but my situation was a little bit different, let me explain.

In my project I had to use files for two purposes:

Store data (database)

Track errors (log file)

So my model was dedicated to the interaction with files used as database and i created some helpers (I was using Codeigniter) to write log files. In this way i could invoke helper functions everywhere and this was really helpful because I had to track errors in models and controllers.

In your case i suggest you to write your own helper class to be invoked where you need to write data.

I hope it helps

Title: Where in an MVC web application should writing files locally go?

Body:
In my web application that uses an MVC framework which has different modules for models, views and controllers I talk to several databases and APIs. Those are implemented as individual models.

A lot of data gets entered by the user accross several different screens. That data goes into the session. Some of that data is meta information that validates the success of the process, and some of it is stuff that I want to keep. That data is supposed to be written to a file in the file system, and the path of that file with some meta-information is stored in a database. After that, a confirmation page will be displayed to the user.

I am now struggling with where to put the writing of the subset of the data that has accumulated in the session to the file in my specific format.

There are several thoughts I have on the matter. I am not sure which one is the most right.

It should be a View because it takes data that is already there in the user's session and presents it in a specific way – the file format (which is XML, but that is not relevant). Formatting and writing the file is implemented there.

Reasoning: The default HTML view that renders data as a website to the user's browser has the webserver's interface set as its STDOUT channel. Likewise would a JSON view that presents stuff in case an API call is made. If we write to a file, the STDOUT of the view that formats the file is set to a local file handle and we write there.

There should be a View to bring the data into my XML format, but a Model to write the data into the file.

Reasoning: Because after writing the file, another website will be displayed. Only one view can be at the end of the chain of things that do stuff in the lifetime of one request handling. But because data is being formatted, a view is appropriate. It just returns the formatted data rather than writing it to a sink (STDOUT).

It should be a Model, because it deals with data.

Reasoning: Models are data sources and data sinks. Although the source-part is absent here there is still a data sink. The fact that it needs to be formatted also is neglegible because if we'd talk to e.g. a RESTful API of some sort we would also first format the data to be either part of a GET request (which is very simple) or maybe a JSON representation as the body of a POST/PUT request.

The code that formats the data into XML is already built as a stand-alone class that is not tied to the webapp yet.

My question is this: Where in the application should I use that class and write the file to disk so I do not break the MVC pattern?

Example cases where this specific process would happen include:

a user feedback/survey form with multiple pages, like the Stack Overflow anual user survey,

an e-commerce order funnel,

back-office data entry that talks to a third party through a file-based API where the "sending" happens asynchronously at a later, unrelated time


问:
Is this the correct way to include this MIT licensed software in my software?
I'm using this script in one of my projects. It's licensed under MIT or Apache 2.

I've committed JSON.sh (as in, just the script) to my project, and copy+pasted the MIT license (as it appears in LICENSE.MIT) to the bottom of it.

Is that sufficient?

答:
It's correct but you should include the licence or a link to it in every file of your software, as specified in the text:

Copyright (c)

Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

I follow this approach:

create the MIT licence file (something like LICENCE.txt) and put this file on the root of the project

add a link to this file in every file of my project, just a comment with the url to the licence.

I like this approach because is not so expensive and "protect" each file of your software.
The comment I use is something like that:

```<code>//This code is under MIT licence, you can find the complete file here: www.mylicencefile.com
</code>```

Anyway GitHub gives you an easy way to add a license to your project, you can read how to do that here.

Body:
It's correct but you should include the licence or a link to it in every file of your software, as specified in the text:

Copyright (c)

Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

I follow this approach:

create the MIT licence file (something like LICENCE.txt) and put this file on the root of the project

add a link to this file in every file of my project, just a comment with the url to the licence.

I like this approach because is not so expensive and "protect" each file of your software.
The comment I use is something like that:

//This code is under MIT licence, you can find the complete file here: www.mylicencefile.com

Anyway GitHub gives you an easy way to add a license to your project, you can read how to do that here.


问:
When deploying a production app using docker, should I still use volumes or should I use add in the dockerfile?
I've been working on this little rails app with docker for a while and I'm finally ready to move it into production but I'm not sure what the best practice is for deploying a Docker app.

When developing my app I was using volumes because waiting for the docker to rebuild the image with each change to the app was ridiculous. In a production app, however, I'm not sure if there are any disadvantages.

Are there, if so what are they?
Should I continue to use volumes or should I just make a new dockerfile with add?

答:
The idea of an app container is that it is a "lightweight portable runtime which can be dropped anywhere". It isn't clear what you are using volumes for, if it is for certain libraries that will always be present on any host machine you choose to run this container on, then you can use volumes.

For app files, it is better to ADD the source files to the container and build.


问:
Why is free software good for programmers?
When I say Free Software I mean it in the FSF terms. Free as in Free Speech, not as in Free Beer.

Why is it a good idea for programmers to use and write Free Software?

答:
There are literally scores of different reasons why someone might choose to distribute Free software: that's why there are scores of different F/OSS licenses. My favorite reason for going Free is from Linus Torvalds on why he chose and sticks with GPLv2:

Me, I just don't care about proprietary software. It's not "evil" or "immoral," it just doesn't matter. I think that Open Source can do better, and I'm willing to put my money where my mouth is by working on Open Source, but it's not a crusade -- it's just a superior way of working together and generating code.

It's superior because it's a lot more fun and because it makes cooperation much easier (no silly NDA's or artificial barriers to innovation like in a proprietary setting), and I think Open Source is the right thing to do the same way I believe science is better than alchemy. Like science, Open Source allows people to build on a solid base of previous knowledge, without some silly hiding.

But I don't think you need to think that alchemy is "evil." It's just pointless because you can obviously never do as well in a closed environment as you can with open scientific methods.

This goes to Eric S. Raymond's Linus's Law:

Given a large enough beta-tester and co-developer base, almost every problem will be characterized quickly and the fix obvious to someone.

Or, less formally, "Given enough eyeballs, all bugs are shallow."

ContentLicense: CC BY-SA 2.5


答:
update the (PDF) manual any time that a code change would alter the instructions in the manual - just make updating the manual part of the release process

if the users rely on the manual to tell them how to use the product, and the product changes, then it's only common sense that the relevant section(s) of the manual should also change

Title: Manuals - How Up To Date?

Body: If you have a product that has been in the market for a long time, but it is still in active development daily - how often should the manuals be updated? If your users are constantly updated to the bleeding edge version due to the fact that your organization sees fit that the latest bug fixes are always in the shipped version. Meaning, you could fix a bug one day and next day it is hitting production.</p>


问:
Why would you use a Report Engine, if your application are modeled around ORM
For example, you use some MVC framework for your web application and for most of the time you are thinking in very object oriented way, and that is why you opted to use an ORM framework in the first place.

However, when it comes to reporting. You decided to use reporting framework like BIRT, for example. BIRT does not know about your object relational mapping, it knows about your tables and raw SQL queries. It suddenly takes away all the abstraction that you've put in place. Nothing wrong with that but it feels rather disconnected (and 2005).

So the question is, why would you use any reporting framework when you can simply just use any (HTML5) templating framework out there to render your report. Assuming you don't need the multi-format exporting capabilities of a reporting framework.

Remarks: performance is not an issue ... at all

答:
Working with a framework is all about trade-offs: you lose some capabilities or flexibility in one area to gain an advantage that matters to you. For example:

Reporting tools might offer different export capabilities out-of-the-box: you can export any report to PDF or XLS or CSV or HTML or...

Reporting tools might offer scheduling and the ability to run reports automatically at a given time

Reporting tools might offer you advanced formatting capabilities such as sorting or templating

Reporting tools might allow you to query different systems and join data across these systems, using different technologies (SQL vs XML vs JSON vs...)

It's not that this can't be done in a roll-your-own HTML reporting application, it's just that this takes time and effort. You should ask yourself if you want to spend time and effort writing your own reporting when there are frameworks that can take care of that for you. Just like you should ask yourself if you want to spend time and effort writing SQL and mapping your domain to the database or use an ORM.

There is also the fact that there is a big difference between your object model and the reporting model. An object model is very different from a report model and the way you write your object model does not necessarily map very well to reporting. Unless you specifically design your object model to handle reporting, chances are a report on top of this model will have SELECT N+1 issues. Reporting benefits a great deal from queries that use JOINS and the like.

Lastly, for really big applications denormalisation of data and things like data warehousing mean that you are working with a database-structure that is intended and optimized for reporting anyway. It doesn't make a lot of sense to introduce a model on top of that because SQL is very good at reading from this kind of data storage.


问:
Intro to C for an experienced programmer
This reply to the question "I don't know C. And why should I learn it?" has me interested in learning C. What is a good self-instruction program (textbook/website/OpenCourseWare, etc.) for someone who already has lots of experience in high-level languages?</p>

答: Leendert Ammeraal's "C For Programmers", while VERY dated now (15 years old or more) is by far the best thing I have ever seen along these lines.</p>


问:
Is there a well defined notion of 'before' and 'after' in finite state machines?
When working with finite state machines, is there or can there be a well defined concept of 'before' and 'after'.

The ordering would, for example, tell me that one state is always considered to be 'before' another state, in the sense that any sequence of transitions through a state machine from some start state, to some end state, must always encounter a particular state before some other state.

I think these would be partial orders on the states of the machine. Sometimes two states would be neither before or after each other.

The particular problem I am trying to solve, is for field validations on items being passed through a workflow, defined as a state machine. If some field must be present in a particular state, it must also be present in states considered to come 'after' that state.

It is possible in the workflows, that items can be moved back into earlier states. For example, an item may go through a workflow and be 'published' but later un-published to be re-worked, and then put back through a workflow to be published again. There are edges in state machine that move forward towards end states, but also edges that move backwards towards start states. Given that, can I still define some sensible 'before' and 'after' relationships between states?

What I am trying to ask is, in state machine theory, is there a standard definition of what 'before' and 'after' mean that I can use to implement these functions?

答:
I don't think you can make definite assumptions for the general graph.

Some edges might bypass a Node, so it is not clear if the Node was visited or not. The state machine is like a map of possibilities.

Speaking of maps, you usually take the opportunities offered by a map one after the other. While the location itself has no notion of time, your visit of them certainly does.

Applying that to your state machine means that you create another graph that represents the ordered list of states visited and transitions used.

This graph (list) is never cyclic, even if the state machine is, because happening one after the other makes each visit of a Node (even those to the same Node) unique. This allows you to declare one Node to be before another one, if it is closer to the starting Node in the "visited states graph" than the other Node. "closer" means "it takes less transitions to get there"


答:
If you're interested in having different behaviour and/or tracking as part of the state whether a particular state has ever been visited, you can duplicate all of your possible states and then change all the transitions from the state of interest to the new duplicate of its original destination.

For example, consider the FSM with four states A, B, C and D, and the following transitions:

```<code>A -> B
B -> C
B -> D
C -> A
</code>```

D is an end state

If we wanted to treat the result differently depending on whether or not C is visited we can change it to have 8 states, A..D and A'..D', with transitions:

```<code>A -> B
B -> C
B -> D
C -> A'
A' -> B'
B' -> C'
B' -> D'
C' -> A'
</code>```

We can then say that A'..D' are after C, while A, B and D are before C.

Title: Is there a well defined notion of 'before' and 'after' in finite state machines?

Body:
When working with finite state machines, is there or can there be a well defined concept of 'before' and 'after'.

The ordering would, for example, tell me that one state is always considered to be 'before' another state, in the sense that any sequence of transitions through a state machine from some start state, to some end state, must always encounter a particular state before some other state.

I think these would be partial orders on the states of the machine. Sometimes two states would be neither before or after each other.

The particular problem I am trying to solve, is for field validations on items being passed through a workflow, defined as a state machine. If some field must be present in a particular state, it must also be present in states considered to come 'after' that state.

It is possible in the workflows, that items can be moved back into earlier states. For example, an item may go through a workflow and be 'published' but later un-published to be re-worked, and then put back through a workflow to be published again. There are edges in state machine that move forward towards end states, but also edges that move backwards towards start states. Given that, can I still define some sensible 'before' and 'after' relationships between states?

What I am trying to ask is, in state machine theory, is there a standard definition of what 'before' and 'after' mean that I can use to implement these functions?

Body:
If you're interested in having different behaviour and/or tracking as part of the state whether a particular state has ever been visited, you can duplicate all of your possible states and then change all the transitions from the state of interest to the new duplicate of its original destination.

For example, consider the FSM with four states A, B, C and D, and the following transitions:

A -> B
B -> C
B -> D
C -> A

D is an end state

If we wanted to treat the result differently depending on whether or not C is visited we can change it to have 8 states, A..D and A'..D', with transitions:

A -> B
B -> C
B -> D
C -> A'
A' -> B'
B' -> C'
B' -> D'
C' -> A'

We can then say that A'..D' are after C, while A, B and D are before C.


问:
How to explain to PM that a task is too small to be shared
There is task that from the business point of view is really critical but, even it has been estimated in 40 days of works [of course worst case], involves a really small part of the project (a couple of java classes, some JS and JSP pages) and, in my opinion is really complicated to be assigned to more than one developer. Working in parallels in this task probably will have a huge cost in terms of team management in particular because the two developers assigned to this task will work on two complitely different timezones (pair programming not possible).

I shared that with the PM but it seems not acceptable for him so, my question at this point is: how can I justify a situation like that to the PM(s)? How can I manage this kind of situation?

答:
Something estimated to take that long can be shared, something that was estimated at more than a month of work for one person has not been properly broken down and tasked out. You've mentioned that there are a couple different pages involved, at the most naive level this could be broken down by page if you define the expected data passed between the pages if any.

It sounds like your real problem is you have a distributed team and don't have a working communication solution, which would make working together on the same thing extremely difficult to impossible. This is what you should be talking to your PM about, and its also something he should have the power to do something about. Trying to argue that a month long task can't be split up among multiple developers is futile because its entirely false, arguing that splitting this task among developers that can't communicate effectively will increase risk is something a PM will understand.


问:
Is anyone actively developing software to be used with the Emotiv headset?
Based on the "featured apps" section of the main page
http://www.emotiv.com/index.php

Alot of the so called "mind control" apps so far seem to be fairly rudimentary read/scan apps that look to profile a certain activity, or perhaps allow the user to manipulate or control an app in a way loosely analogous to using a mouse/keyboard.

I'm just wondering if anyone is currently working on something (assuming they can talk about it) that is a mind blowingly spectacular use of the Emotiv headset?

thanks.

答:
Sure. have a look.  The software shown in this video will be out shortly as soon as testing and refining is finished.  It's called EmoLens and it uses the Emotiv EPOC headset to detect emotions and tag Flickr photographs with them.  Note the emotions shown being detected in the video (Happy/Sad/Anger/Fear) have been changed to (Interesting/Happy/Funny):

http://www.youtube.com/watch?v=E9_XZlHoSp0

I'm the author.

roschler

OwnerDisplayName: Robert Oschler


答:
If it's that mission critical don't break the task, but have someone review what you write.

The PM will be happy to have devoted more resources to one of the most important parts of the project and the code will be more robust.

Title: How to explain to PM that a task is too small to be shared

Body:
There is task that from the business point of view is really critical but, even it has been estimated in 40 days of works [of course worst case], involves a really small part of the project (a couple of java classes, some JS and JSP pages) and, in my opinion is really complicated to be assigned to more than one developer. Working in parallels in this task probably will have a huge cost in terms of team management in particular because the two developers assigned to this task will work on two complitely different timezones (pair programming not possible).

I shared that with the PM but it seems not acceptable for him so, my question at this point is: how can I justify a situation like that to the PM(s)? How can I manage this kind of situation?


问:
Where to place the R code for R+Sweave+LaTeX workflow
I spent the last week learning 3 new tools: R, Sweave, and LaTeX. One question that came to my mind when working through my first project: Where do I place the majority of the R code?

The tutorials that I read online placed the majority of the R code in the LaTeX .Rnw file. However, I find having a bunch of R calculations in the LaTeX file distracting. What I do find extremely helpful (of course) is to call out to R code in the LaTeX file and embed the result.

So the workflow I've been using is to place 99% of my R code in my .R file. I run that file first, save a bunch of calculations as objects, and output the .Rout file once finished (to save the work). Then when running Sweave, I load up that .Rout file, so that I have the majority of my calculations already completed and in the Sweave R session.

Then my LaTeX callouts to R are quite simple: Just give me the XTable stored in 'res.table', or give me the result of an already-computed calculation stored in the variable 'res'.

So I push towards the minimal amount of R code in the LaTex file possible, to achieve the desired result (embedding stats results in the LaTeX writeup).

Does anyone have any experience with this approach? I'm just worried I might run into trouble further down the line, when I start really trying to load up and leverage this workflow.

答:
In order to keep code out of my .Rmd I've started writing a package with all the functions in it.

This may be with a slightly different intent than your workflow, but my project is repetitive enough that I can generalise the code into functions, with the goal of the project being to use it as a sort of super mail-merge to generate a document per data set from a large repository.

This satisfies the criteria of removing chunky R code blocks that you then want to hide, though it doesn't do much for reducing the processing time.

An alternative I've seen around suggests using source(), though that would, to my limited understanding just mirror your current process.


问:
To what values should you initialize the neurons and connection strengths in a neural network?
The values of all of the neurons in my neural network are initialized to 0 and the connection strengths between the neurons are set to randomly generated floats, between 0 and 1. I have seen other people setting their ranges from 0 to .5, however. Are there any benefits of one over the other? and Should the neuron values be randomly set to either 1 or 0, instead?

答:
Randomizing the nodes and connections, increases the initial entropy of the network.

Creating stronger biases in the network at the beginning (before training), would presumably facilitate the formation of some of the neural paths faster.

When all other factors are equal for an input, this will amortize worst cases during training (this should happen rarely, but in a network training session it may happen a few times).

In practice the difference in efficience is probably infinitesimal throughout the training period (if it matters at all) - so in the end, it is a matter of prefference.

Similarly, if you implement qsort and choose the pivot position randomly, (instead of picking the middle of each sorted segment) the sorting tends to have on average, a faster execution time (observable usually only over many repetitions).


问:
Patterns for sharing context variables between functions
I am looking for ways of passing around a set of contextual variables that are required by functions.

As a Python programmer, right now I can see three ways of solving the problem: passing them around as explicit arguments, class encapsulation and closures (function factory).

I find that explicit arguments tend to obscure the function logic, class encapsulation tend to lead to the do-it-all, thousand lines classes, whereas closures tend to create an programming overhead because of factory creation.

I was wondering if there were any other patterns that allow sharing of dynamically defined contextual variables between functions devoid of such shortcomings? For instance how this problem would be solved in the context of functional programming?

答:
You might look into the Reader or State monads; they can be used for sharing data between (pure, monadic) functions, without resorting to explicit parameters or the like.

There's a tutorial series on F# for fun and profit about the State monad (AKA Workflow in F# parlence). I also gave a description of it in this SO answer that appears to be fairly approachable.

There are some implementations of other monads in python that you could reference too, if you have to implement your own.

Many people (myself included) find monads challenging at first, so if you're not familiar with the concept then I'd recommend looking at some of the simpler monads like Maybe or Either, and then perhaps Reader or Writer, before tackling State. The Python implementations linked to above may make things more clear for you than what you're likely to find elsewhere online (which would probably be Haskell).

A few caveats: there is still a little overhead over just functions, since the monad is involved, and this has to be used with functions; I don't think you could do this with class methods (though I could be wrong -- I've never tried it!).

UPDATE:

The "monads in python" page/lib I linked to above actually does have a state-monad implementation; check out the code starting at ###### StateChanger Monad ######### for the definition and examples.

EDIT in response to question in comment:

Yes, that's the way you'd do it -- to be extra clear, the arguments you declare the function with should not include the environment variables, just the ones the function would need normally; the environment variables will be accessible through the monadic get and set functions.

A Python example using the notation given in the "monads in python" link above:

```<code>@do(StateChanger) # <-- this makes makes it a stateful computation
def my_stateful_function1(arg):
    # do something with `arg` here
    # then put it in the state:
    yield dict_state_set(key, var_from_arg)
    # I believe you can leave out `mreturn` for this

@do(StateChanger)
def my_stateful_function2(arg1, arg2):
    # something with `arg1` here
    # get the state chained via the monad:
    state = yield get_state()
    # do something else stateful:
    yield my_stateful_function1(arg2)
    # do something with `state` dict here
    # return; you have to use `mreturn` instead of `return`:
    mreturn(some_value)
</code>```

To run this you'd call:

```<code>ret_val = my_stateful_function2("hello","world").run(initial_state_dict)
</code>```

and your return value would be a tuple:

```<code>(return_value_of_function, final_state_dict) = ret_val
</code>```

Remember to use yield when calling other stateful functions.

Admonition: Be careful about modifying the state in your functions since the Python dictionary type is mutable. You can get and set state vars, as well as apply a (lambda) function to them; you may wish to stick with this rather than pulling the state out and mutating it willy-nilly.

Body:
You might look into the Reader or State monads; they can be used for sharing data between (pure, monadic) functions, without resorting to explicit parameters or the like.

There's a tutorial series on F# for fun and profit about the State monad (AKA Workflow in F# parlence). I also gave a description of it in this SO answer that appears to be fairly approachable.

There are some implementations of other monads in python that you could reference too, if you have to implement your own.

Many people (myself included) find monads challenging at first, so if you're not familiar with the concept then I'd recommend looking at some of the simpler monads like Maybe or Either, and then perhaps Reader or Writer, before tackling State. The Python implementations linked to above may make things more clear for you than what you're likely to find elsewhere online (which would probably be Haskell).

A few caveats: there is still a little overhead over just functions, since the monad is involved, and this has to be used with functions; I don't think you could do this with class methods (though I could be wrong -- I've never tried it!).

UPDATE:

The "monads in python" page/lib I linked to above actually does have a state-monad implementation; check out the code starting at ###### StateChanger Monad ######### for the definition and examples.

EDIT in response to question in comment:

Yes, that's the way you'd do it -- to be extra clear, the arguments you declare the function with should not include the environment variables, just the ones the function would need normally; the environment variables will be accessible through the monadic get and set functions.

A Python example using the notation given in the "monads in python" link above:

@do(StateChanger) # <-- this makes makes it a stateful computation
def my_stateful_function1(arg):
    # do something with `arg` here
    # then put it in the state:
    yield dict_state_set(key, var_from_arg)
    # I believe you can leave out `mreturn` for this

@do(StateChanger)
def my_stateful_function2(arg1, arg2):
    # something with `arg1` here
    # get the state chained via the monad:
    state = yield get_state()
    # do something else stateful:
    yield my_stateful_function1(arg2)
    # do something with `state` dict here
    # return; you have to use `mreturn` instead of `return`:
    mreturn(some_value)

To run this you'd call:

ret_val = my_stateful_function2("hello","world").run(initial_state_dict)

and your return value would be a tuple:

(return_value_of_function, final_state_dict) = ret_val

Remember to use yield when calling other stateful functions.

Admonition: Be careful about modifying the state in your functions since the Python dictionary type is mutable. You can get and set state vars, as well as apply a (lambda) function to them; you may wish to stick with this rather than pulling the state out and mutating it willy-nilly.


问:
How do you use Roundup issue tracker?
Roundup issue tracker is pretty minimalistic by default, and it does not bring any specific workflow with itself. It was once called ‘so configurable that it’s probably better described as a lightweight tracker-oriented framework.’

Have you ever used Roundup extensively or seen some interesting use cases? If so, please share an example.

(If you don’t consider your workflow special enough, at least tell how do you understand & utilize superseder field in the default ‘classic’ template, which alone could be interpreted differently—see old.nabble.com/Superseder-td13792131.html)

答:
I'm using it for the Python bug tracker. We have the customization publically available.

In addition, I also use it for students to submit exercises (assignments are somewhat similar to components/milestones; solutions are similar to bug reports, except for access control). However, the code for this is not public.

Title: How do you use Roundup issue tracker?


问:
Functions whose parameters are implicitly supplied
Callback functions are able to accept some parameters, but they are not explicitly declared when calling the function.

How does this actually work? What is going on that allows us to pass a function as a parameter to another function, and implicitly include a parameter in there?

For example:

Javascript

```<code>$.get('somefile.php', {func : 'getUserNames'}).done(function(data){
    if(data)
       console.log(data); // '{"0" : "billy", "1" : "bobby"}'
    // This is a js ajax call to a php file.
    // How exactly am I retrieving "data" ?
}, 'json');
</code>```

C#

```<code>private void BeginReadingData(){
    NetworkStream stream = tcpClient.GetStream();
    stream.BeginRead(buffer, 0, bufferSize, MyCallBack, tcpClient);
}

private void MyCallBack(IAsyncResult ar){
    // Now I can operate on 'ar'
    // why and how?
}
</code>```

This is something I understand how to use, just not how to explain or correctly describe the process.

答:
What do you call a callback function that accepts some parameters, but they are not explicitly declared when calling the function?

I'm not sure what you're talking about.

function(data) explicitly declares a parameter named data for the anonymous function.

private void MyCallBack(IAsyncResult ar) explicitly declares a parameter named ar with the type IAsyncResult for the function named MyCallback.

They both make that identifier available to the body of the function, and the compiler/interpreter knows to translate that identifier resolution to "access the first argument of this function".


答:
What do you call a callback function that accepts some parameters, but they are not explicitly declared when calling the function?

I'm not sure. In certain cases an object's method may be considered to have the object itself as an implicit parameter.

But there are no function calls with implicit parameters your examples. With a callback, you don't pass the result of calling the function, you pass the function itself.

stream.BeginRead(buffer, 0, bufferSize,
    MyCallBack, /* <- Not a function call, just a reference to a function. */
    tcpClient);
```

<p>The function that you gave the callback, in these cases <code>$.get</code> and <code>stream.BeginRead</code> will call the callback function you gave them, and explicitly give it the parameters that it should take.</p>

<p>So what you're missing here is the definition of <code>stream.BeginRead</code> has something like:</p>

<pre class="lang-cs prettyprint-override"><code>public virtual ISyncResult BeginRead(
        byte[] buffer,
        int offset,
        int count,
        AsyncCallback callback,
        Object state
    ) {
    /* stuff */

    callback(ar); /* <-- called with explicit parameter */

    /* more stuff */
}
</code>```

Title: Functions whose parameters are implicitly supplied

Body:
Callback functions are able to accept some parameters, but they are not explicitly declared when calling the function.

How does this actually work? What is going on that allows us to pass a function as a parameter to another function, and implicitly include a parameter in there?

For example:

Javascript

```<code>$.get('somefile.php', {func : 'getUserNames'}).done(function(data){
    if(data)
       console.log(data); // '{"0" : "billy", "1" : "bobby"}'
    // This is a js ajax call to a php file.
    // How exactly am I retrieving "data" ?
}, 'json');
</code>```

C#

```<code>private void BeginReadingData(){
    NetworkStream stream = tcpClient.GetStream();
    stream.BeginRead(buffer, 0, bufferSize, MyCallBack, tcpClient);
}

private void MyCallBack(IAsyncResult ar){
    // Now I can operate on 'ar'
    // why and how?
}
</code>```

This is something I understand how to use, just not how to explain or correctly describe the process.

Body:
What do you call a callback function that accepts some parameters, but they are not explicitly declared when calling the function?

I'm not sure. In certain cases an object's method may be considered to have the object itself as an implicit parameter.

But there are no function calls with implicit parameters your examples. With a callback, you don't pass the result of calling the function, you pass the function itself.

stream.BeginRead(buffer, 0, bufferSize,
    MyCallBack, /* <- Not a function call, just a reference to a function. */
    tcpClient);

The function that you gave the callback, in these cases $.get and stream.BeginRead will call the callback function you gave them, and explicitly give it the parameters that it should take.

So what you're missing here is the definition of stream.BeginRead has something like:

public virtual ISyncResult BeginRead(
        byte[] buffer,
        int offset,
        int count,
        AsyncCallback callback,
        Object state
    ) {
    /* stuff */

    callback(ar); /* <-- called with explicit parameter */

    /* more stuff */
}


问:
Why not just make non-parameterized queries return an error?
SQL injection is a very serious security issue, in large part because it's so easy to get it wrong: the obvious, intuitive way to build a query incorporating user input leaves you vulnerable, and the Right Way to mitigate it requires you to know about parameterized queries and SQL injection first.

Seems to me that the obvious way to fix this would be to shut down the obvious (but wrong) option: fix the database engine so that any query received that uses hard-coded values in its WHERE clause instead of parameters returns a nice, descriptive error message instructing you to use parameters instead.  This would obviously need to have an opt-out option so that stuff like ad-hoc queries from administrative tools will still run easily, but it should be enabled by default.

Having this would shut down SQL injection cold, almost overnight, but as far as I know, no RDBMS actually does this.  Is there any good reason why not?

答:
```<code>SELECT count(ID)
FROM posts
WHERE deleted = false
</code>```

If you want to put the results of these in the footer of your forum you would need to add a dummy parameter just to say false every time. Or the naive web programmer looks up how to disable that warning and then continues on.

Now you can say you would add an exception for enums but that just opens the hole again (though smaller). Not to mention people first need to be educated to not use varchars for those.

The real problem of injection is programmatically constructing the query string. The solution for that is a stored procedure mechanism and enforcing its use or a whitelist of allowed queries.

Body:
SELECT count(ID)
FROM posts
WHERE deleted = false

If you want to put the results of these in the footer of your forum you would need to add a dummy parameter just to say false every time. Or the naive web programmer looks up how to disable that warning and then continues on.

Now you can say you would add an exception for enums but that just opens the hole again (though smaller). Not to mention people first need to be educated to not use varchars for those.

The real problem of injection is programmatically constructing the query string. The solution for that is a stored procedure mechanism and enforcing its use or a whitelist of allowed queries.


问:
How to decide git repo division with workflow considerations?
We are moving from subversion to git for branching and distributed development reasons. One struggle in the past with our old repository workflow was that every application had its own repository. A huge application had its own repository and a small application that had 15 files and barely ever changed had its own. Most of the applications are inter-dependent at least on the db side, if not sharing code, as part of our overall product suite. There are just a couple primary application but they are becoming more and more integrated and may soon be using the same api for all of their "backend" requests.

As I come up with a proposal for how to move forward using git, repo organization and workflow, I am trying to decide between a few choices...

monolithic: one primary repository (1 repo)

independent: a separate repository for nearly every application/library (total ~20) plus main repo with submodules

compromise: one repository per major application, one for all minor apps and one for libraries (~4 repos) plus main repo with submodules

I initially started with the monolithic approach with the git workflow and felt comfortable with that approach but the more I read I see this is not the best practice for git. I am now evaluating the separate repo and submodules approach, however it adds many steps to the workflow not directly supported in repo systems (ex: pull requests across multiple repositories) and appears to be prone to problems in the main repository if not careful with order of operations.

I'm starting to lean towards the compromise approach however the fact that I've done some testing with the monolithic approach and not seeing any problems makes me think that in trying to follow best practices I'll actually be making our workflow more complex, require more time to deal with pulls and releases, and more prone to errors.

Am I understanding the best practice of "one repo per project" incorrectly? Should our codebase of inter-related applications be considered one project thus one repo?

Thoughts?

答:
Most of the time, if you think you need submodules to keep dependent versions between your separate repos in sync, that's a sign you'd be better off with a single repository.  Separate repos should usually be highly independent, and be able to be updated and released without worrying about the versions of other projects.

Even with all the projects in one logical repo, git's distributed nature means you can still use separate physical repos if that makes sense for your organization.  For example, the Linux kernel has one big logical repo, where everything eventually gets merged, but the various subsystems have their own separate physical repos where the day to day work gets done.

Submodules are mostly intended for situations where you have a strong dependency on third-party code that has no reciprocal dependency.  For example, if your application depended heavily on specific bleeding-edge versions of a widely-used library like numpy, to which you contribute regular patches, but otherwise they don't know your application exists.