答: Golang handles this by using the parser module to parse the test files, and then generating a new program which runs the test files, compiling that program, and executing it: https://code.google.com/p/go/source/browse/src/cmd/go/test.go#1022

Title: How do statically typed languages handle test discovery?

Body:
I come from a Python background, so I'm used to pretty automatic test discovery. For example, the py.test library automatically locates any files which begin with test, finds classes whose names start with Test inside of the those files, and then calls all the functions whose names start with test_ in those classes.

This type of test discovery is enabled by Python's deep support for reflection and dynamism.

These features are often absent in statically typed languages, because they're difficult to make integrate with the type system.

Therefore, I'm interested in hearing about what approaches statically typed languages use to make test discovery simpler?


问:
Database Schema Data Independence
I'm currently reading about database schemas about how the three-level ANSI-SPARC architecture works and i'm a bit confused about a concept it's talking about.

My question is what would happen if an application was modified so it could store data for a column not defined in the logical schema?

The book i'm reading talks about:

... the addition or removal of new entities, attributes or relationships should be possible without having to change existing external schemas or having to rewrite application programs." - Database Systems: A practical Approach to Design, Implementation and Management. Page: 40 (Part: 2.1.5)

How does the logical schema handle input (columns) from applications for which it is not defined in the logical schema?

ANSI-SPARC architecture: http://en.wikipedia.org/wiki/ANSI-SPARC_Architecture

答:
For those who don't have that reference handy, the Wikipedia article on ANSI-SPARC provides a decent overview.

How does the logical schema handle input (columns) from applications for which it is not defined in the logical schema?

The short answer is that the logical schema can't handle (store) input if it doesn't have columns defined for it.

The long answer is that I think the problem is that you've got the frame of reference backwards.

The internal or logical schema needs to have a representation for all of the data that all of the applications (external schemas) may present.  But the external schemas don't need to know of all of the potentialities that are possible within the logical schema.

What that quote is focusing on is adding a new, external view onto the existing database.  That will likely require the logical schema to be extended to handle the new bits of data that the new view will require.  But the changes required for this new external view will have zero bearing upon the existing external views and their perception of what the database schema looks like.

To use a concrete example...

Say I have an application that tracks ticket sales.  I have all sorts of wonderful schemas built around pricing, history, seating, sellers, and buyers.  So my ticket sales app has a view of what it perceives the database schema to be.

Later on, I'm talking with another business partner and realize that with a little modification to the database and a new external view, I can easily track auction results.  The premise of that quote is that I should be able to make changes to the logical schema (my database) to support my new auction results application without having to make any changes to my ticket sales tracking application.

ContentLicense: CC BY-SA 3.0

Title: Database Schema Data Independence


问:
Web Services exposed by url
Lets take some random internet site which i am not aware of any API it exposes for it's web services if there are any , is there a way to query that URL for exposed web services ? </p>

答: There is no defined way to "query" a site about any web services it might offer. Typically, if the site wants you to be able to query it, the method to do so will be clearly indicated (perhaps find a "Developers" link on the site). Otherwise, the site probably doesn't want you to query it.</p>

Title: Web Services exposed by url


问:
Is it legal to reflector some .NET code and use it in a commercial application?
I'm working on a commercial application that requires .NET 4.0 Client Profile, but I need to make a call to HttpUtility.ParseQueryString, which is not included in the Client Profile but it is in the normal one.

So I just figured out that I can use Reflector to get the whole method and all the other required methods for it to work and add it to my app. This way I won't need to change the requirement from Client Profile to the normal one which is a lot heavier just to call a single method. Would this be illegal? Do I have to change the applications target framework just for a single method?

答:
I wonder.

Considering Microsoft has recently posted an entire browser for their source code at http://referencesource.microsoft.com/ and the license in the help does not seem particularly restrictive this might become a lot less ambiguous now.

ContentLicense: CC BY-SA 2.5


问:
Solutions to problems that .NET can solve better than Java (or vice-versa)
To me it seems these are two different platforms that address similar enterprise(but not only) problems. I'm interested however in problems that Java can solve better than C#/.NET or C#/.NET can solve better than Java. Leaving aside the 'cost' factor, since that is somehow not an issue for big enterprise companies (the developers probably cost more than the licenses from Microsoft - it's just a thought) and even for small projects there are free/open-source tools for .NET so the cost can be zero for the .NET world as well. With Mono, you can port .NET to Linux and MacOS as well so the benefit that Java had(cross platform) isn't THE decision factor to use Java nowadays..

What real world problems can you think of where .NET would be a much better solution than Java, and vice-versa? I'm only interested in solutions to problems.

答:
the only significant differences that I am aware of - and my information may be out of date - are:

MS Office automation/integration is easier in .NET

C# supports 'unsafe' code for direct memory manipulation; Java I believe still lacks this. You don't need this often, but when you do the difference in efficiency can be incredible

integration with non-VM libraries (COM/DLL/etc) seems to be easier in .NET than Java (unless JINI has vastly improved over the years)

Java actually works on more than the Windows platform without being six versions out of date

If you don't need any of these things, then it doesn't matter - though Java is far less expensive for the 'official' tool set ;-)


问:
How to get money from reluctant client?
I completed this website 4 months ago. (I would like to keep the website anonymous - if this post comes up on google search by customers, it will have a negative impact on their business). We did several iterations, the client was very demanding (and nosy), I complied with every single thing that was wanted, including the font-size of the footer which destroyed the aesthetic looks by quite a bit; (and they messed with the colours too, making it look dangerously childish and unprofessional).

Anyway, the client was very friendly during the whole process. After getting all the requirements I accepted to build the website for £950 and I charged him £150 in advance so he wouldn't want to bail out after I started the work. The requirements kept changing quite a lot, I made adjustments as and completed the website just 5 days late, w.r.t. the agreed date, in-spite all the changes in requirements.

That was four months ago. They have never returned my calls nor replied to my emails since then. How do I get the money back from them? I really need some advice on this, this is the second time someone has not paid me.

Points to be noted:

We did not sign any contract - the client was a friend of a friend.

I still hold the passwords for ftp, cpanel and everything. I don't want to bring the site down; somehow it doesn't seem ethical to me.

I posted this on Stack Overflow and it was closed, I was redirected here.

EDIT

Thank you everyone, for your enormous support. I thought I should include some more details: The client is hosting the site; as in, I made them register and use their own debit card to buy the domain name, webspace and everything, I just have the passwords for his cpanel, and ftp (well, I have access to cpanel that pretty much gives me access to many things).

Now, if I give them a warning, he might change the password to cpanel, but I am fairly sure they doesn't know about ftp's.

UPDATE

I followed Anna Lear's advice and sent the final invoice, on Saturday, with a warning that I will take the site down if he doesn't respond to my email before this Tuesday. They havn't replied to my emails yet, but I will let you know how this goes. Thanks much for your support. I plan to put up a holding page as Darknight suggested after Tuesday.

Points

I don't have a server space of my own, however I have few web spaces of my clients but I don't want to use them for this kind of purpose.

RESULTS

After my follow up of final invoice and warning, the client refused to anything. workman's advice seemed to be the most sensible to me. I mirrored the site to my own webspace, logged into his CPanel and forwarded the website to my site. Once that was done, I put up a holding page on my site so anyone going to the website would see a holdup page (nothing fishy, just an Under Construction page). Of course, this was all very weak in the sense that if my client knew about CPanel he could just remove the redirection. But, I had this second chance to get back to him and I was relying on him not knowing anything.

Two hours later, I got a call from the said client, (and  acting as if they did not get any of my voice mails or emails) and asked me to get the site back up. I, of-course, said I had to be paid and two days after that I received a bank transfer. The site's back up and running now.

Just wanted to say thank you all very much, I was very desperate when I had started this question. You are the best, not only you told me to learn the lesson (which I did) you also gave me a very very good solution that seemed to be very ethical (almost) to me.

A BIG thank you to workman!

If I could choose more than once answer, I would have chosen Anna Lear  too, but since I followed workman's advice I had to pick that up. People who made a point about not taking the site down without consulting a lawyer, thanks a lot.

答:
You're hosting his site - doesn't this incur some sort of continuing cost to you?

That said - I think you need to issue him a final invoice and, if he does not pay, turn the site off.

Past that, if you cannot get in contact with the customer, you should find a good laywer and talk about your legal options.

EDIT: Given that he's paying for the hosting, my answer becomes send him a final invoice. If he doesn't pay it, go talk to a good lawyer about your legal options. Discuss whether or not you can take the site down, should he not pay.

Title: How to get money from reluctant client?


问:
Algorithm for base-conversion in C?
I put in this code which does what it's supposed to do, but perhaps there is a better or more general approach? I'm converting a 4-digit base 10 number e.g. "11" to base 16 e.g. "17" (which gets written out on the display as 11 when called with 17 because the function takes bits as argument).

```<code>    int hex1 = perhapsprime / 1000;
    int hex2 = (perhapsprime - hex1*1000) / 100;
    int hex3 = (perhapsprime - hex2*100 -hex1*1000) / 10;
    int hex4 = perhapsprime - hex3*10 - hex2*100 - hex1*1000;
    int test = 16*16*16*hex1+16*16*hex2+16*hex3+hex4;
</code>```

The integer "test" will have the correct value after this code was run, but is there a more efficient way to do it?

Update

I settled for the following that appears to be able to convert any number of digits to BCD:

```<code>int tbcd(int v) {
    int total = 0;
    int resultbase = 1;
    while(v > 0) {
        total += resultbase * (v % 10);
        resultbase *= 16;
        v /= 10;
    }
    return total;
}
</code>```

答:
This is not a conversion to base 16. This is a conversion to BCD: Binary Coded Decimal. You are taking a (presumed) 4 digit decimal number and placing each decimal digit into its own 4 bit hexadecimal digit.

This is a perfectly legitimate thing to do, once you give it the right name. This may also help: http://en.wikipedia.org/wiki/Binary-coded_decimal.

Yes, there are much more general and less error-prone ways to convert integers into BCD. See https://stackoverflow.com/questions/1408361/decimal-to-bcd-conversion.

ContentLicense: CC BY-SA 4.0

Title: Algorithm for base-conversion in C?


问:
Unit testing behaviours without coupling to implementation details
In his talk TDD, where did it all go wrong, Ian Cooper pushes Kent Beck's original intention behind unit testing in TDD (to test behaviours, not methods of classes specifically) and argues for avoiding coupling the tests to the implementation.

In the case of behaviour like save X to some data source in a system with a typical set of services and repositories, how can we unit test the saving of some data at the service level, through the repository, without coupling the test to implementation details (like calling a specific method)? Is avoiding this kind of coupling actually not worth the effort/bad in some way?

答:
My interpretation of that talk is:

test components, not classes.

test components through their interface ports.

It's not stated in the talk, but I think the assumed context for the advice is something like:

you are developing a system for users, not, say, a utility library or framework.

the goal of testing is to successfully deliver as much as possible within a competitive budget.

components are writen in a single, mature, probably statically typed, language like C#/Java.

a component is of the order of 10000-50000 lines; a Maven or VS project, OSGI plugin, etc.

components are written by a single developer, or closely integrated team.

you are following the terminology and approach of something like the hexagonal architecture

a component port is where you leave the local language, and its type system, behind, switching to http/SQL/XML/bytes/...

wrapping every port are typed interfaces, in the Java/C# sense, which can have implementations switched out to switch technologies.

So testing a component is the largest possible scope in which something can still be reasonably called unit testing. This is rather different from how some people, especially academics, use the term. It's nothing like the examples in the typical unit test tool tutorial. It does, however, match its origin in hardware testing; boards and modules are unit tested, not wires and screws. Or at least you don't build a mock Boeing to test a screw...

Extrapolating from that, and throwing in some of my own thoughts,

Every interface is going to be either an input, an output, or a collaborator (like a database).

you test the input interfaces; call the methods, assert the return values.

you mock the output interfaces; verify the expected methods are called for a given test case.

you fake the collaborators; provide a simple but working implementation

If you do that properly and cleanly, you barely need a mocking tool; it only gets used a few times per system.

A database is generally a collaborator, so it gets faked rather than mocked. This would be painful to implement by hand; luckily such things already exist.

The basic test pattern is do some sequence of operations (e.g. save and reload of a document); confirm it works. This is the same as for any other test scenario; no (working) implementation change is likely to cause such a test to fail.

The exception is where database records are written but never read by the system under test; e.g. audit logs or similar. These are outputs, and so should be mocked. The test pattern is do some sequence of operations; confirm the audit interface was called with methods and arguments as specified.

Note that even here, providing you are using a type-safe mocking tool like mockito, renaming an interface method cannot cause a test failure. If you use an IDE with the tests loaded, it will be refactored along with the method rename. If you dont, the test won't compile.


问:
Unit Testing a method that contains two output type parameters
I was following a book Art of Unit Testing, This book says that You must not have any logic in Your asserts as this reduces readability of test, or I may be testing too many things at a time. Suppose there is a method with signature as below:

```<code>public int DoSomething(int variable1, out string variable2, out float variable3)
{
...
}
</code>```

How should I test this method, as I have to assert on return value, variable2, variable3 ???

Sample Test method that tests all of these three concerns:

```<code>    public void DosSomethingTest(){
        //add code for arrange
        int expectedvalue=12;
        string expectedVariable1="I am expected";
        string expectedVariable3=15.9;
        string actualVariable1, actualVariable3;
        var sut=new Foo();
        int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable3);

        //this is where I am testing 3 concerns in one test. Is there a better way?
        if(actualValue==expectedvalue){
            if(expectedVariable1==actualVariable1){
                if(expectedVariable3!=actualVariable3){
                    Assert.Fail("Unexpected variable2 returned");//pseudo code
                }
            }
            else{
                Assert.Fail("Unexpected variable1 returned");//pseudo code
            }
        }
        else{
            Assert.Fail("Unexpected Value returned");//pseudo code
        }
    }
</code>```

Approach 2

Seperate Test methods that tests concerns separately:

```<code>    public void DosSomething_Passing15_Returns12Test(){
        //add code for arrange
        int expectedvalue=12;
        string expectedVariable1="I am expected";
        string expectedVariable3=15.9;
        string actualVariable1, actualVariable3;
        var sut=new Foo();
        int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable3);

        Assert.IsTrue(actualValue, expectedvalue);
    }

    public void DosSomething_Passing15_ReturnsExpectedVariable1Test(){
        //add code for arrange
        int expectedvalue=12;
        string expectedVariable1="I am expected";
        string expectedVariable3=15.9;
        string actualVariable1, actualVariable3;
        var sut=new Foo();
        int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable3);

        Assert.IsTrue(actualVariable1, expectedVariable1);
    }

    public void DosSomething_Passing15_ReturnsExpectedVariable2Test(){
        //add code for arrange
        int expectedvalue=12;
        string expectedVariable1="I am expected";
        string expectedVariable3=15.9;
        string actualVariable1, actualVariable3;
        var sut=new Foo();
        int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable3);

        Assert.IsTrue(actualVariable3, expectedVariable3);
    }
</code>```

Isn't approach 2 adhering to "Tests should not test more than one concern"?

Conclusion

If redesigning of SUT is possible:

There should ideally be no out parameter instead an aggregate class
should be evaluated in Asserts.

If there are unrelated out parameters then SUT method should be
refactored into multiple methods, then those new methods should have their own Test methods and they will then test only one concern.

If redesigning of SUT is not possible then as per the answer there will be three Asserts

答:
You call this function a number of times with chosen values for variable1. For each input value, you check that each of the output variables and return value match the expected result. You write those as single asserts on each expected value, so that a failure pinpoints the fault. Each input value and set of output values constitutes a single test.

The values you choose should span the range of permitted values, and should particularly explore any known values that represent edge conditions for the algorithm the function uses. Some people call this "grey box" testing (not quite black).

You also test (or attempt to test) the function for aberrant behaviour (perhaps variable1 must be positive, so you check that it fails correctly for negative values.).

A data driven approach works well, where all the relevant values are pre-computed and stored in a database or other structure. The actual unit test should contain little or no computation.


问:
How do statically typed languages handle test discovery?
I come from a Python background, so I'm used to pretty automatic test discovery. For example, the py.test library automatically locates any files which begin with test, finds classes whose names start with Test inside of the those files, and then calls all the functions whose names start with test_ in those classes.

This type of test discovery is enabled by Python's deep support for reflection and dynamism.

These features are often absent in statically typed languages, because they're difficult to make integrate with the type system.

Therefore, I'm interested in hearing about what approaches statically typed languages use to make test discovery simpler?

答:
Almost all statically typed language have runtime type and method discovery. The main exception is C/C++.

In the .NET world, reflection and attributes provide a particularly rich environment for test discovery and management, which both Visual Studio and NUnit utilise.

The Java world has something similar, see JUnit.

Those are the "big three". Scala, Haskell and some other related languages are also statically typed, but provide ample support for type discovery.

I guess the static typed world can do just about everything you can do in Python, just a bit differently. C/C++ is a world of its own.


问:
Algorithm for Learning development
This is a fairly general question. I know a bit of Perl and Python and I am looking to learn programming in more depth so that once I get the hang of it I can start developing applications and then websites.

I would like to know of an algorithm (sequence of steps :)) that could describe my approach towards learning programming in general. I have posted small questions on Perl/Python and I have recieved great help from everyone.

Note:- I am not in a hurry to learn. I know it takes time and that's fine.

Please give any suggestions you think are valid. Also, please don't push me to learn Lisp, Haskell etc - I am a beginner.

答:
```<code>while (stillLearning)
{
    read(some);
    practice(lots);
}
</code>```

Title: Algorithm for Learning development


答:
An assert is an encapsulation of the test logic:

```<code>assert foo(x) is y
</code>```

can be written as

```<code>if foo(x) is not y then throw AssertionError
</code>```

Using assert is encouraged since it's shorter, more readable, and unit testing frameworks may recognize it and treat it specially.

Now, you want to have those benefits for assertions that encapsulate a different logic - one that also tests out parameters. For this - you should write your own assertion helper!

The logic will be inside the assertion helper and the assertion statement itself will remain logicless. True - it's syntax will be a bit complex, as you have to specify the method to be tested, the input parameters, the expected return value and the expected out parameter values. Still, the fact that you have out parameters means you are using a language that is not Java so you should be able to achieve a nice syntax, that can be readable with the right line-breaking and indentation conventions.

Maybe your testing framework even have such helper!

UPDATE

You are concerned about testing multiple things with the assertion. OOP can help you here - first create an object that encapsulates the specific call to the method, and then use methods of that object to assert the different parts of the result of that call:

```<code>ComplexAssert.AssertWithOutParameters(sut.DoSomething,15)
    .AssertReturnValue(expectedValue,"Unexpected Value returned")
    .AssertOutParameter(1,expectedVariable1,"Unexpected variable1 returned")
    .AssertOutParameter(2,expectedVariable3,"Unexpected variable2 returned");
</code>```

Now everything is neat and readable - the tested method is only called once and still each assertions gets it's own method call.

Title: Unit Testing a method that contains two output type parameters

Body:
I was following a book Art of Unit Testing, This book says that You must not have any logic in Your asserts as this reduces readability of test, or I may be testing too many things at a time. Suppose there is a method with signature as below:

```<code>public int DoSomething(int variable1, out string variable2, out float variable3)
{
...
}
</code>```

How should I test this method, as I have to assert on return value, variable2, variable3 ???

Sample Test method that tests all of these three concerns:

```<code>    public void DosSomethingTest(){
        //add code for arrange
        int expectedvalue=12;
        string expectedVariable1="I am expected";
        string expectedVariable3=15.9;
        string actualVariable1, actualVariable3;
        var sut=new Foo();
        int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable3);

        //this is where I am testing 3 concerns in one test. Is there a better way?
        if(actualValue==expectedvalue){
            if(expectedVariable1==actualVariable1){
                if(expectedVariable3!=actualVariable3){
                    Assert.Fail("Unexpected variable2 returned");//pseudo code
                }
            }
            else{
                Assert.Fail("Unexpected variable1 returned");//pseudo code
            }
        }
        else{
            Assert.Fail("Unexpected Value returned");//pseudo code
        }
    }
</code>```

Approach 2

Seperate Test methods that tests concerns separately:

```<code>    public void DosSomething_Passing15_Returns12Test(){
        //add code for arrange
        int expectedvalue=12;
        string expectedVariable1="I am expected";
        string expectedVariable3=15.9;
        string actualVariable1, actualVariable3;
        var sut=new Foo();
        int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable3);

        Assert.IsTrue(actualValue, expectedvalue);
    }

    public void DosSomething_Passing15_ReturnsExpectedVariable1Test(){
        //add code for arrange
        int expectedvalue=12;
        string expectedVariable1="I am expected";
        string expectedVariable3=15.9;
        string actualVariable1, actualVariable3;
        var sut=new Foo();
        int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable3);

        Assert.IsTrue(actualVariable1, expectedVariable1);
    }

    public void DosSomething_Passing15_ReturnsExpectedVariable2Test(){
        //add code for arrange
        int expectedvalue=12;
        string expectedVariable1="I am expected";
        string expectedVariable3=15.9;
        string actualVariable1, actualVariable3;
        var sut=new Foo();
        int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable3);

        Assert.IsTrue(actualVariable3, expectedVariable3);
    }
</code>```

Isn't approach 2 adhering to "Tests should not test more than one concern"?

Conclusion

If redesigning of SUT is possible:

There should ideally be no out parameter instead an aggregate class
should be evaluated in Asserts.

If there are unrelated out parameters then SUT method should be
refactored into multiple methods, then those new methods should have their own Test methods and they will then test only one concern.

If redesigning of SUT is not possible then as per the answer there will be three Asserts

Body:
An assert is an encapsulation of the test logic:

assert foo(x) is y

can be written as

if foo(x) is not y then throw AssertionError

Using assert is encouraged since it's shorter, more readable, and unit testing frameworks may recognize it and treat it specially.

Now, you want to have those benefits for assertions that encapsulate a different logic - one that also tests out parameters. For this - you should write your own assertion helper!

The logic will be inside the assertion helper and the assertion statement itself will remain logicless. True - it's syntax will be a bit complex, as you have to specify the method to be tested, the input parameters, the expected return value and the expected out parameter values. Still, the fact that you have out parameters means you are using a language that is not Java so you should be able to achieve a nice syntax, that can be readable with the right line-breaking and indentation conventions.

Maybe your testing framework even have such helper!

UPDATE

You are concerned about testing multiple things with the assertion. OOP can help you here - first create an object that encapsulates the specific call to the method, and then use methods of that object to assert the different parts of the result of that call:

ComplexAssert.AssertWithOutParameters(sut.DoSomething,15)
    .AssertReturnValue(expectedValue,"Unexpected Value returned")
    .AssertOutParameter(1,expectedVariable1,"Unexpected variable1 returned")
    .AssertOutParameter(2,expectedVariable3,"Unexpected variable2 returned");

Now everything is neat and readable - the tested method is only called once and still each assertions gets it's own method call.


答:
If someone tells you there is something wrong with:

```<code>int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable2);

AssertEquals("actualValue", 1, actualValue);
AssertEquals("actualVariable1", 23, actualVariable1);
AssertEquals("actualVariable2", 14, actualVariable2);
</code>```

then they are very likely being overly pedantic, applying a rule blindly without understanding anything of context. I mean, you probably generally should consider simplifying a function with multiple out arguments.

But if you have them, that's how you test them.

Body:
If someone tells you there is something wrong with:

int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable2);

AssertEquals("actualValue", 1, actualValue);
AssertEquals("actualVariable1", 23, actualVariable1);
AssertEquals("actualVariable2", 14, actualVariable2);

then they are very likely being overly pedantic, applying a rule blindly without understanding anything of context. I mean, you probably generally should consider simplifying a function with multiple out arguments.

But if you have them, that's how you test them.


问:
Trouble understanding the COCOMO model
In the basic COCOMO Model which is used to estimate the development time of software

Effort : a * KLOC^b  = X person months

Development time : c * Effort^d =  Y months

where a , b , c , d are constants derived from the table below depending on the type of your software project

Question 1

Assuming X = 10 , Effort will be equal to 10 person months.

Does 10 person months mean that the effort required to complete this project will be 1 month if we have 10 people working on it

OR

Does 10 person month mean that the effort required to complete the project will be 10 months if we have 10 people working on it.

Question 2

Do the constants have any SI units like the SI unit of Effort is person months

I am confused by the terminology

答:
Team size is one of the inputs to the model; you only get to use the good coefficients if you have an existing, small and experienced team. Which means a team experienced at working together, with each other, on this general class of problem.

You can perhaps add 1 or 2 members, but anything more and you have invalidated the model assumptions. Go back and recalculate with the new coefficients and it will generally provide an estimate of just how much you would delay the project by adding more people.

For the example of a woman having a baby, doing so would move the project from 'routine, within personell capabilities' to 'WWII-scale open-ended genetics research effort that may or may not be physically possible'.

There isn't a line in the chart for that, but you can extrapolate...

Title: Trouble understanding the COCOMO model


问:
Why do higher level languages have neither xor nor nand short-circuit operators?
While many higher level languages have bitwise (exclusive or) and bitwise (exclusive and), for instance C, C++, Java, etc. I'm curious why the ( vastly more useful ) logical short-circuit operators don't have this functionality? Is it simply due to the capacity of being able to concatenate logic through use of "not"?

This question is mainly to do with the language design considerations....

答:
NAND is either !a || !b or !(a && b) both will be short circuited when a is false.

XOR can't be short circuited at all as @delnan explained


答:
Perl6 has got short-circuit XOR but its meaning of XOR is specific. I've repeat my comment jist here: there are two meanings of XOR:

if count of true arguments is odd

if only exactly one argument is true

Example for difference: XOR (True, True, True) gives True with the 1st meaning and False with the 2nd meaning. If Perl6 machine detects at least 2 arguments are true, it stops evaluation of rest because result is already determined as False.

But, for the 1st meaning (more traditional), one can't determine final result until all arguments are evaluated.

I think we should invent special clarification terms for these XOR variants, even if they won't be used outside of this discussion.

Title: Why do higher level languages have neither xor nor nand short-circuit operators?

Body:
While many higher level languages have bitwise (exclusive or) and bitwise (exclusive and), for instance C, C++, Java, etc. I'm curious why the ( vastly more useful ) logical short-circuit operators don't have this functionality? Is it simply due to the capacity of being able to concatenate logic through use of "not"?

This question is mainly to do with the language design considerations....


答:
The short answer is because the truth table for XOR doesn't have a single row of True's or False's.

If the first argument to OR is True, then the answer is True, regardless of the second argument.

If the first argument of AND is False, then the answer is False regardless of the second argument.

BUT If the first argument of XOR is True, or False, it still needs the second argument because the truth value may "flip":

True OR ? = True (always)

False AND ? = False (always)

True XOR ? = False or True

False XOR ? = True or False


答:
Before going too far two books that you really should read:

The Mythical Man Month

Software Estimation: Demystifying the Black Art: Demystifying the Black Art

The basic COCOMO model has some issues with it that were outdated and addressed in the COCOMO II model.  From the cited wikipedia page:

COCOMO II is the successor of COCOMO 81 and is better suited for estimating modern software development projects. It provides more support for modern software development processes and an updated project database. The need for the new model came as software development technology moved from mainframe and overnight batch processing to desktop development, code reusability, and the use of off-the-shelf software components.

While the effort of "10 man months" is an estimation of effort it assumes the perfectly divisible task.  If you are digging 10 holes in the ground, you can have one person dig 10 holes or 10 people dig one hole - and the 10 people will do it about 10 times faster.  As has often been noted, this doesn't work well with software programming.

Of particular interest in this is the paper "Effect of Schedule Compression on Project Effort" [link] which looks into the relative cost of the percent of the most efficient schedule.

Another thing to read is How Software Estimation Tools Work written by one of the people who is often cited the algorithms for software estimation tools.

Effort / staff = time period

As you note, that doesn't work well for programming.

From something I wrote a long time back and didn't cite well I had the following table to tack on to the end of the estimated effort (digging a bit more, it looks a bit like something from the COCOMO II Schedule Equation).  Take a default schedule multiplier (3.67) multiply the cube root of the time estimation (your case 10 months).

3.67 * 101/3 = 7.9

This represents the best case for a software development project timeline.

Where do these numbers come from? Fitting 20k projects to a curve.

From this 7.9 we've got a few things we can get from it:

Least effort = 2x optimal delivery time (15.8 months)

Region of impossibility = < 75% of best case delivery time (5.9 months)

There's a lot going on behind the COCOMO and COCOMO II model.  These numbers are fits to a sampling of huge numbers of software projects and unless you understand what you are feeding into the model (to match what the model expects) the numbers you get out won't match anything even vaguely resembling reality.

Realize also that you've gotten about 2/3 of the way through the estimation process.  It doesn't end with the estimated effort (10 man months) and continues on with the scheduling.  That last bit of the Duration is often dropped or forgotten when the estimate of 10 man moths comes out and they'll just toss 3 people on it and have it done in 3 months (and then it fails because its in region of impossibility)

Further reading:

An Empirical Validation of Software Cost Estimation Models

COCOMO II Model Definition Manual

Effect of Schedule Compression on Project Effort

Title: Trouble understanding the COCOMO model

Body:
In the basic COCOMO Model which is used to estimate the development time of software

Effort : a * KLOC^b  = X person months

Development time : c * Effort^d =  Y months

where a , b , c , d are constants derived from the table below depending on the type of your software project

Question 1

Assuming X = 10 , Effort will be equal to 10 person months.

Does 10 person months mean that the effort required to complete this project will be 1 month if we have 10 people working on it

OR

Does 10 person month mean that the effort required to complete the project will be 10 months if we have 10 people working on it.

Question 2

Do the constants have any SI units like the SI unit of Effort is person months

I am confused by the terminology


答:
The object of the exercise with COCOMO, as with any other software estimating methodology, is to answer two questions: How much will it cost and how long will it take?

What the COCOMO man-months of effort and months of duration results mean is that, when the project is over, it is estimated that you will have paid out the equivalent of that many man-months in salary, and so many months will have gone by on the calendar.

It does NOT mean that one man can do it in that many months, and it does NOT mean that that many men can do it in one month.

COCOMO estimates are based on deliverable source lines of code estimates, and yield results in man-months, because both deliverable source lines of code and expended man-months are easy to measure after-the-fact.  One of them comes directly from the delivered code, and the other comes directly from the payroll data for the project.  The magic numbers in COCOMO were developed by doing postmortem measurements on timecard data and line count for a large number of projects.

This allows you to calibrate the estimator to your particular organization, and improve the overall quality of your particular organization's estimates.  Boehm et al strongly recommend every organization do this.  The numbers they give are good starting points for an individual organization, but they are not engraved in stone tablets and they are not the Final Answer.

Basic COCOMO gives you BOTH the nominal total effort, in man-months, AND the nominal project duration, in months.  To get the nominal number of people required over that duration, you divide effort by duration.

That's nominal.  Basic COCOMO DOES NOT ADDRESS off-nominal schedules, either compressed or stretched out.  To account for the effect of management monkey-wrenching the schedule, you must use Intermediate COCOMO or Detailed COCOMO.

To answer your second question: It is not possible to assign units to the individual magic numbers of Basic COCOMO, because the system is formally underspecified.  You have no way to decide which units go with which magic number, and which units get cancelled in the dimensional (factor label) analysis.

Title: Trouble understanding the COCOMO model


问:
How to distribute, one virtual token to each person in this world, and make sure nobody gets more than one?
How to distribute, one virtual token to each person in this world, and make sure nobody gets more than one?

In other words, how to prevent a user from creating more than one user account in a site?

What's this problem called? Is there any specific name to this problem? What are the solutions? Thanks.

答:
You could take a look at the Indian Aadhaar program: http://en.wikipedia.org/wiki/Aadhaar
Whcih tries to provide each Indian (now +future) with a unique ID, which can also serve for banking etc....

To add a little rant:
The question asked by the OP is not a technical one per se. Sure, you could discuss endlessly about identification schemmas etc. but the much more daunting task is the organization of the whole scheme. You need to have offices even in the most rural areas of the world (passport? social security number?) where illiteracy is rampant. Also, you need to have a schema which accomodates high birth rates and even can track children in region where the infrastructure is very sparse.
Since India has much of this problems, and it's Aadhaar schema seems tu be sucessful, I would look at it and try to emulate it's practices.


答:
Binary

Nand

Lets look at how NAND can be implemented with just AND or OR gates.

NAND becomes one of:

```<code>!(a && b)
!a || !b
</code>```

Either of these can be seen as short circuiting.  The reason that NAND doesn't exist is that it is easily rewritten as not(a and b)

Xor

XOR, is at its heart, a parity checker.  To check the parity of two values, you need to test both values.  This is why it is fundamentally not able to short circuit it - you can't validate if the value is true or false until you test all the values.

Looking at how XOR is written with AND and OR gates:

```<code>(a || b) && !(a && b)
</code>```

If a is true, the OR part of the xor can be short circuited, however it also means that the AND part cannot be short circuited.

N-ary

N-ary operands take any number of inputs (compared to the binary ones that just take two).

Nand

The n-ary NAND is

```<code>!(a && b && c && d ... )
</code>```

This again can be short circuited in that as soon as one of operands evaluates to false, the value of the NAND is true.

Xor

There are two different interpretations of the n-ary xor:

An odd number of true operand

One and only one true operand

The first one is in common usage (see XOR at Wolfram):

For multiple arguments, XOR is defined to be true if an odd number of its arguments are true, and false otherwise. This definition is quite common in computer science, where XOR is usually thought of as addition modulo 2.

From Wikipedia

Strict reading of the definition of exclusive or, or observation of the IEC rectangular symbol, raises the question of correct behaviour with additional inputs. If a logic gate were to accept three or more inputs and produce a true output if exactly one of those inputs were true, then it would in effect be a one-hot detector (and indeed this is the case for only two inputs). However, it is rarely implemented this way in practice.

The 'one hot' xor may be short circuited when evaluating the expression when finding the second true value.

Otherwise, again, the XOR is more commonly implemented as the "odd number of true values" which serves as a parity checker and requires the evaluation of all the operands to determine the truth of the expression as the last value evaluated can always change the truth of the expression.

Body:
Binary

Nand

Lets look at how NAND can be implemented with just AND or OR gates.

NAND becomes one of:

!(a && b)
!a || !b

Either of these can be seen as short circuiting.  The reason that NAND doesn't exist is that it is easily rewritten as not(a and b)

Xor

XOR, is at its heart, a parity checker.  To check the parity of two values, you need to test both values.  This is why it is fundamentally not able to short circuit it - you can't validate if the value is true or false until you test all the values.

Looking at how XOR is written with AND and OR gates:

(a || b) && !(a && b)

If a is true, the OR part of the xor can be short circuited, however it also means that the AND part cannot be short circuited.

N-ary

N-ary operands take any number of inputs (compared to the binary ones that just take two).

Nand

The n-ary NAND is

!(a && b && c && d ... )

This again can be short circuited in that as soon as one of operands evaluates to false, the value of the NAND is true.

Xor

There are two different interpretations of the n-ary xor:

An odd number of true operand

One and only one true operand

The first one is in common usage (see XOR at Wolfram):

For multiple arguments, XOR is defined to be true if an odd number of its arguments are true, and false otherwise. This definition is quite common in computer science, where XOR is usually thought of as addition modulo 2.

From Wikipedia

Strict reading of the definition of exclusive or, or observation of the IEC rectangular symbol, raises the question of correct behaviour with additional inputs. If a logic gate were to accept three or more inputs and produce a true output if exactly one of those inputs were true, then it would in effect be a one-hot detector (and indeed this is the case for only two inputs). However, it is rarely implemented this way in practice.

The 'one hot' xor may be short circuited when evaluating the expression when finding the second true value.

Otherwise, again, the XOR is more commonly implemented as the "odd number of true values" which serves as a parity checker and requires the evaluation of all the operands to determine the truth of the expression as the last value evaluated can always change the truth of the expression.


问:
Best books on the theory and practice of software architecture?
I have a couple of developers at my company who wish to move from programming into architecture. What are the best books out there on the theory and practice of software architecture? Include a cover picture if you can.

Feel free to include general books, and also books that relate to a specific technology.

答: I've found volumes 1 and 4 of Pattern-Oriented Software Architecture to be very useful.  I'm sure the other volumes are good too, I just haven't read them so I can't recommend them.</p>


问:
How does Observer create loosely-coupled design?
I completely understand the Observer design pattern, what it is for and how to implement it. I also understand what the term 'loosely-coupled' means.

But I'm not sure how Observer makes designs more loosely-coupled.

For example, let's say I want objects B and C to get updates from object A about it's state. The Observer pattern is a great way to do that. But one could also implement this with a more 'brute-force' way, not using the pattern.

Please explain to me how the Observer pattern allows for more loosely-coupled designs. I'm not sure I completely understand. Thanks

(Again, I understand what 'loosely-coupled' means, but not exactly how Observer allows for designs to be more loosely-coupled).

答:
By using the observer pattern, A needs not know about B or C. If you explicitly had A call B and C then it would necessarily know about B and C.

Depending on how you do it, B and C don't even know about A, some D ties them all together.

That "lack of knowledge" is at the core of decoupling components.


问:
When allowing a user to change passwords, should I generate a new salt?
In my database, I have a column for the hashed password and the salt.  My application allows users to change their password.  Should I use the same salt for the password, or should I generate a new one?  Does it matter to the security of the application?</p>

答:
Yes.  Always generate a new salt when the password is changed.

Consider the following two scenarios:

Known not changing salt

I know you aren't changing the salt for your passwords.  I see admin has a salt that is 'xyz', and now I grind out the rainbow table for that salt.  Doesn't matter what you change your admin password to, I know it.

Repeated passwords

I know that the user had a hashed password of 'xyz:abcdef' (xyz is the salt, abcdef is the hashed password).  Then later I see that the hashed information is 'xyz:012345' - ok, they changed their password.  Yet later I see the hashed password as 'xyz:abcdef' and I know they've changed it back the first password.

These two scenarios where unnecessary information is given to the attacker is trivially avoided by generating new salt each time a password is generated.

You'll note that italics on the "when the password is changed" above. This was added after a comment by darkhogg asking if changing the salt more often is "better, worse, or just useless?"

On Security.SE the question of How often should I reset my salt? answers this.  Changing the salt more frequently than the password changes gives a possible attacker more information about the password than just one hash.

Changing the salt more often than the password doesn't mean that an attacker will be more hindered by the new information because the same correct password will still work no matter what the salt is.


问:
Can referentially transparent functions have side effects?
I read everywhere that referential transparency and side-effects are mutually exclusive for all functions, however, what about the case in which a function changes some state that has no effect on its outputs. For example:

```<code>global_variable = 0

def foo(a,b):
    global_variable += 2
    return a + b

# Other code ...
</code>```

Now, if you call this function, it seems to fit the standard definition of referential transparency while it also changes state and thus has side-effects.

With that in mind, I wonder, do I misunderstand referential transparency or the even the idea of a side-effect? Is it correct to say that the function foo is both referentially transparent and has side-effects?

To an extent, I feel that it is counter-productive to expand the definition of referential transparency with the condition that side-effects with no effect on the return value of a function still excludes functions from being considered referentially transparent.

答:
Referential Transparency means that you can replace an expression with the result of evaluating that expression everywhere in the program without changing the result of the program.

So, take the following program:

```<code>a = foo(1, 2) + foo(1, 2)
b = a + global_variable
</code>```

Referential Transparency says that I can replace every occurrence of foo(1, 2) with the result of evaluating foo(1, 2) (i.e. 3) without changing the meaning of the program. So, this program must have the exact same result as the preceding program:

```<code>a = 3 + 3
b = a + global_variable
</code>```

But it doesn't. The first program has a = 6 and b = 10 the second program has a = b = 6. Therefore, foo is not Referentially Transparent.

In fact, we can simplify the program even more, I just wanted to demonstrate what "everywhere in the program means":

```<code>foo(1, 2)
</code>```

must be the same as

```<code>3
</code>```

but the values of global_variable in both programs are different.

Note that a complex expression can be Referentially Transparent when viewed as a black box even if its constituent parts aren't.

For example:

```<code>def foo(a, b)
  static mutable_cache
  if not mutable_cache.has_key?([a, b])
    mutable_cache[[a, b]] = a + b
  end
  return mutable_cache[[a, b]]
end
</code>```

foo uses a mutable data structure to cache the results of the incredibly expensive operation of adding two integers. Even though that clearly is not RT, the function viewed as a black box is: I can replace foo(1, 2) with 3 everywhere without changing the result of the program as a whole. The side-effects are contained within foo. This is sometimes called externally pure. This is common in Scala, for example. The standard library favors referentially transparent interfaces, but sometimes the (hidden) implementation uses mutation under the hood.

Body:
Referential Transparency means that you can replace an expression with the result of evaluating that expression everywhere in the program without changing the result of the program.

So, take the following program:

a = foo(1, 2) + foo(1, 2)
b = a + global_variable

Referential Transparency says that I can replace every occurrence of foo(1, 2) with the result of evaluating foo(1, 2) (i.e. 3) without changing the meaning of the program. So, this program must have the exact same result as the preceding program:

a = 3 + 3
b = a + global_variable

But it doesn't. The first program has a = 6 and b = 10 the second program has a = b = 6. Therefore, foo is not Referentially Transparent.

In fact, we can simplify the program even more, I just wanted to demonstrate what "everywhere in the program means":

foo(1, 2)

must be the same as

3

but the values of global_variable in both programs are different.

Note that a complex expression can be Referentially Transparent when viewed as a black box even if its constituent parts aren't.

For example:

def foo(a, b)
  static mutable_cache
  if not mutable_cache.has_key?([a, b])
    mutable_cache[[a, b]] = a + b
  end
  return mutable_cache[[a, b]]
end

foo uses a mutable data structure to cache the results of the incredibly expensive operation of adding two integers. Even though that clearly is not RT, the function viewed as a black box is: I can replace foo(1, 2) with 3 everywhere without changing the result of the program as a whole. The side-effects are contained within foo. This is sometimes called externally pure. This is common in Scala, for example. The standard library favors referentially transparent interfaces, but sometimes the (hidden) implementation uses mutation under the hood.


答:
In your example, the variable global_variable is not referentially transparent, because its value is being mutated – we cannot arbitrarily exchange global_variable with 0 in the program.

While the function foo does have side effects, it could also be argued that it's a pure function because the return value is solely dependent on the function arguments. However, this is not a contradiction: foo is not a function in the mathematical sense, but more like a procedure (which is executed solely for side effects).

So the question is what exactly you mean by “referential transparency”:

A name is interchangeable with the definition it has been bound to:

Then yes, foo would be referentially transparent because inlining the function will not change the program behavior.

An expression is interchangeable with the value of that expression:

Then no, because substituting foo(x, y) with x + y does not maintain all side effects of the foo procedure.

Title: Can referentially transparent functions have side effects?

Body:
I read everywhere that referential transparency and side-effects are mutually exclusive for all functions, however, what about the case in which a function changes some state that has no effect on its outputs. For example:

```<code>global_variable = 0

def foo(a,b):
    global_variable += 2
    return a + b

# Other code ...
</code>```

Now, if you call this function, it seems to fit the standard definition of referential transparency while it also changes state and thus has side-effects.

With that in mind, I wonder, do I misunderstand referential transparency or the even the idea of a side-effect? Is it correct to say that the function foo is both referentially transparent and has side-effects?

To an extent, I feel that it is counter-productive to expand the definition of referential transparency with the condition that side-effects with no effect on the return value of a function still excludes functions from being considered referentially transparent.


问:
Storing web app passwords so that they can be retrieved
Short version

My boss wants me to store user passwords for an ASP.NET Web Forms web app we're developing in clear text, so that a user with admin rights can click a button and get back the current passwords for the accounts she controls.

I don't want to do that, because I deeply care about the security and privacy of users of a web app I am involved with in whatever way.

What would be a good way to store the passwords in an encrypted form, that can still however be decrypted?

I can't count on users having an email address, so sending the user a link to reset the password is not an option.

Read the following for more context.

Some context

This app was written by individuals who have little clue as to how software should be written. Lots of duplicated code, risks for SQL injection everywhere, no unit tests whatsoever, one new connection gets instantiated and opened for each and every query... name a bad practice, you'll find it in this codebase.

The passwords are currently stored as a simple MD5 of the original string, which is weak and horrible and everything, but still a tiny bit better than clear text.

I just finished implementing a feature request where the admin I was talking about can click a button and have an account automatically created for each employee she manages, with a random password.
I cringe while writing this, but one of the requirements was to export the credentials in an Excel spreadsheet. Which I did.

This is bad in and of itself, but then my boss said "What if the user loses the spreadsheet? Users are dumb, you know. There needs to be a way to get the passwords back."

Bang.

Getting him to listen to people who know what they're talking about is not an option, sadly.

The obvious suggestion would be "GTFO", I know, but rest assured that it's something I'll do as soon as I possibly can.

Meanwhile, I need to cheat and pretend I store passwords in clear text, while I do things in the best way possible to protect my users' passwords.

EDIT

For some reason people answering are assuming I'm a girl so, just for the record, I would like to clarify that I'm a guy. Not that it should make any difference, but hey ;)

答:
If you're dead set on being able to recover "the" password, I'd be tempted to try and give your users a tiny amount of security by hashing the passwords in such a way as to make it trivial to create a password that hashes to the same value without necessarily being the same password.  (Remember, a high percentage of your users will be using the same password for their banks, credit cards, and retirement accounts!!!)  This way, you can print out for your boss a password that will allow access to the account, without necessarily being identical to the user's password.  If you construct a 60-bit hash carefully (outlined below), you can reverse the hash for all passwords shorter than 10 characters.  Longer passwords will result in a false reversal... a password alias that creates a hash collision with the real password.

If you use a 60-bit hash, the probability of a collision is about 1 in a sextillion.  Put another way, if an attacker is allowed 1 billion login attempts per second, it will take her on average about 17 years to log in if the user uses a strong password.

One possible implementation is to create a generalized feedback shift register of 9 base94 digits.  pow(94,9) is just shy of pow(2, 60).  The characters can just be read out of the feedback register.  However, if the password is longer than 9 characters, the feedback will start mixing entropy of earlier characters back into the later characters, so longer passwords will be aliased by shorter passwords.

If you're supporting Unicode passwords, pick a normalization, normalize, and convert to UTF-8 before hashing.   All passwords containing non-English characters will be aliased to English character passwords.

I wrote a short 100-line C program that implements the above and demonstrates its reversibility.  The program takes a 20-character base64 obfuscation key followed by the password.  It hashes the password and prints the hash and the backed-out password from the hash to stdout.  It can be found at https://github.com/kmag/bad_password_hash


答:
risks for SQL injection everywhere

That's your chance. Exploit this and show your boss, how easy it is for any stranger to read the whole database, including your boss's password. Then ask him, on how many web sites he personally uses the same password. After he answered this, it's time to explain, what salted hashes in your web app can do for his PayPal account.

Especially given this cheesy software, where locating (let alone fixing) all the security holes will take a long time, a hashed irreversible pwd gives a big amount of security NOW, today.

BTW, could the SQL injection issues also be used to overwrite stored passwords? I'm just asking ...

Title: Storing web app passwords so that they can be retrieved

Body:
Short version

My boss wants me to store user passwords for an ASP.NET Web Forms web app we're developing in clear text, so that a user with admin rights can click a button and get back the current passwords for the accounts she controls.

I don't want to do that, because I deeply care about the security and privacy of users of a web app I am involved with in whatever way.

What would be a good way to store the passwords in an encrypted form, that can still however be decrypted?

I can't count on users having an email address, so sending the user a link to reset the password is not an option.

Read the following for more context.

Some context

This app was written by individuals who have little clue as to how software should be written. Lots of duplicated code, risks for SQL injection everywhere, no unit tests whatsoever, one new connection gets instantiated and opened for each and every query... name a bad practice, you'll find it in this codebase.

The passwords are currently stored as a simple MD5 of the original string, which is weak and horrible and everything, but still a tiny bit better than clear text.

I just finished implementing a feature request where the admin I was talking about can click a button and have an account automatically created for each employee she manages, with a random password.
I cringe while writing this, but one of the requirements was to export the credentials in an Excel spreadsheet. Which I did.

This is bad in and of itself, but then my boss said "What if the user loses the spreadsheet? Users are dumb, you know. There needs to be a way to get the passwords back."

Bang.

Getting him to listen to people who know what they're talking about is not an option, sadly.

The obvious suggestion would be "GTFO", I know, but rest assured that it's something I'll do as soon as I possibly can.

Meanwhile, I need to cheat and pretend I store passwords in clear text, while I do things in the best way possible to protect my users' passwords.

EDIT

For some reason people answering are assuming I'm a girl so, just for the record, I would like to clarify that I'm a guy. Not that it should make any difference, but hey ;)


问:
What really is the "business logic"?
I'm working with web development since 2009, when I started with PHP. When I moved to ASP.NET, I've heard a lot about DDD and OOAD where a lot of focus is given to this "business logic" and "business rules". The point is that all the apps I've developed until now were all about CRUD operations and I've never seen these things in practice.

I simply can't imagine what those things can really be in practice. So, what really is this business logic and how does this fit into an app? I know these are implemented as methods in domain models, but what could those methods possibly be, and where in the application they could possibly be used?

答:
CRUD is simply the Create, Read, Update, Delete that an application does.

To an extent, a bug tracker is a CRUD app too.  Create bugs, Read (display) the bugs, Update the bugs, and maybe, delete them.

However, there is more to a bug tracker than just CRUD.

A developer isn't allowed to mark the bug verified or closed - thats part of QA's job.  And so some code is in there to make sure that someone who lacks the role of QA can't mark a bug as closed or verified.

No one but a project manager can actually delete a bug.

In order for a bug to be marked as "test me", there must be at least one commit of code against the bug.

Only a bug that is in the 'closed' state may be moved to the 'reopen' state

The developer assigned to the bug cannot move it from 'code review' to 'code review complete'

QA and Developers can only see bugs on projects they are assigned to.

The code that implements the above is the business logic of the application.

The restriction of workflows, or who can do the various operations in CRUD.  These are what separates one CRUD app from another.  They are the parts where you need to get the business to actually say how the application works.  How logical it is... well, thats best discussed over a beer out of the earshot of the project manager.  But thats what business logic is.

Sure, its possible to write a 'pure' CRUD app where there are no roles, everything can be modified and viewed - but these are the exception rather than the rule.

The business logic is the logic that you are writing into your program to handle the business rules that you are given.

When you start getting into business rules, this tends to be be at a higher level than crud itself or business logic.  This tends to be the things you get from a business analyst who is working with the business.

Consider in this example, a program that determines how to handle the return of an item at a returns desk in a store.

If the receipt is equal to or more than 90 days old, only in store credit may be given

If the receipt is less than 90 days old, credit the tender that the receipt was used to purchase with (credit goes back on the credit card, cash goes back to cash, in store credit goes to in store credit)... unless it was a check, in which case use cash.

Those are some business rules.  They don't speak to the CRUD part of the application.

When working with business rules, you may often find these written in a rules engine (for example, Windows Workflow Foundation Rules Engine) instead of writing the raw code in your system.

Realize that the logic / rules distinction is one of terminology and can be argued all night long (best over a beer again).  Though this isn't an uncommon distinction, though the two can blend into each other.

Title: What really is the "business logic"?


答:
CRUD is an acronym that stands for Create, Read, Update and Delete.  Those are the four basic operations that you can perform on a database tuple.  But there's always more to business applications than creating, reading, updating and deleting database records.

Let's start with some basic definitions, and then look at a couple of examples and see how those definitions map to the examples, and how they map to actual software.

Business logic or domain logic is that part of the program which encodes the real-world business rules that determine how data can be created, stored, and changed.  It prescribes how business objects interact with one another, and enforces the routes and the methods by which business objects are accessed and updated.

Business Rules describe the operations, definitions and constraints that apply to an organization.  The operations collectively form a process; every business uses these processes to form systems that get things done.

Now, let's work with some examples.

Transferring money from one checking account to another

First, what are the things that you need to know (input)?

The identity of the person making the transfer

The amount of money to be transferred

The source checking account number

The target checking account number

What are some of the "business rules" that must be applied?

The person making the request must have the authority to do so.

The transaction must be atomic.

The transaction may have reporting requirements to the government, if it is over a certain amount

By "atomic," I mean that the transaction must completely succeed or it must completely fail.  You can't have account transactions where money is taken out of one account without arriving in the other (money disappears), or money is deposited into an account, but not debited from another account (money magically appears from nowhere).

Ordering something from Amazon.

What do you need to know?

The identity of the person ordering

Shipping information

Billing information

Method of Payment

Amount and quantity of each item to ship

How to ship (overnight, slow boat or super saver)

State Tax Rate

What happens after the order is placed?

Items are pulled from stock

On hand quantities are debited

Items are packaged for shipment

Out of stock items are backordered

Items that drop below minimum quantities are ordered

One shipment or two?

An invoice/shipping list is printed, and placed with the order

..etc.

Title: What really is the "business logic"?

Body:
I'm working with web development since 2009, when I started with PHP. When I moved to ASP.NET, I've heard a lot about DDD and OOAD where a lot of focus is given to this "business logic" and "business rules". The point is that all the apps I've developed until now were all about CRUD operations and I've never seen these things in practice.

I simply can't imagine what those things can really be in practice. So, what really is this business logic and how does this fit into an app? I know these are implemented as methods in domain models, but what could those methods possibly be, and where in the application they could possibly be used?


问:
Why is CPU cache memory so fast?
What makes CPU cache memory so much faster than main memory? I can see some benefit in a tiered cache system. It makes sense that a smaller cache is faster to search. But there must be more to it.</p>

答:
In the case of a CPU cache, it is faster because it's on the same die as the processor.  In other words, the requested data doesn't have to be bussed over to the processor; it's already there.

In the case of the cache on a hard drive, it's faster because it's in solid state memory, and not still on the rotating platters.

In the case of the cache on a web site, it's faster because the data has already been retrieved from the database (which, in some cases, could be located anywhere in the world).

So it's about locality, mostly.  Cache eliminates the data transfer step.

Locality is a fancy way of saying data that is "close together," either in time or space. Caching with a smaller, faster (but generally more expensive) memory works because typically a relatively small amount of the overall data is the data that is being accessed the most often.

Further Reading

Cache (Computing) on Wikipedia

Title: Why is CPU cache memory so fast?


答: The "business logic" of a program or application is the part of the code that actually does things with input (from the user, the operating system, and etc).  The "business rules" of an application is usually the defined parameters of the program itself (such as how to handle input).  At least, this is how I have heard it referred to from many people.  They are pretty much similar terms to describe parts of the code.</p>

Title: What really is the "business logic"?


答:
It is faster because both it is closer and because it is SRAM not DRAM.

SRAM is and can be considerably faster than DRAM the values are kept statically (the S in SRAM) so they don't have to be refreshed which takes away cycles.  DRAM is dynamic, like tiny rechargeable batteries, you have to regularly recharge the ones so they don't drain away and become zeros. This steals cycle time in addition to how you have to access the bits, etc.

Being on the same die as or nearer the processor reduces the round trip, both L1 and L2 are faster than DRAM from an access perspective.

SRAM is faster to access than DRAM taken apples to apples, and the caches are usually on chip or closer or on faster busses than the DRAM making the access time faster as well.

Title: Why is CPU cache memory so fast?

Body: What makes CPU cache memory so much faster than main memory? I can see some benefit in a tiered cache system. It makes sense that a smaller cache is faster to search. But there must be more to it.</p>


问:
Is the flyweight pattern a good security choice for managing permissions?
I'm designing a system, and it needs future expandability for the use of a permission system of some kind. I'm wondering if the flyweight pattern would be a good choice to implement this. I'm not responsible for the implementation right now, as it is just a prototype, and we're not prototyping any parts that need the right system. However, because of the demand for future extensibility to parts that need permission management the interface needs to be solid. This means that in the end it will be a thought experiment, rather than a real part of what I have to work on. However, I do need to be able to explain and justify my design in this area of the application.

In favour of using the  are that you can define permissions by having them symbolized through a token class, as represented in the flyweight pattern. If you're dealing with hundreds of users, this would somewhat simplify the handling and issuing of the rights a user holds, and the required rights a user needs for an action within the system; as well as the memory usage of the rights assigned to all the users.
In the system I have in mind, a factory method of some kind will assign the rights needed at construction time.

As I'm not really experienced with designing with security in mind, I'm having a paranoid line of thought of which I can't determine if it's justified, security wise. A shared pointer could be hijacked by 'evil intruders' to gain rights they should not be getting. This is the major argument against the use of a flyweight that keeps bugging me, Even though the 'how' is undefined, and I wouldn't know how someone would get it done. (no experience in the security mindset, or it's workings. However, I'm not really looking for a lecture in security beyond the secure use of patterns, unless motivated and clearly related to the question)

Q: Is the flyweight pattern a suitable pattern to manage the representation of the rights of a user (or other some 'hand out' type of data) in the design of a software system that needs to be secure by design? Does the use of flyweight objects as representation of permissions pose more of a security risk than other patterns (I could also use a decorator chain for it, even though that would take up more memory) when dealing with permissions?

答:
If you're trying to design the interface, why are you worrying about the implementation details?  Even on the level of making an implementation, I think worrying about whether to use flyweight is premature.  Flyweight is a memory-space optimization, and if you don't know how much space you're using to start with, how do you know it will save you space?

You don't mention what kinds of things you'll be tracking with the permissions, so I'll assume that it's about the same amount as unix-style read/write/execute bits for user, group, and other.  That's a total of 9 bits; depending on how you slice it, it will fit in 2 or 3 bytes.  Each flyweight would need a pointer, probably in the range 32-64 bits, or 4 to 8 bytes.  So, even if you didn't need to allocate any more space for the permission objects (and you would), you're probably increasing memory requirements.

Of course, that might not be true if your permissions objects are large enough, but in that case, you'd still get nothing from flyweight unless there was a significant amount of duplication in your large objects.  Do you know that you would get a lot of duplication among your objects and that they'd be relatively large?  Probably not, if you're still figuring out the interface.

I can't really tell you about security, but it seems to me that if anyone has penetrated your system to the point that they can overwrite an arbitrary pointer, they already have control over your program.


问:
Question/Answer for multiple Users - How should I design it?
I'm wondering about a good way to deal with a Question/Answer - Model for multiple Users.
My goal is to have an efficient and readable model where all the results of my users are stored. Every user has the same questions/answers!

At the moment I have three classes, Question,Answer and User.

A user has a Set of Questions.
A question has a Set of Answers and an extra field selected_value which is the answer the user clicked.

Every user has a copy of the same set of questions. Therefore I can easily see what a user has clicked.

This is an unnecessary overload because I need to store the questions/answers more than once.

But the good thing about this approach is the availability of my questions/answers in my user-model as I need to see what every user clicked. It's also easy to extract this information (e.g. via xml) doing just a loop around every user and his questions.

But what kind of approach would you recommend to use? Should I create a model "result" inside of my User-Model where I simply store a list of pairs like "QuestionId, AnswerId"? Is there any more accepted way to do so?

答:
When you design a DB you may want to keep it normalized I.e. stay out of duplicates so that update queries will run faster and in a safer way. This is not the only approach as you might want to de-normalize your tables so that read queries will run faster (more suitable for BI). The point is that there's no right or wrong- both are fine depending on your needs.

Regarding your case- if the quantities we are talking about here are not large, and performance is not an issue, I would go with storing only a representation of the selected answer in your user object (maybe an id or an answer object). It will make things easier and simpler. Things you should consider are CRUD operations and their frequency- how frequently do you change the text of an answer? A question? How frequently does the selected answer changes if ever? And so on..

One more thing- keeping your domain objects design synchronized with the actual db design  is not a must so you may have one normalized and the other de-normalized.


问:
What are the valid test cases for method calls within if-else condition
I have a discount service that gets called if certain conditions are met. I need to write test cases to check if the discount service is called. My doubt is checking if the discount service is NOT called for type 4 and 5 is a valid test case scenario.  </p>

```<code>public void ApplyDiscount(int typeId, double amount)
{

if(typeId == 1)
{
  //call discount service
}

else if(typeId == 2)
{
  //call discount service
}

else if(typeId == 4)
{
   //do other stuff
}
else if(typeId == 5)
{
   //do some other stuff
}

}
</code>```

答:
All good unit test suites do not just test the sunshine cases, but also test to see what happens if something is done that is supposed to be disallowed.

You'll have to make an exhaustive list of cases that your unit has to be able to handle.
For every one of your casetypes in the snippet you posted, you'll need to think of at least one case that has to evoke the error handling code in your code for every error handled by your code. For the sunshine cases it matters how much your 'input range' is. You'll have to test for every class of input in the range you're going to handle.

After you've done that, you have to determine which ones are worth working out for complete testing.

Your not calling 4 or 5 should definitely be one of several test cases.

BTW, I agree with @MichaelT and I'd suggest using a strategy pattern [1] to get a better design going. This would also make it easier to build a proper test suite for your application, as all behaviours are in their own classes.

[1]http://en.wikipedia.org/wiki/Strategy_pattern


答:
One thing that should be mentioned explicitly is the impact of the speed of light. In this video Grace Hopper shows a piece of wire about a foot long, which is how far an electrical signal can travel in one nanosecond*. If a CPU is operating at 3GHz, then that implies a distance of 4" per clock cycle. This is a hard physical limit on memory access speeds. This is a large part of why being close to CPU (as L1 cache is), allows memory to be faster.

EDIT *actually how far light can travel in a vacuum, the distance through copper/silicon is less.

Title: Why is CPU cache memory so fast?


问:
Familiarize with unknown source code
I have to continue feature development, issue fixing of a halfway completed code base.

There is a no documentation, all developers had left the company.

The technology stack is somewhat familiar to me (Spring, Hibernate, Web Services (Rest, SOAP), MySQL).

Also there are non descriptive JIRA items that the team had worked over 3 years. Seems code has implemented in consistent way like layering, ant file per project, DAO classes. I would like to get feedback from all our experts.

What should be the approach to get familiar with the project?

Do you recommend to use profilers, bug track tools like Sonar to get some hints?

Any other approach I can try out?

答:
In short: read the book.

Michael Feathers wrote an excellent book for people just like you, who are tasked with maintaining or extending legacy systems. There's a lot of little gems in there, but his main approach is simply based on his definition of legacy code. I may be paraphrasing here, but the gist is that

Legacy code is code without tests.

Hence, his proposed approach is to add tests to the existing code and a lot of the book deals with how to do that in more or less complicated situations.

Interestingly enough, you did not even mention the existence of any test code. If you have some, it is a good starting point to see how the individual pieces work and depending on the presence of integration tests, how they fit together.

Title: Familiarize with unknown source code


答:
Business logic basically consists of 2 broad categories: validation and flow.  Business logic says that qty 1 must be greater than or equal to qty 2 -- for example, number of items to purchase must be less than or equal to number of items in stock.

In one application, the business folks will say this is a business rule, and so you write code to enforce this business logic(validation).  Another application will say that if the number of items ordered is greater than the numbers of items in stock, to accept the order and then to place your own order for the difference plus 20%, and so you will write this business logic(flow).

CRUD is simply getting data in and out storage and changing it.  Business logic determines what you do with that data and what transformations you are allowed to make to it.  Is your customer born in the future, under 5, from a certain geographical area (discounts for locals/visitors).  CRUD is simple, knowing that you can get a child tax credit only if the child lived with you for more than half of the time it was alive in the calendar year NOT just more than 6 months, is more complex.

Title: What really is the "business logic"?


问:
PHP Code base design: Single "queries.php" file, or spread queries across different php files/classes?
When I create PHP projects, is it better to put all database (e.g. MySql) queries in a single file (i.e. "queries.php")? Or is it better to place the respective queries in any "model" classes (i.e. User.php) that I may be creating? Is it bad practice to put database queries anywhere in any PHP file?

In the queries.php I would be placing functions for calling the queries.

答:
Usually, it boils down to choice, when I work with MVC, I tend to keep separate files for all my database objects other than that  I've all my database objects/model within a single file.

MVC favours the idea of separation,separate models, views and controllers from each other. Over the years i've experienced a growing pattern where individual models are kept in separate files. You can check Ext Js 4 mvc application for reference.

I've adopted this same pattern for most of my MVC based application, locating files for editing have never been easier than this and I know where exactly to find which file.

New Programmers were also able to work with the codebase, they just knew where to find what.

When not using MVC, I tend to have all my models within a single file to avoid the overhead of importing/including these files when needed.

For a bigger codebase, sticking with MVC and keeping separate files will help when it comes to maintenance and for a smaller codebase, a single file will suffice.


问:
When is it beneficial to not use utf-8?
When is it beneficial to use encodings other than UTF-8? Aside from dealing with pre-unicode documents, that is. And more importantly, why isn't UTF-8 the default in most languages? That is, why do I often need to explicitly set it?</p>

答:
For an external encoding (i.e., an encoding of things not inside your program) it is very hard to beat UTF-8; it supports every character your users might ever reasonably need and there's lots of support in many OSes and tools. (The one place that counts as an exception to this is in file names, where you must use the platform's conventions if you want any kind of interoperability at all. Fortunately, many platforms now use UTF-8 for this so the warning is a moot point there.)

For an internal encoding, things are more complex. The issue is that a character in UTF-8 is not a constant number of bytes, which makes all sorts of operations rather more complex than you might hope. In particular, indexing into the string by character (a very common operation when doing string processing!) changes from an O(1) operation into an O(N) operation, and that can be a very significant performance issue. There are a number of possible workarounds, such as using a rope data-structure or converting the string into a fixed-width character format (typically ASCII, ISO 8859-1, UTF-16 or UTF-32, depending on the maximum Unicode value of the characters in the string). The problems that plague such formats (limited character support and/or endian-ness problems) don't actually apply here because you can only apply a transformation where it is meaningful and you are only using it as an internal encoding.

Don't think that you can get away with storing that internal encoding to disk or giving it to another program. It might be “convenient” but it's a problem waiting to happen; send/store the data as UTF-8.

And don't forget that there's a lot of legacy data out there, far too much to dismiss. Of particular concern are various East Asian languages which have complex encodings that are potentially quite a bit shorter than UTF-8, so resulting in less pressure to convert, but there are many other issues lurking even in Western systems. (I don't want to know what is happening in major bank databases…)

Title: When is it beneficial to not use utf-8?


问:
Is it safe to just use MySQLi?
I have developed an open source PHP application and currently it uses both the MySQLi or MySQL extension for backwards compatibility. I'm wondering about switching it over to only be compatible with MySQLi since PHP now no longer supports the MySQL. Another reason I'd like to get away from supporting both MySQL and MySQLi is that I'm basically using MySQLi the same way I do as with the old MySQL extension. Can anyone explain to me if this is a good or bad idea?</p>

答:
In terms of performance, mysqli is better, if your intended users are solely mysql based,
then use mysqli else you can try PDO which will give you the flexibility of connecting to other databases with minimal changes.

I think PDO is slightly slower due to that fact that its more generic compared to mysqli or oci, but that is nothing to worry about.

You can create 2 scripts, one with PDO, the other with Mysqli and you apache ab to benchmark.
With my test Mysqli was slightly faster in terms of request processed as compared to PDO but I must admit was negligible.

Title: Is it safe to just use MySQLi?


问:
Should I keep using the normal mysql_query or switch to PDO interface in php?
I'm building a big website, and using the normal old mysql_query method for transactions and communications with the database, and everything i going fine, including security. I'm a little bit confused, should I switch to the new PDO interface? cause I learnt that's safer, or keep using the old mysql_query() and mysql_fetch_assoc() methods?

I'm very close to completing the website, and to switch to the PDO interface will cost me time, to start updating my codes.

I'm a little confused, which should I use and what are the pros and cons?

答:
You can still work with your code provided you don't plan upgrading to the version(s) of php that will take mysql out.
Which means you'll loose most of the improvements in these new version(s).

Switching from mysql to mysqli will be easier as compared to pdo, mysqli have similar interface/functions to mysql.

If you intend to connect to only mysql databases, then i would advise you to use mysqli, pdo is more generic and allows you to connect to other databases with minimal changes, but I think there will be a performance loss as compared with mysqli.
I must admit though that its unnoticeable.


答:
One of the philosophies I studied was the obtain-maximum-throughput-in-minimum- hardware movement when we talk about any cache based memory, be it CPU cache, buffer cache or memory cache for that purpose. The basic motive is achieved when there is the least or no hardware movement for retrieving/reading/writing data and the operation is completed faster.

The data transfers from disk -> main memory (RAM)(temporary storage) -> CPU cache (smaller temporary storage near the CPU for frequently accessed data) -> CPU (processing).

The CPU cache is a smaller, faster memory space which stores copies of the data from the most recently used main memory locations.

The buffer cache is a main memory area which stores copies of the data from the most recently used disk locations.

The browser cache is directory or similar space which stores copies of the data from the most recently visited websites by users.

Reference: How Computer Memory Works

Title: Why is CPU cache memory so fast?


问:
Contradiction of layered design and global data access for analytics reporting
While developing an application (mobile app for Android), our team always strives to use best development practices such as interfaces, layering and separation of concerns.

When it comes to reporting analytics events from our app, the requirements sometimes force us to send events with data that is stored and managed by multiple different app "components".

Some of this data is not directly available at the component/layer that does the reporting, nor at any central location in the application.

To me, this seems like it contradicts all the efforts of architecture and design that were made during the development of the application.

My question is:

What is the correct way to deal with this issue?

Is the problem in the requirements we received, or is it a common issue that a layered/modular application sometimes needs to make things "global" ? if so, what is the way to solve this issue while still reaping the benefits of development best practices?

答:
One of the principles of layered structure is that every layer call only the layer below and receive callbacks. So if the reporting layer does not provide access to this data, it is fair to assume that the data is not accessible from any other layer above.

I don't think adding globals is a good idea. It makes the architecture inconsistent and adds very little (if any) value. I would rather add the missing functionality to the reporting layer. In this case the reporting layer could call the component(s) managing the data and forward it to the original caller.

There might be deeper considerations if the data itself is distributed among different components. But anyway, having a single interface for all the data will make the structure clear and easier to maintain.


问:
Why aren't databases integrated as a language feature?
Are there any programming languages that have a built-in database as a first-class language feature rather than connecting to an external SQL (or other) database? What would be the drawbacks and benefits to such a feature? What would such a feature look like and how would it change the way we program?</p>

答:
they are; such languages are called 4GLs. DataFlex is my favorite, though I don't use it any more.

Caveat: I helped develop the object-oriented version of DataFlex, v3.0


答:
The answer is that UTF-8 is by far the best general-purpose data interchange encoding, and is almost mandatory if you are using any of the other protocols that build on it (mail, XML, HTML, etc).

However, UTF-8 is a multi-byte encoding and relatively new, so there are lots of situations where it is a poor choice. Here are a few.

Internal encoding in Windows/C/C++/C#/Java/ObjectiveC. These environments do not internally support UTF-8 (or any multibyte encoding). Strings are respectively ANSI/UCS-2/UTF-16.

Legacy code, especially C/C++. Strings are typically ANSI/ISO/UTF-16/UTF-32.

Legacy data. There are vast mountains of textual data already encoded in some 8 bit format, including various code pages, JIS, etc.

The remaining cases involve the use of text files. They will likely remain an issue as long as plain old text files remain popular. The point is that text files do not encode their encoding, so the reader and writer have to make assumptions. Yes, there is something called a Byte Order Mark but it is neither required or recommended for UTF-8 files so any file containing 8 bit characters is of uncertain encoding.

Here are some examples using text files with little reason to allow or use UTF-8.

Software tools. Things like sed, awk, tr etc may or may not work with UTF-8. It's often easier not to try.

Compilers. Most computer languages are defined in terms of 7 bit ASCII and read plain text files from disk, with special tricks for extended characters.

Log files, simple protocols, embedded systems. Sometimes 7/8 bit ASCII is just the easiest.

Not always needed. Most European languages can be encoded in code page 850 or 1252, with possible savings in space and coded logic.

I confidently expect that many of these will go away over time, but they are real reasons to avoid UTF-8 in certain situations until then.

Title: When is it beneficial to not use utf-8?

Body: When is it beneficial to use encodings other than UTF-8? Aside from dealing with pre-unicode documents, that is. And more importantly, why isn't UTF-8 the default in most languages? That is, why do I often need to explicitly set it?</p>


问:
Using a progress dialog and multi threading
My .NET Windows desktop application creates an HTML report, and has 3 main phases. It may create multiple reports.

I show a progress bar so the user knows (estimates) how long it will take (as well as reassure the system didn't crash by an updating GUI). So, if I needed to generate 3 reports, there would be a total of 9 phases (3 phases * 3 reports).

The issue I now have, is the process is taking too long. As such, I need to use threads so I can start on phase 1, then open a new thread which completes phase 2 and 3. Whilst phase 2 and 3 are in progress, the next item on the list begins with phase 1 and the process continues. I'm hoping this makes sense.

So I'm now thinking what to do with the progress bar since multiple phases will be being run at once. At the moment, the only logical thing I can think of is

```<code>Report 1. Start phase 1. New thread -> Phase 2 and 3

Check to see if Report 2 is last report. It isn't, so, during Report 2 phase 2, start Report 2 phase 1. New thread -> Phase 2 and 3

Check to see if Report 3 is last report. It is. So, during report 2 phase 2, start Report 3 phase 1, then continue on the same thread with phase 2 and 3
</code>```

The above will mean I update the Progress Dialog during phase 2 and 3 of the last Report (and I guess I need to add some checks to ensure the other phases are actually finished).

I can't imagine I'm doing any thing new or different to what has been before and as such, I was wondering if there is already a pattern for dealing with type of situation?

答:
I would try to organize it into tasks, which is to say a job that is one-to-one with your phases.  In other words if you have 3 reports with 3 phases each, you will have 3*3 or 9 tasks.

It would seem that some of these tasks can be run in parallel while others can't, so I would allow a task object to wrap another task, with the intended meaning that once the outer task is finished, it will simply call the inner task in the same thread.

Once you've done this, there really should be only 6 such tasks (3 of which execute phase 2 and wrap task for phase 3).  At this point you can safely execute all 6 tasks using a thread pool of some sort with a minimum and maximum thread count.

At this point, in order to update the progress bar, I would add a recursive method to task object which asks how many tasks are to be performed, and it would be 1 + recursive call to inner task.  Given a list of tasks, you should be able to use this method to determine the amount of progress steps.

From there, when you launch each task, you should optionally pass a progress bar control which updates it once the task is finished and then passes the same instance to inner tasks if there are any.

Since it is using threading, the progress bar may update a little sporadically, but such is the nature of threads.  I hope that points you to the right direction.