问:
In plain English, what is an object model?
I read about objects models on Wikipedia, but it is too abstract to really make much sense to me. Can someone explain what an object model is in plain English?</p>

答:
For our purposes an Object is a thing or concept and a Model is a representation of the parts you need to refer to in your design/code.

An Interface is a description of what of what we need to know/do in our design/code.

For example: a Vehicle object model might be an interface which requires:-

Properties to represent the state of the object (capacity, speed, direction)

Methods which affect those properties (load/unload, go faster/slower, turn)

Exceptions that represent errors which may occur (collision, breakdown, no fuel)

That interface is then implemented as a class and the code might differ for a Hovercraft compared to a Car but for the code which needs to operate the vehicle, it should not need to know about those things.


问:
Should I spend time preventing piracy of my app?
The title says it all, the more I do research about piracy and the tools used to crack an app the more I think it is just wasted time.

My biggest threat is that my app is being cracked and uploaded again within minutes after I released it. But I'm not sure how harmful it will be to my revenue, if there even will be revenue. Maybe someone can come up with some experience, it's my first app which I'm going to publish and I have no experience with that. My app is going to be free with ads. I think this is another line of defense because in my opinion, the main focus is on paid Apps due they are not available in a lot of countries..

My current approach is that I will just use proguard not really to make it harder to crack (more likely understand the code), because you don't even need to understand the code if you just simply resign it and upload the same application to the playstore, you will just need to change the package name. My main point of using proguard is just to shrink the app.

Is this a "good" approach?

答:
Conclusion

My conclusion, to don't get in conflict with Q&A Format, after all of this great answeres is not to invest a lot of time in making it as hard as possible to crack my app. For this app, I will just use proguard because of the shrink-effect and because it is more difficult to understand the code if someone wants to modify it...

I rather spend more time in SEO/implementing more features like Steven pointed out and after publishing i will try to give a better support to my users than the pirates will do! ;) I think that is going to make the difference and is one of the best ways to fight them.

Anything else which will happen is additional experience and will or will not change how i publish my apps in the future. Thank you!

ContentLicense: CC BY-SA 3.0


答:
There are two kinds of object models:

for a programming language, it is the characteristics of objects in that language.  Three examples of those characteristics, there are others:

is there a notion of multiple inheritance or not (if present, there are more questions to answer, is it limited to something like interface or more general like in C++, what happens in case of apparent ambiguity: error like in C++ or a resolution algorithm like in Common Lisp, which resolution algorithm is also important)

are method's validity checked statically (how? with an inheritance mechanism or something else) or dynamically (what happens if there is no method of that name? an error? is forwarding possible?)

are those characteristic ad hoc or do they have a theoretical foundation?  Which? (Cardelli's Object Calculus?  Something else?)

The object model is somewhat independent of the programming language.  Languages targeting Microsoft's CLR tend to have a more similar object models than others as the classes are designed with a model in mind.  You may even have languages with several object models. C++/CLI has two, the C++ one and the CLR one.  Objective C++ is another language with two object models: the C++ one and the Objective C one (which is nearer to the one of SmallTalk)

a (more or less standardized) set of classes representing something (documents, telescope, ...).  I won't write more about that, it is just a modelization based on classes and objects.

Title: In plain English, what is an object model?

Body: I read about objects models on Wikipedia, but it is too abstract to really make much sense to me. Can someone explain what an object model is in plain English?</p>


问:
Is it possible to save and load a decorated object
I am wondering if there is an easy way to save and load a decorated object in c++ as i have never done file handling in C++ before.

Currently the only object type I need to save is objects that stores values for health, damage etc. and each of these objects has at least 1 decorator. I know i could make an save function for each of the classes however I'm unsure how I would load the object.

Edit: The way that i have set up the decorator is like so. new Champion(new Monster()) where the Champion is the decorator.

答:
Writing objects of any kind to a file (whether decorators are involved or not) requires serializing those objects somehow, and loading them later requires deserializing them. Most of the time, (de)serializing objects means converting them to and from strings.

You appear to be asking how to serialize objects. For most simple objects, this is very straightforward and you can pretty much do whatever you want. For instance, you might choose to serialize a std::tuple with 0, 1 and 2 as the string "<0,1,2>". For some objects, like TCP sockets, serialization is inherently impossible, though you may be able to serialize some related information like what IP addresses they were connected to.

In principle, decorators shouldn't make this more difficult. At most they might increase the number of (de)serialization methods you need to implement. We may need more information about your objects to figure out why you're stuck.

If you're asking for common approaches to serializing more complex objects, or large collections of objects, I would suggest looking at the JSON and XML formats. There are plenty of libraries for generating and parsing them.


问:
How do you respond to a request for 'emergency contact information' for when you are on vacation?
I want to go on vacation and not think about work at all but they want me to provide them a contact number in the event of an emergency (server goes down, web service malfunctions, etc). I am afraid that it will be abused (they will contact me before trying everything for example) but I also think that if I am on vacation I should not be bothered even if there is an outage. Does anyone have experience with situations like this? What's the tactful approach? Any creative solutions?</p>

答: Give them a cellphone number, but tell them you might not be available over extended periods, because you don't know how good the coverage is at the place you are going to. Then switch it off whenever you don't want to be disturbed, but in case they called, call back several hours later, or the next day, or whenever you feel like it.</p>

ContentLicense: CC BY-SA 2.5


问:
Where would be better to handle an exception?
Imagine I have the following DAO method:

```<code>public Employee getEmployeeById(Integer id){
    NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());
    String sql = "SELECT * FROM users WHERE id = :userId";
    Map<String, Object> parameterMap = new HashMap<String, Object>();
    parameterMap.put("userId", id);
    return jdbcTemplate.queryForObject(sql, parameterMap, new EmployeeRowMapper());// Throws
                                                               //EmptyResultDataAccessException
}
</code>```

The DAO method is used by the controller method:

```<code>public class EmployeeListController{

    @Resource(name = "employeeDAO")
    private EmployeeDAO employeeDAO;

    @RequestMapping(value="/{empId}", method=RequestMethod.GET)
    public String getEmployeeById(@PathVariable String empId, Model model){
        model.addAttribute("employee", employeeDAO.getEmployeeById(Integer.valueOf(empId)));
        return "employeesList";
    }
}
</code>```

Where would be better to handle the Exception? In the controller's method or the DAO's method? I think, that in the controller it would be, because otherwise we should return the Object with empty properties, which is not good. Is it correct?

答:
The answer to your question "where would it be more appropriate to handle the exception" will depend on what your intended semantics are for the getEmployeeByID method.

In the .NET Framework, methods that semantically must never throw an exception are prefixed with Try, as in Double.TryParse().  Usually, you pass a string to parse and a ref variable, and the function returns a boolean indicating success or failure.

In other words, if you handle the exception in the getEmployeeByID method, you must also return some status to the caller indicating whether the operation succeeded or not.

Since I don't see any evidence that your getEmployeeByID method returns something indicating success or failure, the semantics of your method dictate allowing the exception to pass to the caller. Ergo, you would handle the exception in the EmployeeListController class.

Further Reading

Does Java have an int.TryParse that doesn't throw an exception for bad data?


问:
How do you show the exception handler in a class diagram?
I have one exception handler class. I want to show this class in the uml -- class diagram. But, I do not know how to represent relationship between class <X> and exception handler class. How can I represent relationship between class in class diagram?

答:
One take on it is that the exception handlers are not a part of the problem domain, but rather a part of the non-functional requirements. That is, the architecture of the system. In that sense, they don't really belong in a class diagram of a domain model any more than a Logger class belongs there. (Or a BeanFactory, or garbage collector, etc.)

Class diagrams display information about classes in the model as well as relationships between them. But an exception handler has a relationship with many or all of the classes -- in that the control flow might suddenly halt and go to the exception handler instead. Worse still, the relationship between the exception handler and the domain classes is managed by the framework of the application, so there isn't a direct relationship to the domain classes (by design).

If your class diagram is for the framework classes, then it's easy. There will most likely be some sort of controller with a "has a" relationship to the exception handler. But if the class diagram is for the domain model, there are lots of bits from the background I wouldn't put in the class diagram.


问:
run time of nested while loop inside for loop
I'm here to clarify my understanding of the run times of these 2 algorithms:

```<code>Algorithm1(n):
For i = 1 to n
    j = 1
    while i+j < n
        j = j+1
</code>```

and

```<code>Algorithm2(n):
For i = 1 to n
    j = 1
    while i*j < n
        j = j+1
</code>```

The first algorithm I believe is O(n) because the inner loop is bounded by n, and the while condition is incremented linearly as i is incremented by the outer for loop.  Otherwise, I would say O(n^2) if I'm wrong.

The second algorithm I believe is O(log(n^2)) because, as i increases, the amount of iterations will decrease in the while loop which is controlled by the outer for loop.

答:
Your first algorithm is O(n^2), as the outer loop executes n times, and on average the inner loop executes n/2 times; we discard the constant factor as we only care about asymptotic behavior.

Your second algorithm is I believe O(n log n): the outer loop again executes n times, so there must be a factor of n in the answer, and I believe the inner loop executes log n times on average.

Note that your suggested answer of O(log (n^2)) is not a valid answer in any case: log (n^2) = 2 log n, so O(log (n^2)) should be simplified to O(log n).


答: I am always willing to give my contact info to people at work.  I trust my coworkers to not call me unless it is a truly important matter.  And if it is a matter of that gravity I am willing to help.  I have even taken time out of vacations to dial into important conference calls.  But of course I had a beer in my hand when I did. :-)</p>

Title: How do you respond to a request for 'emergency contact information' for when you are on vacation?

Body: I want to go on vacation and not think about work at all but they want me to provide them a contact number in the event of an emergency (server goes down, web service malfunctions, etc). I am afraid that it will be abused (they will contact me before trying everything for example) but I also think that if I am on vacation I should not be bothered even if there is an outage. Does anyone have experience with situations like this? What's the tactful approach? Any creative solutions?</p>


问:
Where to put data for tree structure which every node requires?
I have a quad-tree structure where each node has some of its own data, but there is also data which applies to the tree as a whole.

I'll explain my current solution and I would appreciate feedback on whether this is the best solution or whether better solutions exist.

I have two classes:

One for the node

One for the tree

The tree class contains a root node pointer and the data relevant for that tree. The nodes in the tree need to access that data, so one option would be to have the node class include a data member which is a pointer to the tree object, and then invoke its accessor methods to get at the data.

This would increase the side of each node, though, so I decided to have a single static pointer for the node class. When a tree object wants to do something to all the nodes (most of the algorithms are recursive beginning at the root), it first sets the static pointer to point to its tree data (which I put in a struct) and then invokes the static pointer to point to its data.

Here is some pseudo-code:

```<code>struct TreeData {
    // data relevant to tree as a whole
};

class Tree {
public:
    void algorithm() {
        root.set_data(&data);
        root.algorithm();
    };

private:
    Node root;
    TreeData data;
};

class Root {
public:
    static void set_data(TreeData * data) {
        tree_data = data;
    }

    void algorithm() {
        // code that uses tree_data
    }

private:
    static TreeData * tree_data;
};
</code>```

I wanted to avoid having every node increase in size, but there can be multiple trees instantiated at a time, so it couldn't just be static data for the node class.

So where should I put data for tree structure which every node requires?

答:
Your current solution has a major down side in that it is not thread safe. I would definitely redesign so that you can have multiple tree operations preformed in parallel.

Assuming that nodes are purely internal to the tree structure, and always called via the tree, I would consider simply having their owner tree passed in as a parameter when you call any of their methods that needs access to this data.


问:
find the minimum number of sets
Let's explain my question with example I have some integer sets for example

S1 = {2,3}

S2 = {2, 5}

S3 = {4, 5}

S4 = {4}

S5 = {5}

And I have sample set Ssample with 4 elements {2, 3, 4, 5}.

So now I want to find minimum number of sets to build Ssample. In this case I can use S1 and S3 because S1 contains {2, 3} and S3 contains {4, 5}. Their union is equivalent to Ssample. We can choose sets S1, S4, and S5 but that isn't a sufficient answer so how can find this minimum number of sets?

Isn't it a kind of knapsack problem?

答: It's similar to the knapsack problem in that it is NP-complete. This particular instance is the Set Cover Problem. There are a number of ways to solve this but only by approximation. Integer Linear Programming yields a reasonably fast method of approximation.</p>

Title: find the minimum number of sets


问:
How can Swift be so much faster than Objective-C in these comparisons?
Apple launched its new programming language Swift at WWDC14. In the presentation, they made some performance comparisons between Objective-C and Python. The following is a picture of one of their slides, of a comparison of those three languages performing some complex object sort:

There was an even more incredible graph about a performance comparison using the RC4 encryption algorithm.

Obviously this is a marketing talk, and they didn't go into detail on how this was implemented in each. I leaves me wondering though:

How can a new programming language be so much faster?

Are the Objective-C results caused by a bad compiler or is there something less efficient in Objective-C than Swift?

How would you explain a 40% performance increase? I understand that garbage collection/automated reference control might produce some additional overhead, but this much?

答:
Honestly, unless they release the source to the tests they are using I wouldn't trust anything Apple has to say on the subject.   Remember, this is the company which switched from PPC to Intel based on power concerns when 6 months earlier they were saying that Intel sucked and actually torched the Intel bunny in a commercial.  I would like to see hard irrefutable proof that Swift is faster than ObjC in more categories than just sorting.

Additionally you have to question any stats which are released at WWDC since they have the smell of marketing all over them.

All of that being said I haven't run any tests between swift and ObjC myself, but from what I know swift has it's own LLVM IR extensions and it is possible that more optimization is being done at compile time than in ObjC.

Full Disclosure: I am writing an open source Swift compiler located at https://ind.ie/phoenix/

If anyone would like to help make sure that Swift isn't just available on Apple hardware, let me know and I would be glad to include you.


答:
It is impossible to completely prevent piracy.

You must accept that your code will run on other people's machines. Those people can take your code on their machines and do anything with it, including change and (illegally) redistribute it.

You can leverage your country's legal system if you believe your rights have been infringed upon; e.g., an American citizen can issue a DMCA takedown request against an entity that is distributing his work. However, it will be more difficult to dismantle an international distributed network, such as those composed of torrent links.

Alternatively, you can revise your philosophy on software distribution. Considering it is already possible for your users to do anything with your program, you could accept that reality. Then, embrace that reality, and grant your users the freedom to run, copy, distribute, study, change and improve your software. This is typically accomplished by declaring your program "free software" (and when I say "free," am I speaking in terms of "freedom and liberty," not in terms of "price").

Releasing your program as "free software" has numerous advantages:

Your users will easily be able to modify your program.

If you appreciate their modifications, you can merge them back into the main project, and it will be more valuable as a result.

If I was to modify your program, the first thing I would do would be to remove the advertisements, because I find them quite annoying. You could take this as an indication that your application would be better without advertisements, which would spur you to imagine a better revenue model ("better" both in terms of pleasing your users and profit).

Your users will be free to redistribute your program.

If you want your program to "go viral," removing all legal barriers to virality would be a good thing.

People can already redistribute your program. Either they are "evil," or they are benevolent for sharing things with their neighbors, which is a basic human trait that makes us more successful than species without compassion. Now they can feel good about it, as they should.

Other people will be able to study your work and learn from it.

I learned a tremendous amount about programming from trudging through the source of RPGMaker games, for which the game code is usually free to browse. In fact, I am aware that a whole community of game developers have emerged from sharing and learning things from each others' code, and have grown up and are leading successful careers and delivering high-quality products. You can be happy knowing that your program has benefited more people than just you.

Making your program "proprietary," as you intend to do, gives you the false reassurance that people must first pay you in order to obtain and use your software. You are aware that this is not true, due to piracy.

So consider the converse: What if you offered the software to the customers first, and told them that if they derived value from it, then they would pay you?

If an "honest" person was willing to pay you for your software before he could use it, then (as long as you are providing a high quality product) why should he not be just as willing to pay you after he has enjoyed it? (I paid the author of Chrome's AdBlock plugin, which is free software available gratis, because I derived immense value from it.)

As for a "dishonest" person who would download a modified version of your program from an illegal source, he is certainly not willing to pay up-front. Now you have the opportunity to capture revenue from that person, because the "freeloader" might derive value from your program and then decide to pay you. If pirates pose a considerable "threat" to your program, you might consider turning the tables such that your pirates become potential customers instead.

I recommend the "free software" approach. You could continue to create proprietary software and you would still probably make plenty of money, as many people who produce proprietary software do; though you would have to ignore the "problems," both financial and moral, which exist inevitably and incurably because of the nature of creative works. These "problems" become vehicles for the enhancement of your product when you adopt free software philosophies; you would have an edge over competitors who cannot understand this power.

Title: Should I spend time preventing piracy of my app?

Body:
The title says it all, the more I do research about piracy and the tools used to crack an app the more I think it is just wasted time.

My biggest threat is that my app is being cracked and uploaded again within minutes after I released it. But I'm not sure how harmful it will be to my revenue, if there even will be revenue. Maybe someone can come up with some experience, it's my first app which I'm going to publish and I have no experience with that. My app is going to be free with ads. I think this is another line of defense because in my opinion, the main focus is on paid Apps due they are not available in a lot of countries..

My current approach is that I will just use proguard not really to make it harder to crack (more likely understand the code), because you don't even need to understand the code if you just simply resign it and upload the same application to the playstore, you will just need to change the package name. My main point of using proguard is just to shrink the app.

Is this a "good" approach?


问:
Is there a way to write this fold neater in Haskell?
I have the following small function that uses foldr to find the largest second number of a 2-tuple:

```<code>listMax :: [(Int,Int)] -> Int
listMax = snd . foldr (\(_,freq1) (_,freq2) -> (0,max freq1 freq2)) (0,0)
</code>```

My question pertains to the body of the lambda:

```<code>(0,max freq1 freq2)
</code>```

I had to make it into a tuple with a dummy head so that it matches it's own input for the fold. To me though, it looks ugly and makes it harder to read. Is this the standard way of dealing with this situation, or is there a idiomatic way around this?

答:
As jozefg pointed out, your version is incorrect for negative numbers, as it gives 0.

I would write

```<code>listMax = foldr1 max . map snd
</code>```

The difference between my solution and theirs is the behavior for empty lists. Mine gives an exception, which I think is appropriate, since an empty list has no minimum. Theirs returns minBound.

Body:
As jozefg pointed out, your version is incorrect for negative numbers, as it gives 0.

I would write

listMax = foldr1 max . map snd

The difference between my solution and theirs is the behavior for empty lists. Mine gives an exception, which I think is appropriate, since an empty list has no minimum. Theirs returns minBound.


问:
Algorithm to find the closest summation of elements in a list to a given number
Say I have a list {1,3,7,2,11,8,2} and I want to take x elements from the list and get the value 15.5.

Is there an algorithm that would give me x elements in a list that, when added together, get nearest to this given value?

There is no preferred amount of elements, I just want to get as close to the given as possible.

I plan on implementing this algorithm in Swift (Object Oriented) if that makes any difference.

答:
For a small dataset and a fixed value for the total and the number of elements, I would just do a modified brute force that was based on enumerating all the x number elements and discarding each less optimal solution as you go.  I wouldn't bother to over-optimize it.

If you're talking about a changing data set and repeated variances of x and quantity, then I would start looking for more advanced options.


问:
Efficient algorithm to count number of substrings divisible by 3
Given a string of decimal digits, I have to find the number of all substrings divisible by 3 in the range L to R [both inclusive], where L & R are index[1-based] of the specified string

string length <= 100000

I've tried the Naive approach of iterating over all possible substrings & obtaining the answer, but that is not fast enough, especially for multiple pairs L & R.

Then I tried a DP approach. I can obtain all possible substrings divisible by 3 in the whole string, i.e. I'm unable to code the DP solution that gives result for given range.

DP Solution that I tried (not completely sure about It):

```<code>for(i=0 ; i<n ; i++) {
    for(j=0 ; j<3 ; j++) {
        dp[i][j]=0 ;
    }
    int curr = (input[i]-'0')%3 ;
    dp[i][curr]++ ;
    if(i) {
        for(j=0 ; j<3 ; j++) {
            if(curr % 3 == 0) { dp[i][j] += dp[i-1][j]; }
            if(curr % 3 == 1) { dp[i][j] += dp[i-1][(j+2)%3]; }
            if(curr % 3 == 2) { dp[i][j] += dp[i-1][(j+1)%3]; }
        }
    }
}
long long sum = 0;
for(i=0 ; i<n ; i++) { sum += dp[i][0] ; }
</code>```

Can this solution be modified to give results for given range [L,R] ?

After searching alot, I learnt that range queries problems are solved by Segment Tree, but I'm unsure as how Segment Tree + Lazy Propagation can help in this question.

So what is a performant way to count all substrings divisible by 3 in the range L to R [both inclusive]?

EDIT:

Input: First Line contains the given string. Lines after that contain two integers denoting L and R respectively, where both L and R are index(1-based) of string.

Input:

  301524
  1 2
  4 6
  3 5

Output:

  3
  1
  1

Explanation:

  When L=1 & R=2 we get 3 possible substrings, {3}, {0}, {30} & all these when considered as a decimal number are divisible by 3. Hence the output.

  When L=4 & R=6 we get 6 possible substrings, {5} , {52}, {524}, {2}, {24}, {4} & out of these only {24} is divisible by 3.

Repetitions in substrings like 3333 count multiple times, so for L=1 to R=4 the answer would be 10, since we have four times 3, three times 33, two times 333 and one time 3333 (all divisible by 3).

答:
Cute dynamic programming problem. Here is a Java solution and quick explanation.

The basic question to ask yourself is if I knew subproblem X, I could solve solve problem Y easily.

In this case, problem Y is the number of substrings divisible by 3, the subproblem X is the number of substrings modulo 3 that terminate at the previous character for each possible mod (that is remained 0, 1, and 2).

If you know that at the previous position, there were 2 substrings that terminated there that had a residue of zero, 3 with a residue of one, and 1 with a residue of two, then given the current number and its residue, it is trivial to determine the residues of all the strings that terminate at the current character.

If the current number's residue is one (e.g., the number is 1, 4, or 7), then the substrings terminating on the previous number with a residue of one now have a residue of two, those with a residue of two now have a residue of zero, and those with a residue of zero now have a residue of one plus 1 more for the current digit since you added a new possible substring of length one.

For example, if you had the string 521438 and you knew the number of strings terminating at the 3 for each residue (2, 2, and 1 respectively for residues 0, 1, and 2), and since 8 mod 3 is 2, you know that all those with residue zero now have residue 2, those with residue two now have residue one, and those with residue one now have residue zero, so (2, 1, and 2 repectively), plus you have a new string of residue 2 so you have 2, 1, and 3 now including the current number.

After you process this in linear time, for all the substrings, you add up the all those with residue zero terminating in all locations.

Here is the code:

```<code>// Takes constant space and linear time.
public static void main(String[] args) {

    // You really only need these numbers mod 3.
    int[] s = new int [] { 5,8,1,4,6,2 };
    int left = 3;
    int right = 4;

    int[] found = new int[3];
    int[] last_found = new int[3];
    int sum_found = 0;

    for(int i = left; i <= right; ++i) {

        int res = s[i-1] % 3;

        // leaving the +0 just to show the symmetry.
        // Basically, rotate by the residue and +1 for the new substring.
        // This can be done as a single array, but this is clearer I think.
        // (Also, a proper mathematical modulus would be easier too.)
        found[(res+0) % 3] = last_found[0] + 1;
        found[(res+1) % 3] = last_found[1];
        found[(res+2) % 3] = last_found[2];

        sum_found += found[0];

        // Swap the current and last arrays to make top of the loop simpler.
        int[] swap = last_found;
        last_found = found;
        found = swap;
    }

    System.out.println( sum_found );
}
</code>```

Code Edit

The code above removed the table and just keeps track of the last position. It does this with two arrays of length three and swapping between them. It could  be done with a single array, but it makes the code more complex (and probably doesn't even perform better in the micro-optimization sense either).

It is now linear time and constant space while obeying the Left and Right requests. It is like a number of other DP algorithms, if you notice each iteration you are only looking back the the Ith-1 iterations, then you can usually elide the full table.

It also keeps track of the sum along with way (now required since the final array doesn't exist anymore either). I didn't fully understand the problem at first, and it appears to have gone through some edits along the way.

Body:
Cute dynamic programming problem. Here is a Java solution and quick explanation.

The basic question to ask yourself is if I knew subproblem X, I could solve solve problem Y easily.

In this case, problem Y is the number of substrings divisible by 3, the subproblem X is the number of substrings modulo 3 that terminate at the previous character for each possible mod (that is remained 0, 1, and 2).

If you know that at the previous position, there were 2 substrings that terminated there that had a residue of zero, 3 with a residue of one, and 1 with a residue of two, then given the current number and its residue, it is trivial to determine the residues of all the strings that terminate at the current character.

If the current number's residue is one (e.g., the number is 1, 4, or 7), then the substrings terminating on the previous number with a residue of one now have a residue of two, those with a residue of two now have a residue of zero, and those with a residue of zero now have a residue of one plus 1 more for the current digit since you added a new possible substring of length one.

For example, if you had the string 521438 and you knew the number of strings terminating at the 3 for each residue (2, 2, and 1 respectively for residues 0, 1, and 2), and since 8 mod 3 is 2, you know that all those with residue zero now have residue 2, those with residue two now have residue one, and those with residue one now have residue zero, so (2, 1, and 2 repectively), plus you have a new string of residue 2 so you have 2, 1, and 3 now including the current number.

After you process this in linear time, for all the substrings, you add up the all those with residue zero terminating in all locations.

Here is the code:

// Takes constant space and linear time.
public static void main(String[] args) {

    // You really only need these numbers mod 3.
    int[] s = new int [] { 5,8,1,4,6,2 };
    int left = 3;
    int right = 4;

    int[] found = new int[3];
    int[] last_found = new int[3];
    int sum_found = 0;

    for(int i = left; i <= right; ++i) {

        int res = s[i-1] % 3;

        // leaving the +0 just to show the symmetry.
        // Basically, rotate by the residue and +1 for the new substring.
        // This can be done as a single array, but this is clearer I think.
        // (Also, a proper mathematical modulus would be easier too.)
        found[(res+0) % 3] = last_found[0] + 1;
        found[(res+1) % 3] = last_found[1];
        found[(res+2) % 3] = last_found[2];

        sum_found += found[0];

        // Swap the current and last arrays to make top of the loop simpler.
        int[] swap = last_found;
        last_found = found;
        found = swap;
    }

    System.out.println( sum_found );
}

Code Edit

The code above removed the table and just keeps track of the last position. It does this with two arrays of length three and swapping between them. It could  be done with a single array, but it makes the code more complex (and probably doesn't even perform better in the micro-optimization sense either).

It is now linear time and constant space while obeying the Left and Right requests. It is like a number of other DP algorithms, if you notice each iteration you are only looking back the the Ith-1 iterations, then you can usually elide the full table.

It also keeps track of the sum along with way (now required since the final array doesn't exist anymore either). I didn't fully understand the problem at first, and it appears to have gone through some edits along the way.


问:
Is DDD not appropriate for my website or should I introduce a Query Layer?
I have inherited an ASP.NET website application and the previous developer has used what I believe are some DDD concepts. I am new to DDD and I have to admit I am struggling with the practical side of it having come from an N-Tier Transaction Script background.

One of the problems with the site is that it is slow. There is no paging on huge grids and also the business logic layer pulls down way more data than is needed for 90% of operations 70% of which are reads to bind data to grids.

The general design is that the business logic layer has a Service class per aggregate root, with various "GetByX()", 'FindBestMatching()" and "Update()" type methods on it. These Service classes are the points from which trees of domain objects are created such as "Organisation" and "User."

Back in my comfortable transaction script days, my service layer was similar: there would be some logic possibly, a call into a repository (or since EF 6 direct use of EF as it can be mocked for testing) and then the call would return. The objects that were returned would be DTO type objects containing return data relevant, including possibly some POCO entity objects. These DTOs would travel to clients via webservices, be bound to ASP.NET or Silverlight grids...all was good.

My operations on my service layer could be very specific, allowing for queries like:

```<code>"GetUsersWithSurnameIncludeChildren(string surname, int skip, int take)"
</code>```

allowing for nice narrow DB queries that supported paging and eager loading of related data. It was fast and loaded only the data that was actually needed.

Now with this site I have inherited there is an actual OO model of the business domain. These classes are POCOs, not generated from EF, but EF is used database first as a repository (there is a lot of mapping between the domain objects and the EF objects). An example domain object is below (without any logic).

```<code>public class Organisation
{
    public int OrganisationID { get; set; }
    public string Name { get; set; }

    public IList<Organisation> AssociatedOrganisations { get; set; }
    public IList<User> Staff { get; set; }
    public IList<User> Managers { get; set; }

    // Business logic method implemented below here
}
</code>```

Many of the classes are essentially copies of the underlying entity framework objects, others have a significant amount of logic encapsulated within them.

The way the site works currently is that every time the OrganisationService service class creates a new Organisation domain object (and it may create a collection in one hit) it also populates ALL of the fields and collections in that object...and all of the fields and collections in those objects! A huge deep tree is created in memory and a stack of joins and unions (generated by EF) is needed to get all of the data. This is totally inappropriate for a website that mainly displays loads of flat grids.

My questions are:

1) Is an application that is 70% pulling data out of a DB for display and 30% business logic actually a bad candidate for DDD?

2) If DDD is appropriate how are scenarios like this generally designed? Should I implement a separate "Query Service" that is designed just to pull out loads of flat data for binding to pages and grids (these could just be the EF POCOS themselves) and reserve the Domain objects just for parts of the application where logic must actually be performed?

3) Should I only load data into my Domain Object reference types and collections when it is actually accessed (like EF lazy loading...)? Previous posts I have read have suggested lazy loading in a Domain Object is a code smell: DDD Lazy Loading Code Smell

I am about to buy a DDD book tonight :)

答:
After you read Evans' book, you will see that DDD is a collection of concepts. The book was written over a decade ago. My opinion of it today is that it has good parts but is easily misunderstood and sometimes used inappropriately. In reality, some parts you may not need or may not be right for your application or chosen tools.

As far as EF, I don't think that the DDD concept of combining data and behavior in your entities melds well with it. EF entity models should be devoid of behavior if you want to avoid a lot of unexpected errors and performance bottlenecks. As other answers here point out, using a CQ(R)S pattern is a good way of implementing behavior externally from EF entities. Bottom line is, try to avoid implementing a "rich domain model" using methods on EF entities. You can still crunch the business knowledge into "the model", but your "model" should contain different classes for data (entities) and behavior (operations).

I also don't like the idea of repositories, but that's primarily my opinion and I'm sure others will disagree when I say they really aren't necessary when you are using an ORM like EF. Maybe a decade ago, before we had modern generics, they were more useful. These days, you can wrap a single generic interface around an EF DbContext and have a single generic repository (along with unit of work).

On the other hand, things like the ubiquitous language, aggregate roots, bounded contexts, query criteria, etc. I consider to be pearls. Keeping the application layer thin is a timelessly good practice too. It sounds like the other developer might not have applied the appropriate DDD concepts, and as someone else here already said, created more problems than they solved.


答:
Here is a Python solution to the problem. It is basically the same as the solution of @JasonN. It also implements a function that returns the value for different pairs of L and R. It uses less memory when doing the precalculations. You can run it here </p>

```<code>#http://programmers.stackexchange.com/q/268022/51441

# s:
#   input digit string that should be checked
# L:
#   the start of the substring that should be investigated
# L:
#   the end of the substring that should be investigated
# cnt:
#   number of 3divisble substrings found so far
# ss0:
#   number of substrings that end at the current position
#   and are divisible by 3
# ss1:
#   number of substrings that end at the current position
#   and have the remainder 1 when divided by 3
# ss2:
#   number of substrings that end at the current position
#   and have the remainder 2 when divided by 3

def ss(s,L,R):
    cnt=0
    (ss0,ss1,ss2)=(0,0,0)
    for i in range(L,R+1):
        r=int(s[i])%3
        if r==0:
            ss0+=1
        elif r==1:
            (ss0,ss1,ss2)=(ss2,ss0,ss1)
            ss1+=1
        elif r==2:
            (ss0,ss1,ss2)=(ss1,ss2,ss0)
            ss2+=1
        cnt+=ss0
    return(cnt)

print(ss('392301',0,len('392301')-1))
print(ss('2035498',2,5))
</code>```

Title: Efficient algorithm to count number of substrings divisible by 3

Body:
Given a string of decimal digits, I have to find the number of all substrings divisible by 3 in the range L to R [both inclusive], where L & R are index[1-based] of the specified string

string length <= 100000

I've tried the Naive approach of iterating over all possible substrings & obtaining the answer, but that is not fast enough, especially for multiple pairs L & R.

Then I tried a DP approach. I can obtain all possible substrings divisible by 3 in the whole string, i.e. I'm unable to code the DP solution that gives result for given range.

DP Solution that I tried (not completely sure about It):

```<code>for(i=0 ; i<n ; i++) {
    for(j=0 ; j<3 ; j++) {
        dp[i][j]=0 ;
    }
    int curr = (input[i]-'0')%3 ;
    dp[i][curr]++ ;
    if(i) {
        for(j=0 ; j<3 ; j++) {
            if(curr % 3 == 0) { dp[i][j] += dp[i-1][j]; }
            if(curr % 3 == 1) { dp[i][j] += dp[i-1][(j+2)%3]; }
            if(curr % 3 == 2) { dp[i][j] += dp[i-1][(j+1)%3]; }
        }
    }
}
long long sum = 0;
for(i=0 ; i<n ; i++) { sum += dp[i][0] ; }
</code>```

Can this solution be modified to give results for given range [L,R] ?

After searching alot, I learnt that range queries problems are solved by Segment Tree, but I'm unsure as how Segment Tree + Lazy Propagation can help in this question.

So what is a performant way to count all substrings divisible by 3 in the range L to R [both inclusive]?

EDIT:

Input: First Line contains the given string. Lines after that contain two integers denoting L and R respectively, where both L and R are index(1-based) of string.

Input:

  301524
  1 2
  4 6
  3 5

Output:

  3
  1
  1

Explanation:

  When L=1 & R=2 we get 3 possible substrings, {3}, {0}, {30} & all these when considered as a decimal number are divisible by 3. Hence the output.

  When L=4 & R=6 we get 6 possible substrings, {5} , {52}, {524}, {2}, {24}, {4} & out of these only {24} is divisible by 3.

Repetitions in substrings like 3333 count multiple times, so for L=1 to R=4 the answer would be 10, since we have four times 3, three times 33, two times 333 and one time 3333 (all divisible by 3).

Body:
Here is a Python solution to the problem. It is basically the same as the solution of @JasonN. It also implements a function that returns the value for different pairs of L and R. It uses less memory when doing the precalculations. You can run it here

#http://programmers.stackexchange.com/q/268022/51441

# s:
#   input digit string that should be checked
# L:
#   the start of the substring that should be investigated
# L:
#   the end of the substring that should be investigated
# cnt:
#   number of 3divisble substrings found so far
# ss0:
#   number of substrings that end at the current position
#   and are divisible by 3
# ss1:
#   number of substrings that end at the current position
#   and have the remainder 1 when divided by 3
# ss2:
#   number of substrings that end at the current position
#   and have the remainder 2 when divided by 3

def ss(s,L,R):
    cnt=0
    (ss0,ss1,ss2)=(0,0,0)
    for i in range(L,R+1):
        r=int(s[i])%3
        if r==0:
            ss0+=1
        elif r==1:
            (ss0,ss1,ss2)=(ss2,ss0,ss1)
            ss1+=1
        elif r==2:
            (ss0,ss1,ss2)=(ss1,ss2,ss0)
            ss2+=1
        cnt+=ss0
    return(cnt)

print(ss('392301',0,len('392301')-1))
print(ss('2035498',2,5))


问:
Cleanest choice for symmetric operations
I have a need to do some processing from a format A to a format B and from B to A. The job in one direction is very similar to its counterpart. Both formats are represented with an interface Msg.

In such a case, I can see four obvious solutions, which is the cleanest? I hope there are some concrete principles explaining one choice over the others and not just personal preferences

Here are the obvious choices

1) Different classes for each

```<code>public class TransformToA {
   public TransformToA() {
       ...
   }
   public Msg transform(Msg incoming) {
       ...
   }
}
public class TransformToB {
   public TransformToB() {
       ...
   }
   public Msg transform(Msg incoming) {
       ...
   }
}
</code>```

Note that in this option, I could extract some common logic into a third common class to avoid code duplication

2) A boolean field to define the direction

```<code>public class Transformer {
   private boolean toBFormat;
   public Transformer(boolean toBFormat) {
       ...
   }
   public Msg transform(Msg incoming) {
       if (toBFormat) {
          ...
       } else {
          //to A format
       }
   }
}
</code>```

3) a boolean flag on the method (this is probably the worst since the caller is forced to pass the flag every single time and makes a method behave in two different ways)

```<code>public class Transformer {
   public Transformer() {
       ...
   }
   public Msg transform(Msg incoming, boolean toBFormat) {
       if (toBFormat) {
          ...
       } else {
          //to A format
       }
   }
}
</code>```

4) Two different methods

```<code>public class Transformer {
   public Transformer() {
       ...
   }
   public Msg transformToA(Msg incoming) {
       ...
   }
   public Msg transformToB(Msg incoming) {
       ...
   }
}
</code>```

答:
Many clean solution exist.

My pick in Java would definitely be the following structure:

```<code>public abstract class AbstractTransform {

    ... do whatever is the same in all transformer,
        or if the constructor would be the same etc...

    protected void iDoThisAllTheTime(){
        ... boring, repeating codes come here
    }

    public Msg transform(Msg incoming);

}
</code>```

then just extend this abtract class, and implement the missing method:

```<code>public class TransformToA extends AbstractTransform {

    @Override
    public Msg transform(Msg incoming){
        ... do the transformation
        iDoThisAllTheTime();
    }

}
</code>```

Advatanges:

easy to extend in a way you want. If you need some additional one, just extend once more.

documents itself, you need to document pretty much only the Abstract one to say what is it for. The rest of classes will do the same.

if you need common logics, you can implement it in abstract class, you will avoid duplications. You can implement protected methods for common use and invoke them in child classes.

not complicated. You don't need to juggle with classes, interfaces if the task is simple, your code can stay simple.

Body:
Many clean solution exist.

My pick in Java would definitely be the following structure:

public abstract class AbstractTransform {

    ... do whatever is the same in all transformer,
        or if the constructor would be the same etc...

    protected void iDoThisAllTheTime(){
        ... boring, repeating codes come here
    }

    public Msg transform(Msg incoming);

}

then just extend this abtract class, and implement the missing method:

public class TransformToA extends AbstractTransform {

    @Override
    public Msg transform(Msg incoming){
        ... do the transformation
        iDoThisAllTheTime();
    }

}

Advatanges:

easy to extend in a way you want. If you need some additional one, just extend once more.

documents itself, you need to document pretty much only the Abstract one to say what is it for. The rest of classes will do the same.

if you need common logics, you can implement it in abstract class, you will avoid duplications. You can implement protected methods for common use and invoke them in child classes.

not complicated. You don't need to juggle with classes, interfaces if the task is simple, your code can stay simple.


问:
Working with legacy code - introducing an external BDD integration test harness
Here's the scenario.

There's a large, organically grown application written in some language and manner that makes it difficult to test.  It works but is hard to maintain.

Specifications are woolly, so even if the code was amenable, it's hard to know what things should be doing without doing them.

You want to get it into a test harness so you can start to refactor and create proper unit tests.

In these cases it makes sense to build an external or superficial 'test everything' harness so you can start more aggressive refactoring to enable you to write proper unit tests.  This seems a pretty established practice of incrementally introducing tests.

"The main thing that distinguishes legacy code from non-legacy code is a lack of
comprehensive tests." - Michael C. Feathers (Working Effectively with Legacy Code)

My question is this:

Does it make sense to build a suite of Behaviour Driven tests at this point and execute them via some kind of automated button clicker?  I'm thinking something like (but not limited to) cucumber or similar where the human readable tests match executable code/scripts that prove the defined behaviour is being met.

A clear advantage of this is that a human readable specification of sorts could be developed alongside the tests and that these specifications are much easier to confirm as sane and correct with users/developers of the system.  They are essentially integration tests but perform the function that Feathers recommends.

eta: I'm not asking for a specific tool recommendation, the actual tool is irrelevant (although it would be helpful to know if they actually exist) I'm after a sanity check and recommendations around external BDD integration testing.

答:
Does it make sense to build a suite of Behaviour Driven tests at this point and execute them via some kind of automated button clicker?

At least it sounds reasonable. What you are suggesting can be implemented by any "GUI robot" with a support for data driven tests (I am not going to suggest you a tool, look here for a start). If the frontend for creating the tests is not enough "BDD style", I think creating an interface between cucumber and the GUI robot should not be too hard.

But beware: creating such tests will definitely need some effort, especially when you are trying to create a "test everything" harness. You have to estimate by yourself if the benefit you get from this outweighs the effort. Furthermore, my own experience with GUI automation tools is that tests created with them tend to become brittle (but YMMV).


问:
What are 4th & 5th programming language generations? Are there more of them?
As it is often classified at school/college level, popular programming languages (C#, Java, C++) are all 3rd generation languages (with higher level of abstraction from the machine's physical parts). Also, assembly languages are classified as 2nd and machine languages as 1st generation languages.

Initially I was thinking SQL should be considered 4th generation language cause it is more abstract and far away from details of looping and more descriptive.

Just now I found out there are 4th generation and 5th generation languages, but what is the basis for any programming language or technology to be categorized as a 4th or 5th generation language?

Also, are there 6th or 7th generation languages as well?

答:
“nth-generation language” is a buzzword. It is a marketing term. There is no universally accepted definition of what exactly defines the “nth generation” for n > 2. Some people categorize “scripting” languages such as Perl or Python as 4GLs because they are much more high-level than C, while others think the defining characteristics of 4GLs is that they're domain-specific, e.g. SQL. Some nitwits even think that Java (a mid-90s language full of object orientation and garbage collection and reflection) belongs in the same “3GL” category as Fortran (from the 50s) and C (from the 70s).

A categorization so confused such as “4th generation language” is of no use. You may see it in old textbooks, or hear it from people that started programming in the 80s, but a tag such as “4GL” is worthless without an accompanying explanation of what exactly the author means by that.

Since no one immediately understands what you mean by “4GL”, you should not use such categorizations. Instead, use specific terms to communicate precisely what you mean. E.g. all of NASM, LLVM IR, and Jasmin are assembly languages, but the latter two target VMs, and the last one is also an object-oriented programming language. Are all of those 2GLs? SQL is a partially declarative, domain specific language for database queries from the 80s. And TeX is a domain specific language for typesetting from the 70s. Are they both 4GLs since they are both more or less domain specific?


问:
Is it good design to put abstract methods in an abstract class even though the methods are already defined in its interface?
Let's say we have an interface Foo with a method "public void someMethod()", and we have one or multiple abstract classes that "implement" Foo but don't necessarily themselves provide an implementation for someMethod().

Would it be good design to put for example "public abstract void someMethod()" in these abstract classes, or would it just be more effort for no good reason?

P.S. My programming language in question is Java, just in case that influences the answer.

答:
No. This is just duplicate code that provides no benefit, unless you're specializing the interface for that abstract base class.

It could be argued that by having the method explicitly declared helps things be more readable, but I would argue that it should be clear by the interface declaration what is going on. If it's not, then your interface needs a better name and/or your abstract base class is doing too many things.

If all you're doing is duplicated code then you cause yourself more work up front, more work when it changes, and make it more likely that the abstract class gets out of sync with the interface, leading to two very similar distinct methods.


答:
Simple generations overview: a language is n'th generation when it's building blocks are

bits

instructions

Abstract operations

Domain objects

Program Goals

Hence even languages as new as Google Go or Apple Swift are still solidly 3rd generation. Regex is a text matching language, which makes it an early 4th generation language. By this definition, 4th generation closely aligns with DSL's. However, note that languages such as C++ can have real-world types such as Length and Weight in addition to float and double, which makes them hybrid 3rd/4th generation.

5th generation languages do not practically exist, as they generally require a level of AI that never materialized. The fact that we programmers still are needed is exactly because non-programmers cannot tell a computer with sufficient precision what exactly they want.

Title: What are 4th & 5th programming language generations? Are there more of them?

Body:
As it is often classified at school/college level, popular programming languages (C#, Java, C++) are all 3rd generation languages (with higher level of abstraction from the machine's physical parts). Also, assembly languages are classified as 2nd and machine languages as 1st generation languages.

Initially I was thinking SQL should be considered 4th generation language cause it is more abstract and far away from details of looping and more descriptive.

Just now I found out there are 4th generation and 5th generation languages, but what is the basis for any programming language or technology to be categorized as a 4th or 5th generation language?

Also, are there 6th or 7th generation languages as well?


问:
What TDD/BDD tests should be writen to test an ORM
So I'm writing an ORM for NodeJS and using Mocha + Chai to test it.

What I want to know is, what tests I should write to it, insertion tests should also have a querying test so I can check if the tool has inserted the correct data?

Also, how should I organize the tests? Any example of how to begin to write those tests? (Not an example of how to write tests, but how to organize and plan the tests for an ORM)

答:
I tested the ORM for the Chicago Boss framework about a year ago. Instead of using unit tests I mostly used QuickCheck Properties, in which I created random data and saved it to the database, then read it back and made sure that I got the same thing back.

It turns out that there was a problem (now fixed) in that if you saved a string that had the substring "\ " in it that the double slash would be dropped. I found this by having my tool create hundreds (or maybe thousands) of strings and saving them to the database until it found one that broke.

Right now I am using this framework in Javascript https://github.com/jsverify/jsverify and quite happy with it


问:
How to deal with checked exceptions that cannot ever be thrown
Example:

```<code>foobar = new InputStreamReader(p.getInputStream(), "ISO-8859-1");
</code>```

Since the encoding is hardcoded and correct, the constructor will never throw the UnsupportedEncodingException declared in the specification (unless the java implementation is broken, in which case I'm lost anyway). Anyway, Java forces me to deal with that exception anyway.

Currently, it looks like that

```<code>try {
    foobar = new InputStreamReader(p.getInputStream(), "ISO-8859-1");
}
catch(UnsupportedEncodingException e) { /* won't ever happen */ }
</code>```

Any ideas how to make it better?

答:
The part of these exceptions that annoys me most is that it hurts my code coverage.

When I'm getting compulsive about coverage, I'll roll up the try / catch that "can never happen" (...or only if I'm using a mutant JVM that somehow forgot to include "US-ASCII") into a class and method that encapsulates that try / catch, and replace the checked exception in one of the ways mentioned here (usually throwing an unchecked exception with a snide message).

Then my code coverage takes a hit in the utility class, but not in all the references to that operation scattered around my code.

Sometimes I'll take the time to roll up like operations in a class that actually has coherent semantics. But since it's pretty obvious to my teammates what's going on, I usually just keep it as simple as I can & not worry so much about the best possible design.

However, as a comment mentioned, Guava & other libraries have ways to mitigate this pain -- but that's basically the same strategy. Move the annoyance off-stage so your main code doesn't take the hit in coverage.


问:
Natural Language Processing (NLP) open source algorithms
I am looking for a way to give an algorithm (service) a sentence, and it will tell me if its positive context or negative or even neutral.

Does such a service exist?

答:
The OpenNLP site may help you

The link refers to a long list of projects that are using OpenNLP to solve natural language processing problems.

Also, since you seem to be looking for a Sentiment and Opinion Mining application, perhaps the open source RapidMiner application may be of interest.

Here is a quote describing it:

The software supports a wide variety
  of clustering, classification and
  other data mining functions.
  Text-related modules include the Word
  Vector Tool (WVT), Named Entity
  Recognition (NER) and Data Stream
  plug-ins. According to Rapid-I
  cofounder and managing director Ralf
  Klinkenberg, RapidMiner responds to a
  very wide set of text-processing needs
  including news filtering, email
  routing, sentiment analysis and
  opinion mining, and general
  information extraction. According to
  Klinkenberg, RapidMiner allows users
  to combine unstructured data (text
  documents) and structured data
  (database tables, time series data,
  audio data, etc.).


问:
How can I (in general) program a website for mobile devices?
I really tried searching about this in the internet but came upon diverse search results which barely specified what must be done specifficaly.

I'm now running ubuntu and php5 through nginx, amongst other things.

How is it that I can specify different layout and functionalities for mobile devices under the url "https://m. (...)"?

m for mobile (I'm aware this signature is not always used)

答:
One approach is to create 2 web sites.

One's your normal everyday site:  http://www.example.com

The other is a copy of the everyday site, except you modify the CSS and make whatever other changes are needed to support your mobile users.  By convention, you have your server folks set that up with the address http://m.example.com.

Now for the clever bit: in your main web site, you look at the browser string that accompanies every request.  If that string looks like it belongs to a mobile device, you respond to the request with a 302 Redirect (or similar - there's a lot of different ways to do this).

If you need the specifics on how to look at the browser string or do the redirect using your particular tool set, you'd be best off posting a separate question (or two) on Stackoverflow instead of here.


答:
Firstly ensure that your view logic and domain logic are separate, you can search for "Model View Controller PHP" on Google for more information about this.

Once your view is separated from your logic it becomes a simple case of including a different view for mobile devices. There are many libraries for detecting if the client is a mobile browser such as http://mobiledetect.net/. These usually work via inspecting the User Agent string of the $_SERVER superglobal. http://php.net/manual/en/reserved.variables.server.php

Hope this helps

Title: How can I (in general) program a website for mobile devices?

Body:
I really tried searching about this in the internet but came upon diverse search results which barely specified what must be done specifficaly.

I'm now running ubuntu and php5 through nginx, amongst other things.

How is it that I can specify different layout and functionalities for mobile devices under the url "https://m. (...)"?

m for mobile (I'm aware this signature is not always used)


问:
Bootstrap licence free template
I´m creating a new website. For that I´m using a free bootstrap template. On top of my index page I have:

```<code> A Design by W3layouts
    Author: W3layout
    Author URL: http://w3layouts.com
    License: Creative Commons Attribution 3.0 Unported
    License URL: http://creativecommons.org/licenses/by/3.0/
</code>```

Can I delete or change this for my own purpose (in other words change author, License, etc)?

Licence also says:

You are free to:

Share — copy and redistribute the material in any medium or format Adapt — remix, transform, and build upon the material for any purpose, even commercially. The licensor cannot revoke these freedoms as long as you follow the license terms.

So, can I have any problem in future (which clearly I´m not seeing)?

答: No, you cannot alter that license. The license is granted by the copyright owner, and you're not the copyright owner. This is a legal restriction, and hence does not need to be repeated in the license itself.</p>

Title: Bootstrap licence free template


问:
Is it reasonable to have grunt/gulp build phases in javascript dev environment
Nowdays it's goes to be very fancy to have grunt/gulp build phases who concatenate and minify and organize javascript code.

And I agree that this is important for production.

But as a developer, I see inconvenience there:

additional step to run code (execute gulp/grunt command)

hard to navigate in one concatenated files (even worse if it's
minified)

Build procedure take time, especially if your project quite big and
pc not very powerfull

So, is it important to have all that steps for development mode anyway, or will be reasonable to make it a part of release process, and avoid using it during development?

答:
It is important to do this in development only if you are not 100% certain that the script-mangling step doesn't introduce errors.

Personally, I think using a tool that you can't be 100% certain of to transform your entire code base is unprofessional and you should never do it, but I recognize that getting the job done in the real world sometimes requires you to compromise your principles. Therefore my answer is not a straight "no, it's not necessary", but only "almost certainly no".


答:
You need to do it from time to time in development to check that it works correctly and isn't adding any additional bugs.

It shouldn't be a step that you're using just in your release process, because that should be happening post-testing.

You shouldn't be doing it for every small change you make, but from time to time you should absolutely be checking your new code works correctly after it's been concatenated and minified.

Title: Is it reasonable to have grunt/gulp build phases in javascript dev environment

Body:
Nowdays it's goes to be very fancy to have grunt/gulp build phases who concatenate and minify and organize javascript code.

And I agree that this is important for production.

But as a developer, I see inconvenience there:

additional step to run code (execute gulp/grunt command)

hard to navigate in one concatenated files (even worse if it's
minified)

Build procedure take time, especially if your project quite big and
pc not very powerfull

So, is it important to have all that steps for development mode anyway, or will be reasonable to make it a part of release process, and avoid using it during development?


问:
The correct manner in implementing an email notification system
I'm looking to build an email notification system using codeigniter. Now the system in question is one of a 2nd hand online store. For example say person A would like a chair. When they search the system and nothing appears I would like them to subscribe to any notification regarding the chair. So when person B uploads a chair to be sold then everyone that subscribed to these notifications will be notified via email. This is what I'm looking to build, which for the most part is fairly easy.

My concern revolves around the sending of these emails. I would like to know what is the BEST way of  sending these types of emails and a solution that scales well. So if 1000 people decide to follow the chair, the solution won't fall apart. I've read about mass email systems chocking servers, being marked as spam server etc. Would it be better to send these emails through a third party etc? If so which third party would be the most reliable and cost efficient for this given job?

Please note this is my first time I'm looking to do this and I'm just looking for guidance to get the job done "right" the first time round. Thank you in advance

答:
Unfortunately, the "best" way of sending out emails of this nature is going to vary depending on the specifics of your project. There isn't a one-size-fits-all solution. If your user-base isn't very large, rolling your own solution can be a quick and easy way to get the job done. However, as your user base increases, so do the resources necessary to handle sending all of the emails in a reliable and timely fashion. At that point, you might consider a third party distributor. What point that is at, though, is going to depend on your budget (both from a fiscal and time perspective). </p>

<p>Regardless, a good design would decouple the sending of emails from the trigger that determines when those emails should be sent. At that point, replacing a solution should be a fairly painless process. I would say that - at least for testing - you ought to roll your own solution (which will make you familiar with any pitfalls), then see about using a third party service if the need arises. </p>

Body:
Unfortunately, the "best" way of sending out emails of this nature is going to vary depending on the specifics of your project. There isn't a one-size-fits-all solution. If your user-base isn't very large, rolling your own solution can be a quick and easy way to get the job done. However, as your user base increases, so do the resources necessary to handle sending all of the emails in a reliable and timely fashion. At that point, you might consider a third party distributor. What point that is at, though, is going to depend on your budget (both from a fiscal and time perspective).

Regardless, a good design would decouple the sending of emails from the trigger that determines when those emails should be sent. At that point, replacing a solution should be a fairly painless process. I would say that - at least for testing - you ought to roll your own solution (which will make you familiar with any pitfalls), then see about using a third party service if the need arises.


答:
There are cases where it could be appropriate.

Consider an abstract base class that contains a default implementation of InitializeSomeMethod(), and that method calls someMethod() but there exists no default implementation for someMethod. The base class can define someMethod as abstract, and thereby allowing it to be called by InitializeSomeMethod().

However if you access the object through it's interfaces and not the base class, and the base class does not need to access those methods or properties, then it isn't necessary to define them as abstract.

Title: Is it good design to put abstract methods in an abstract class even though the methods are already defined in its interface?

Body:
Let's say we have an interface Foo with a method "public void someMethod()", and we have one or multiple abstract classes that "implement" Foo but don't necessarily themselves provide an implementation for someMethod().

Would it be good design to put for example "public abstract void someMethod()" in these abstract classes, or would it just be more effort for no good reason?

P.S. My programming language in question is Java, just in case that influences the answer.


问:
Is there any way to use Python to replace Flash for in browser animation, gaming, whatever?
Is there any way to use Python to replace Flash for in browser animation, gaming, webapps, whatever?  Pretty straight-forward IMHO.  Does anyone know how to do this?</p>

答:
There is Brython, which is a browser-friendly Python(2.7+)-to-JavaScript compiler, written in JavaScript. It works pretty well already and has an active community.

With Brython, you can include your python scripts as simple as:

```<code><script type="text/python"> ... </script>
</code>```

Body:
There is Brython, which is a browser-friendly Python(2.7+)-to-JavaScript compiler, written in JavaScript. It works pretty well already and has an active community.

With Brython, you can include your python scripts as simple as:

<script type="text/python"> ... </script>


问:
`values` vs `list` for returning multiple values from Lisp form
What's the difference between using (values …) versus (list …) (or literally '(one two three …)) to return multiple values from a lambda (or other implicit progn)? Does it create some special glue to multiple-value-bind? Superficially, I can't see any difference and am curious whether it's merely a convention for multiple return values.

答:
This question has been already answered on SO: values function in Common Lisp.

Briefly, multiple values is a facility to return many objects without allocating extra memory.
E.g. floor
must return two values - quotient and remainder.
It can return a list (or a pair) or it can return two values.
In the former case it will have to allocate a cons cell on each call, in
the second it will not.

This means that multiple values have certain limitations
(one cannot return more than 20 values portably).


问:
Where should I place a typedef when used in method signatures in C++?
I'm using an Optional class quite similar to that of boost. For semantic reasons, I switched an attribute of the same (structured) type in some class definitions (and therefore also in method signatures) from mandatory to optional. So, in each related class header file, I included the header with the definition of Optional and also a typedef to ease typing (see CHANGE comments); the passages read like this:

```<code>#include <MyAttrType.h>
#include <Optional.h>                          // CHANGE
typedef Optional<MyAttrType> OptionalAttrType; // CHANGE

class MyClassX
{
// ...
</code>```

Today I run Cppcheck 1.68 on the project and got this style warning:

The typedef 'OptionalAttrType' hides a typedef with the same name.

How can I get rid of theses style warnings without making something bad?

Remarks:

MyAttrType itself is currently independent from Optional (because defined early in the project history, while Optional was being last time)

I think of introducing a new header only for this purpose. But maybe there are better options?

I guess that it could generally be an indication of bad design, to have many classes with the same optional attribute, but I'm not sure in my special case. The code is currently changing to reach higher prioritized goals.

of course, MyAttrType, OptionalAttrType, and MyClassX aren't the actual names

答:
If OptionalAttrType is part of the public API defined by those headers, then I would use some other name for your typedef.

If OptionalAttrType is an implementation detail that you aren't supposed to know about, then those headers should have put it inside a namespace to prevent collisions like this. Since they didn't, you have to work around this somehow.

Because you're asking this question, I assume you expect to encounter more of these collisions in the future, so you need a long-term solution. Unless you can change all the headers and source files you depend on to use namespaces or more consistent class names, the only general solution I can think of is choosing a prefix or suffix that's unlikely to collide with anything (eg, OptionalAttrType_TD) and start using it for all your typedefs.

A less general but perhaps more practical alternative is to simply hide this warning. Chapter 6 of the Cppcheck manual describes all the ways you can suppress a specific warning from that tool.

ContentLicense: CC BY-SA 4.0


问:
How use same Behavior Drive Development (BDD) stories across platforms?
I'm writing an app that has a client for iOS, Android, and the web. The server is hosted on Google App Engine (Java). REST is used for the communication between clients and server.

In order to ensure a uniform user experience across platforms, as a software designer, I want to write Behavior Driven Development (BDD) stories in one text file and have them drive development at every layer of the stack.

One partial solution for the Android client and the server is JBehave because it supports Java. But the iOS client is written in Objective-C and some Swift which JBehave can't help with.

What I like about JBehave though is it allows me to write stories in a simple syntax and keep those stories in a text file. It can be the same text file for every developer, regardless of their layer of the stack (as long as it's a Java developer).

I found some BDD frameworks for iOS at http://www.objc.io/issue-15/behavior-driven-development.html. But after skimming their documentation sets, I can't find any that emphasize a simple file format like JBehave's. As a designer, I don't want to write in some format that's partially story and partially code. That's too much syntax for me to have to learn AND risks inconsistencies cropping up across the different manifestations of the stories.

Moreover I haven't found any frameworks that discuss their portability across different layers of the stack and/or across development platforms.

How can I achieve the maximum potential of BDD in a heterogenous development environment?

答:
Have you looked at Calabash?

Never used it, but it says it offers support for iOS and Android, and it runs under Cucumber which means it supports the Gherkin syntax; also supported by JBehave and by Cucumber-JVM.


问:
Why is having merge bubbles in your git history not actually that bad?
In the past year, most of the rest of my group (of engineers that I work with), has ended up deciding that merge bubbles really aren't that bad.

At the very least, I'm seeing that other developers do not consider rebasing worth the effort needed to avoid merge bubbles when merging (sometimes very badly structured) pull requests.

Why is it actually not that bad to have merge bubbles in your commit history?

To be clear: I am not asking if merge bubbles are bad or not! I am asking why they are not bad.

答:
Whether a satisfactory answer exists to this question is debatable since merge bubbles are desirable for a variety of reasons.

There is less long-term maintenance required when keeping history linear in git, plus it makes it much easier to see what someone was doing rather than attempting to traverse a bushy and complex history. From experience with a large organization and a large number of developers, there is a much higher rate of issues/bugs introduced due to bad merges when compared to rebase.

Honestly, there is not much overhead to keep history linear to avoid merge bubbles. Is it really that hard to add a --rebase option to git pull? Or to set rebase behavior as the default pull behavior in the configuration?

Additionally, the following benenfits are realized when using rebase instead of merge to avoid merge bubbles:

Developers only have to worry about the commits they push when using rebase and not all the complexity and unnecessary commits they added to the history with merges. This greatly simplifies the code review process as well.

Change history analysis is greatly simplified with less time/effort is required.

Reverting changes is a straight-forward process when the history is kept linear through rebase. With merge bubbles in the history, reverting can be more effort than it is worth.

In general, best practices regarding when to use rebase vs merge can be described with the following two use cases:

Rebase should be used for typical development work of individual contributors since it has nearly no additional overhead when compared to a merge.

Merge should only be used by someone in a branch or release management capacity for merging changes between project, organizations, and/or teams.

As a quick disclaimer, with smaller development teams these considerations don't come into play too often, but should still be followed as a best practice. With large organizations though, the benefits of using rebase to keep the history linear greatly outweighs an ill-conceived notion that merge has less overhead than rebase.


问:
how to effectively manage multiple occurrences of one application
I have developed a web application for a client which is live to their customers. Recently, the application has been sold in such as way that it is replicated to other domain names so there are 4+ instances of the application which I am to develop and maintain.

At the moment, each copy of the app has it own SVN repository and when it comes to making changes to the application that effects all instances, I update one and then use Beyond Compare to merge changes over to the other copies.

Would it be a better solution to use svn branches to maintain a core system and to merge out to sub branches and visa versa for bugs? Each application may have changes made to it that are client specific, such as logos, colours etc.

Are Branches the best way to go or continue to have each in their own repository and use BC to merge where necessary?

答:
The typical approach is to have a single core, which can then be configured as needed in a separate module.   For simple cores, you can make do with if-statements based on variables in the configuration module.

For more advanced cores, you need to be able to provide customer specific code overriding standard functionality.  How exactly this happens (compile time, versus runtime) depends on what is most convenient for you.

But you desperately need to consolidate your code in a single code base.  Otherwise the complexity will quickly overwhelm you if you get more customers.


问:
(almost) Pure C instead of C preprocessor
Why isn't (almost) pure C used instead of the C preprocessor?

Sure I understand it would be a little more verbose. For example:

```<code>#define PI 3.14159
</code>```

If we had regular C as preprocessor language, the above could be rewritten to something like:

```<code>#define PI {printf("3.14159");}
</code>```

The idea is to not substitute {printf(...)} for PI but to run the code from the macro definition and splice the output of that code in the place of PI.

Yes, it's more verbose, but for more complex stuff I think it would help alot. Also, going with this design, programmers wouldn't have to learn another language (namely the C preprocessor) in order to write macros.

So, are there any other reason except the verbosity that the C preprocessor is not just pure C (with perhaps small modifications, like the addition of the define keyword)?

答:
What you suggest is possible with more modern languages. C was invented at a time when compiler technology was far too primitive to allow this kind of programmable compilation pipeline. Furthermore, most programmers knew of no use for such a mechanism.

Even today it's difficult to construct a compiler that can permit such programming. It's easy to specify the behaviour in such simple cases but far more difficult to consider what it should do in the general case.


问:
Possible to refactor these methods that contain the same logical flow?
I have many methods in many repositories that have the same logical flow:

Retrieve value from Cache

Check value

If no value, fetch from Database

Update Cache

Return value

Is there a way to refactor these methods in such a way that I don't have to rewrite the same lines over and over again?

I'm using an MVC pattern with services e.g. ActivityService service has ActivityRepositoryInterface (most likely it will be the concrete cached version you see below) injected. I can paste more code if it helps?

Thanks

```<code>namespace DW\DWBundle\Repository\Cached;

use DW\DWBundle\Cache\ActivityCache;
use DW\DWBundle\Entity\User;
use DW\DWBundle\Helper\CacheHelper;
use DW\DWBundle\Repository\ActivityRepository as ActivityRepositoryInterface;
use DW\DWBundle\Repository\Doctrine\ORM\ActivityRepository as ActivityRepositoryDoctrine;

class ActivityRepository extends CustomRepository implements ActivityRepositoryInterface
{
    private $activityRepository;
    private $cacheHelper;

    public function __construct(ActivityRepositoryDoctrine $activityRepository, CacheHelper $cacheHelper)
    {
        parent::__construct($activityRepository);

        $this->activityRepository = $activityRepository;
        $this->cacheHelper = $cacheHelper;
    }

    public function findRecentLikeActivity($limit)
    {
        $key = ActivityCache::KEY_LIKES_WIDGET;
        $name = ActivityCache::CACHE_ACTIVITY;
        $classType = "ArrayCollection<DW\DWBundle\Entity\Activity>";
        $activity = $this->cacheHelper->getFromCache($key, $name, $classType);
        if ($activity == null) {
            $activity = $this->activityRepository->findRecentLikeActivity($limit);
            $this->cacheHelper->saveToCache($key, $name, $activity);
        }
        return $activity;
    }

    public function findRecentCommentActivity($limit)
    {
        $key = ActivityCache::KEY_COMMENTS_WIDGET;
        $name = ActivityCache::CACHE_ACTIVITY;
        $activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
        if ($activity == null) {
            $activity = $this->activityRepository->findRecentCommentActivity($limit);
            $this->cacheHelper->saveToCache($key, $name, $activity);
        }
        return $activity;
    }

    public function findRecentActivity($limit)
    {
        $key = ActivityCache::KEY_ALL_WIDGET;
        $name = ActivityCache::CACHE_ACTIVITY;
        $activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
        if ($activity == null) {
            $activity = $this->activityRepository->findRecentActivity($limit);
            $this->cacheHelper->saveToCache($key, $name, $activity);
        }
        return $activity;
    }

    public function findActivityByUser(User $user)
    {
        $key = ActivityCache::KEY_USER_ID."_".$user->getId();
        $name = ActivityCache::CACHE_ACTIVITY;
        $activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
        if ($activity == null) {
            $activity = $this->activityRepository->findActivityByUser($user);
            $this->cacheHelper->saveToCache($key, $name, $activity);
        }
        return $activity;
    }

    public function findActivityOrderedByCreated()
    {
        $key = ActivityCache::KEY_LIST;
        $name = ActivityCache::CACHE_ACTIVITY;
        $activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
        if ($activity == null) {
            $activity = $this->activityRepository->findActivityOrderedByCreated();
            $this->cacheHelper->saveToCache($key, $name, $activity);
        }
        return $activity;
    }

    public function findActivityOrderedByCreatedASC()
    {
        $key = ActivityCache::KEY_LIST_ASC;
        $name = ActivityCache::CACHE_ACTIVITY;
        $activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
        if ($activity == null) {
            $activity = $this->activityRepository->findActivityOrderedByCreatedASC();
            $this->cacheHelper->saveToCache($key, $name, $activity);
        }
        return $activity;
    }
}
</code>```

....

```<code>namespace DW\DWBundle\Helper;

use JMS\Serializer\Serializer;
use Tbbc\CacheBundle\Cache\CacheManagerInterface;
use Tbbc\CacheBundle\Cache\KeyGenerator\KeyGeneratorInterface;

class CacheHelper
{
    private $cacheManager;
    private $keyGenerator;
    private $serializer;

    public function __construct(CacheManagerInterface $cacheManager,
                                KeyGeneratorInterface $keyGenerator,
                                Serializer $serializer)
    {
        $this->cacheManager = $cacheManager;
        $this->keyGenerator = $keyGenerator;
        $this->serializer = $serializer;
    }

    public function getFromCache($key, $name, $classType)
    {
        $cacheKey = $this->keyGenerator->generateKey($key);
        $cache = $this->cacheManager->getCache($name);
        $serialized = $cache->get($cacheKey);
        $deserialized = $this->deserialize($serialized, $classType);
        return $deserialized;
    }

    public function saveToCache($key, $name, $value)
    {
        $cacheKey = $this->keyGenerator->generateKey($key);
        $cache = $this->cacheManager->getCache($name);
        $serialized = $this->serialize($value);
        $cache->set($cacheKey, $serialized);
    }

    public function deleteFromCache($key, $name)
    {
        $cacheKey = $this->keyGenerator->generateKey($key);
        $cache = $this->cacheManager->getCache($name);
        $cache->delete($cacheKey);
    }

    public function serialize($object)
    {
        return $this->serializer->serialize($object, 'json');
    }

    public function deserialize($data, $class)
    {
        return $this->serializer->deserialize($data, $class, 'json');
    }
}
</code>```

答:
You could create a third class that manages both the repository and the cache. Then, don't manually try to get the cached value and if not available query the repository like

```<code>$activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
    if ($activity == null) {
        $activity = $this->activityRepository->findRecentCommentActivity($limit);
        $this->cacheHelper->saveToCache($key, $name, $activity);
    }
</code>```

Rather have your CachedRepository answer it:

```<code>$activity = $this->cachedRepository->getFromCacheOrRepository($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
</code>```

The cache and repository query logic can now be implemented in the CachedRepository class and therefore be reused.

Body:
You could create a third class that manages both the repository and the cache. Then, don't manually try to get the cached value and if not available query the repository like

$activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
    if ($activity == null) {
        $activity = $this->activityRepository->findRecentCommentActivity($limit);
        $this->cacheHelper->saveToCache($key, $name, $activity);
    }

Rather have your CachedRepository answer it:

$activity = $this->cachedRepository->getFromCacheOrRepository($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");

The cache and repository query logic can now be implemented in the CachedRepository class and therefore be reused.


问:
Does using == in JavaScript ever make sense?
In JavaScript, the Good Parts, Douglas Crockford wrote:

JavaScript has two sets of equality operators: === and !==, and their evil twins == and !=.  The good ones work the way you would expect.  If the two operands are of the same type and have the same value, then === produces true and !== produces false.  The evil twins do the right thing when the operands are of the same type, but if they are of different types, they attempt to coerce the values.  The rules by which they do that are complicated and unmemorable.  These are some of the interesting cases:

```<code>'' == '0'           // false
0 == ''             // true
0 == '0'            // true

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true
</code>```

The lack of transitivity is alarming.  My advice is to never use the evil twins.  Instead, always use === and !==.  All of the comparisons just shown produce false with the === operator.

Given this unequivocal observation, is there ever a time when using == might actually be appropriate?

答:
It turns out that jQuery uses the construct

```<code>if (someObj == null) {
  // do something
}
</code>```

extensively, as a shorthand for the equivalent code:

```<code>if ((someObj === undefined) || (someObj === null))  {
  // do something
}
</code>```

This is a consequence of the ECMAScript Language Specification § 11.9.3, The Abstract Equality Comparison Algorithm, which states, among other things, that

```<code>1.  If Type(x) is the same as Type(y), then
    a.  If Type(x) is Undefined, return true.
    b.  If Type(x) is Null, return true.
</code>```

and

```<code>2.  If x is null and y is undefined, return true.
3.  If x is undefined and y is null, return true.
</code>```

This particular technique is common enough that JSHint has a flag specifically designed for it.

Body:
It turns out that jQuery uses the construct

if (someObj == null) {
  // do something
}

extensively, as a shorthand for the equivalent code:

if ((someObj === undefined) || (someObj === null))  {
  // do something
}

This is a consequence of the ECMAScript Language Specification § 11.9.3, The Abstract Equality Comparison Algorithm, which states, among other things, that

1.  If Type(x) is the same as Type(y), then
    a.  If Type(x) is Undefined, return true.
    b.  If Type(x) is Null, return true.

and

2.  If x is null and y is undefined, return true.
3.  If x is undefined and y is null, return true.

This particular technique is common enough that JSHint has a flag specifically designed for it.


问:
Working with legacy code - introducing an external BDD integration test harness
Here's the scenario.

There's a large, organically grown application written in some language and manner that makes it difficult to test.  It works but is hard to maintain.

Specifications are woolly, so even if the code was amenable, it's hard to know what things should be doing without doing them.

You want to get it into a test harness so you can start to refactor and create proper unit tests.

In these cases it makes sense to build an external or superficial 'test everything' harness so you can start more aggressive refactoring to enable you to write proper unit tests.  This seems a pretty established practice of incrementally introducing tests.

"The main thing that distinguishes legacy code from non-legacy code is a lack of
comprehensive tests." - Michael C. Feathers (Working Effectively with Legacy Code)

My question is this:

Does it make sense to build a suite of Behaviour Driven tests at this point and execute them via some kind of automated button clicker?  I'm thinking something like (but not limited to) cucumber or similar where the human readable tests match executable code/scripts that prove the defined behaviour is being met.

A clear advantage of this is that a human readable specification of sorts could be developed alongside the tests and that these specifications are much easier to confirm as sane and correct with users/developers of the system.  They are essentially integration tests but perform the function that Feathers recommends.

eta: I'm not asking for a specific tool recommendation, the actual tool is irrelevant (although it would be helpful to know if they actually exist) I'm after a sanity check and recommendations around external BDD integration testing.

答:
It's perfectly possible to do this. I've written a blog with a few guidelines, but these additional ones might help you too:

Think about the capabilities of the system. For instance, an accounting system might have the ability to read bank feeds, raise invoices, email those invoices, etc.

Group the scenarios in terms of the capabilities. Look at what kind of contexts (the givens) produce what kinds of outcomes (the thens). Have some conversations with the business people about these, and pick up their language as far as possible. The capabilities themselves will drive what you write for the events (the whens).

For instance, you might find a couple of scenarios for raising invoices where it says something like:

Given an organisation to bill is outside the US

  When we send the invoice

  Then international bank details should be included.

Given an organisation to bill is within the US

  When we send the invoice

  Then it should include only US bank details.

These will then tie into the automation that does the more detailed steps that actually create organisations with different addresses in different countries, send the invoices, and verify that those invoices have been sent with the correct bank details. There will be far more automation steps than there will of these higher-level ones. This is commonly referred to as declarative vs. imperative language, and will help you to work out which scenarios are the most important to cover, and which are functionally equivalent.

Notice that the difference between the scenarios is called out fairly cleanly here, which it wouldn't be if there were multiple UI steps hiding that difference. The difference between the scenarios is what illustrates the behaviour.

You are likely to find bugs. It's up to you if you want to write scenarios around what the system should do. It's highly likely though that by now there are some human workarounds, so I wouldn't worry too much about this behaviour. If the application is in the wild and producing value, it's good. Make sure you get scenarios around the core capabilities written first.

Whenever you have to fix a bug, write some unit tests. This will force you to redesign your code. Regression bugs are usually caused by poor design, and adding yet more scenarios will just make the code harder to change rather than give you any more confidence in it. This is what Michael Feathers is primarily referring to here. See also the test pyramid. As your system is refactored, the number of unit tests and integration tests should be rapidly outstripping those at the UI level.

You can use the different capabilities of the system to guide you in finding the seams which Michael talks about in his book, which will help you to refactor.

Note that I don't use the word test very often. Business people will tend to talk more comfortably about the behaviour of the system when you talk about examples or scenarios in which things happen than when you talk about tests. This harks back to the origins of BDD.

Good luck!