问:
Does software reuse preclude process repeatability

Code Reuse as a Problem

I was thinking about this question on software delivery, and I kept coming back to the issue of repeatability and / or reproducibility.  They matter, because if you don’t repeat a project then it becomes more difficult to improve the process you used to build the project.  Engineering involves constantly improving the processes involved with design and construction in order to produce higher quality projects.

Software can rely heavily upon reuse due to its digital form.  Instead of rewriting a module, we just call it again or copy it to the other system.  Some examples are authentication / login or perhaps a logging function.  There are many well known examples for those categories, and conventional wisdom is to reuse what exists instead of rolling your own.

Some Comparisons to Other Disciplines

Construction

In contrast, construction of physical systems (buildings, bridges) is nowhere near as reusable.  It’s true that the blueprint of a house can be reused many times to build the same copy of the house, but the construction must be performed each time.  Cut & paste doesn’t work like that in the analog world.  Bridge blueprints are less reusable that houses because site conditions will vary.

Master builders are experts recognized for having designed and / or built tens, hundreds, or thousands of things in their area.  For example, Frank Lloyd Wright, a world renowned architect and designer designed more than 1,000 structures and completed 532 works.  Contrast that with Anders Hejlsberg who has designed “just” five languages (Turbo Pascal; Delphi; J++; C#; Typescript).  In many ways, it’s an unfair comparison because the domains are different.  But at a broad level, the quantifiable production from two very intelligent people is vastly different.

Martial Arts

Martial artists will say that mastery of a move comes only from thousands of repetitions. After a good portion of those repetitions have been put in, many martial artists are surprised at how a previously perceived to be complex kata or form has become simple. Instructors of those students will also notice how the motion becomes more fluid and purposeful as well as having an economy of motion. Likewise, experienced martial artists are able to pick up more complex katas more quickly than less experienced students. Experience from repetition has given them a framework or process that allows them to learn more quickly.

Woodworking

Woodworkers experience a similar transformation. Hobbyist woodworkers always refer back to their first project that required a lot of drawers. If they complete the project, they gain a new appreciation for the efficiencies that assembly lines produce. There are other benefits such as a better understanding of how to lay out the drawers parts on the sheet stock in order to maximize use of the wood. Compared to hobbyists, professional woodworkers are able to more quickly design, start, and construct items that they have made many times before. They also gain an ability to see inherent issues within someone else's design having made that mistake in their work.

So, does software reuse prevent software developers from becoming more proficient?

In many ways, software design and construction is always new.  We don’t repeat past works, because if we can reuse a module, library, or system then we do.  We’ll preferentially extend an existing system before rewriting the entire thing from scratch.  But repetition is what allows us to find efficiency in the design and the construction. Anyone who has practiced a sport or physical activity will tell you that repetition is the key to becoming a good practitioner.

My question: Does software’s ability to be reused prevent the necessary process improvement and efficiency that comes from repeating a project?

答:
Does software’s ability to be reused prevent the necessary process improvement and efficiency that comes from repeating a project?

I have worked as a systems and software engineer in the same large project for the past 17 years, incidentally (thinking of the Airbus A380 reference in your first link) in the aircraft industry, though my responsibilities lie in the military aircraft sector. Stories like that are basically pure fiction, and actually really funny to watch when you have insider insight.

But for your brief and concise question: From my experience, I would say both yes and no.

Let me first say that I am all for software recycling in all forms (well, maybe not all...). The advantages of reusing just about anything, from cut-and-paste code snippets and algorithms, to whole code modules and function libraries, is on the whole far better than to always start from the beginning again (to push it a little).

The downside is, as you point out (or at least infer), that when you add functionality by simply putting together a given set of components (and, yes, I am simplifying this to the extreme), you do not really evolve as a programmer, engineer or whatever.

Just looking at the software engineers around me at work, I know from long experience that a majority of them do not know, and worse - have no interest in learning, anything about the product we are constructing other than the bare minimum they need to produce the document or the piece of code that they are assigned to do.

I am reeling a bit off topic here, but my point is that when the programmers do not need to learn what the code they are constructing will really be used for, and do not need to learn the inner workings of the system since they can just reuse already written and tested components, then most of them just will not bother to do so.

Granted, this is also due to other circumstances, such as that the product we are constructing is incredibly complex, and it would be impossible for one person learn about all of it (and I am just talking about one of the computers in the aircraft - the most complex one of them, but still).

If our software engineers did not have the option to re-use as much code, I am convinced that they would become better at their profession generally, and much greater assets to the project specifically.

Oh, and you may have noticed that I talk about them a lot here. I am of course also included among these software engineers. The exception being that I seem to be a lot more inquisitive and eager to learn new things then the others :-) When faced with a new task, I always take it upon myself to learn as much about it that I can, both in the form of facts and by studying source code (yes, I actually enjoy that too).

Ah - dang, side-tracked again... My excuse is that I have not slept for 32 hours, so my focusing ability is a bit... what was I saying?

If anyone is still reading, my conclusion is that:

Yes, too much reuse of software makes for less knowledgeable software engineers, which makes them markedly less efficient when they actually need to know how the stuff works. Problem analysis is a good example, or even just being able to tell if a suggested design solution is viable. And of course, process improvement is also more difficult to achieve when you do not really know what you are doing :-)

and No, reusing software with care, potentially give you a lot of spare time to consider and plan process improvements.


问:
What roadblocks face the development process in using plain-text markup languages as opposed to, e.g., Microsoft Word?
I'm currently an intern at a government contractor and am getting the (obnoxiously unavoidable) feeling that Word is the de-facto standard in the software development process.

Its binary format makes it very difficult to collaborate on documents in the way I am used to collaborating on a code base.  The use of plain text markup (with such languages as LaTeX, Markdown, ReStructured Text, etc.) allows for a diff-friendly document that works well with the normal workflow of a developer.  As for comments where the language doesn't support them (eg Markdown), there are many existing solutions that allow collaborative comments on code bases (eg GitHub, Bitbucket) that could easily be applied to other plain-text files containing markup.

I understand the need to cooperate with technologically illiterate management necessitates some sort of graphical interface to everything, but such interfaces exist for most of these formats.  For example, LaTeX has a 'fork' of sorts called LyX that puts a graphical front-end to a plain-text, LaTeX-like syntax.  This file, even though primarily graphical in its editing, is still diff-friendly.  (It even also has Word-style comments.) Many of these solutions could yet be used instead of Word, and the vast majority are free or open-source.

However, we use Word even for our own internal documentation that nobody else sees.  We work with text for a significant chunk of our career---why is documentation so special?  Aside from the trivial "We didn't know any better and now we're stuck here", there must be reasons supporting such a decision.  What challenges face the software development process in using plain-text documentation in lieu of other, more colloquial (and debatably less powerful) means of writing documents?

Since the reasons will differ, perhaps answering for these two closely related scenarios separately should be in order.

Using plain-text documentation from the start

Migrating to plain-text documentation over time

答:
Lots of participants in the software development process are not developers, and need the ability to interact with documentation regardless. Should QA/Marketing use word and developers use something else completely? It would be inconsistent, it would add another tool into the maintenance chain and the IT portion of a company may have no idea what to do with the files, when they know completely well how to manage/maintain a word document store.

Above all else, many non-developers have spent years in university using Microsoft Word to turn in their work, frequently having had actual training classes in just how to use word. They know it far better than alternatives. I can hardly tell the difference when I'm working in Open Office vs Word, but when I had my sister in law use it to save money, a week later she had her husband buy her Word and proclaimed "Since I got word I love my new laptop!". Think about the mindset that conflates things like that, a slight change in what they're used to is not 'slight' to them.

Modern word allows version differences, annotations with version tracking and change merging as well. It may not be as straight forward as merging code is, but I've seen many project managers do it easily, so surely devs can manage to do it too.

Beyond that, it has become quite common amongst dev teams to do documentation in wikis because it does get back to the textual representation while staying simple enough that non-developers can make edits.

ContentLicense: CC BY-SA 3.0


问:
Good Practice : Storing variables and classes names in database for direct call
I would like to know if this is a good practice to store variables and classes names in database to use let users accessing them.

For instance users may create entries in database's table in which they can insert a program's function name that would executed when the program will read it.

I find it is a dangerous practice since users may execute or access any data of the program, but I've been told it's a quite common practice in languages with introspection like Python.

Moreover, i was also suggested to have field in a table that would store another table field's name, to create somehow a dynamic foreign key.

I personally find both practices very bad since in first case there is no more separation between user data and program data, and for the second case there is no separation between structure and data in the database.

Can you please confirm me these practices are discouraged or tell me I'm wrong and suggest me a way to approach them in a safer way.

Thank you.

答:
First I want to make sure.  You're storing names and classes, but not raw code, right?

The problem with code in the database is that databases do not have a well-developed toolset for commit/rollback/release/branching/etc like we have with files.  Furthermore keeping code+database in sync is an eternal source of potential problems.  90% of the time there is no issue, but that makes for a 10% source of completely unnecessary problems.

Having class names and function names in the database is very flexible.  The problem is that then nothing can be ever assumed to not be referenced from that database.  Which means that any potential refactorings are forever verboten.

Instead what I would recommend is that you store a very simple stupid "translation layer" (which mostly does no translation) that does nothing but sit in your code and map from class/function names in your code to corresponding ones in the database.  This adds no immediate functionality except to serve as documentation about what kinds of information are allowed to be stored in the database and (just as important) what is not.  This serves as internal documentation of your public API which will allow refactoring/cleanup to happen later.

In short, it allows you to pass the grep test: http://jamie-wong.com/2013/07/12/grep-test/


问:
Multiple Data Types for Single Variable in C
I am trying to implement basic cons, car and cdr of SCHEME in C. I have made a simple program that allows me to cons two integers as shown in the main program. However, I want my program to be able to cons a 'consed object' with a digit as well as cons a 'consed object' with another 'consed object' as shows below:

(cons 2 3)

(cons 2 (cons 2 3))

(cons (cons 2 3) (cons 2 3))

Since the limitation arises because the data in the struct is of type int, is it possible to have a variable accept multiple data types in C? If yes, how? If not, is there another way to deal with this issue?
Here is my code:

```<code>#include <stdio.h>
#include <string.h>

typedef struct cons_object {
int data;
struct node* next;
} cons_object;

cons_object* cons(int x, int y )
{
cons_object* car = NULL;
cons_object* cdr = NULL;
car = malloc(sizeof(struct cons_object));
cdr = malloc(sizeof(struct cons_object));
car->data = x;
car->next = cdr;
cdr->data = y;
cdr->next = NULL;
return car; /*returns the pointer car*/
}

int car(cons_object* list) /*takes in a consed object*/
{
cons_object* car = list;
int y;
y = car->data;
return y;
}

int cdr(cons_object* list)
{
cons_object* cdr = list;
cdr = cdr->next;
int z;
z= cdr->data;
return z;

}

int main ()
{
int y = car (cons(33,42));
printf("%d\n",y);
int z = cdr (cons(3,4));
printf("%d\n",z);
return 0;

}
</code>```

答:
Further to ratchet freak's comment, look up discriminated union, or tagged union.

You can make your data type a void *, but you also need to track what it really points to. That is, at some point you need to figure out if it's an integer or a double or another list.

The tagged union itself might look something like this:

#include <stdlib.h>
#include <assert.h>

enum TypeTag { NoType, CharType, IntType, DoubleType, ConsType };
union Value {
    char c;
    int i;
    double d;
    void *p;
};
struct TaggedType {
    enum TypeTag type;
    union Value value;
};
```

<p>and the cons code can use it - without worrying about what type is really inside the <code>TaggedType</code> structure - like this:</p>

<pre class="lang-c prettyprint-override"><code>struct ConsNode {
    struct TaggedType value;
    struct ConsNode *next;
};

struct ConsNode *cons(struct TaggedType value, struct ConsNode *next) {
    struct ConsNode *head = malloc(sizeof *head);
    head->value = value;
    head->next = next;
    return head;
}
struct TaggedType *car(struct ConsNode *head) {
    return &head->value;
}
struct ConsNode *cdr(struct ConsNode *head) {
    return head->next;
}
</code>```

Then all you need is the boxing/unboxing code to work with actual concrete types:

struct TaggedType mkint(int i) {
    struct TaggedType value = { IntType, {.i=i} };
    return value;
}
struct TaggedType mkdbl(double d) {
    struct TaggedType value = { DoubleType, {.d=d} };
    return value;
}

int toint(struct TaggedType *data) {
    assert(data->type == IntType);
    return data->value.i;
}
double todbl(struct TaggedType *data) {
    assert(data->type == DoubleType);
    return data->value.d;
}

int main () {
    struct ConsNode *list = cons(mkint(33), cons(mkint(42), NULL));
    int y = toint(car(list));
    assert(y == 33);
    assert(toint(car(cdr(list))) == 42);
    return y;
}
```

Note that most list operations don't know or care about the type stored in each node - this only becomes important where you do something with it.

Body:
Further to ratchet freak's comment, look up discriminated union, or tagged union.

You can make your data type a void *, but you also need to track what it really points to. That is, at some point you need to figure out if it's an integer or a double or another list.

The tagged union itself might look something like this:

#include <stdlib.h>
#include <assert.h>

enum TypeTag { NoType, CharType, IntType, DoubleType, ConsType };
union Value {
    char c;
    int i;
    double d;
    void *p;
};
struct TaggedType {
    enum TypeTag type;
    union Value value;
};

and the cons code can use it - without worrying about what type is really inside the TaggedType structure - like this:

struct ConsNode {
    struct TaggedType value;
    struct ConsNode *next;
};

struct ConsNode *cons(struct TaggedType value, struct ConsNode *next) {
    struct ConsNode *head = malloc(sizeof *head);
    head->value = value;
    head->next = next;
    return head;
}
struct TaggedType *car(struct ConsNode *head) {
    return &head->value;
}
struct ConsNode *cdr(struct ConsNode *head) {
    return head->next;
}

Then all you need is the boxing/unboxing code to work with actual concrete types:

struct TaggedType mkint(int i) {
    struct TaggedType value = { IntType, {.i=i} };
    return value;
}
struct TaggedType mkdbl(double d) {
    struct TaggedType value = { DoubleType, {.d=d} };
    return value;
}

int toint(struct TaggedType *data) {
    assert(data->type == IntType);
    return data->value.i;
}
double todbl(struct TaggedType *data) {
    assert(data->type == DoubleType);
    return data->value.d;
}

int main () {
    struct ConsNode *list = cons(mkint(33), cons(mkint(42), NULL));
    int y = toint(car(list));
    assert(y == 33);
    assert(toint(car(cdr(list))) == 42);
    return y;
}

Note that most list operations don't know or care about the type stored in each node - this only becomes important where you do something with it.


问:
Why Aren't Rule Engines Written In Prolog?
From what I've seen of Prolog, it seems as if it would be ideal for crafting a rule engine for an app.  Yet, I don't believe I've ever seen a rule engine written in Prolog.  Is there some inherent limitation in Prolog (e. g. poor garbage collection algorithm) that would prevent it from being used to build a rule engine? </p>

答:
Rules engines in their infancy were written almost exclusively in Prolog--it was the logical language.  For a small set of rules they worked great.  However, it turned out they didn't scale very well.  I don't have a definitive reference, but my understanding is that the way Prolog handles the chaining of rules is inefficient--the recursive model made for creating very large stacks that brought it to a crawl.

The development of the RETE algorithm and its successors allowed for a more efficient way to process large quantities of rules, and so took over.

Perhaps modern prolog would be more efficient than back in the 80's, when most of the early work was done.


问:
Factory-Class versus Static Class
I've got a little problem in choosing the best design.
I have some (5 at the moment) image processing operations in my coe (Java). Every processing step independent from the other ones and consoists of a small amount of code, 5-15 lines in general. These are mostly wrappers to JAI, AWT and so on.

My current design is an abstract class:

```<code>public abstract class AbstractPreProcessingStep {
    protected Logger logger = Logger.getLogger(this.getClass().getName());

    protected AbstractPreProcessingStep() {
    };

    public abstract BufferedImage startProcessing(BufferedImage input);

}
</code>```

Every processing step implements this class and can be called uniform. (like the Strategy-Pattern).

Since every processing step may have a different set of parameters, I created a factory class, like this:

```<code>public class PreProcessingFactory {

    public static AbstractPreProcessingStep createColorInverter() {
        return new ColorInverter();
    }

    public static AbstractPreProcessingStep createRescaler(float rescaleFactor) {
        return new Rescaler(rescaleFactor);
    }

    public static AbstractPreProcessingStep createEdgeDetector() {
        return new EdgeDetector();
    }

    public static AbstractPreProcessingStep createBlackAndWhite() {
        return new BlackAndWhite();
    }
...
</code>```

So, if you want to create a black and white image with inverted colors, you need to do this (pseude code)

```<code>bw = PreProcessingFactory.createBlackAndWhite();
inv = PreProcessingFactory.createInverter();
result = bw.startProcessing(result);
result = inv.startProcessing(result);
</code>```

In my mind, this is a good design since the implementation details are hidden and new processing steps can easily be add by adding a new class.

The other approach which was in my mind was to create a single class with every step as a static method - however, I've got dislike of 'static'

Do you have any suggestions to improve the code?

答:
I'll make the following assumptions about your process:

One step does not need to know about the inner workings of another step.

Order of these steps is significant (you don't obtain the same results performing these operations in the opposite order).

In this situation, I can only really tell you what I would do.  I would avoid Factory pattern, simply because it implies you must have a factory method for every type of phase, and if you wanted to invent new stages, you'd also have to modify the factory as well.  Plus while it may be manageable in bite-sized pieces, if you had to deal with 50 phases, even if it didn't change often, it would still be very messy.  Not to mention that factory would seem to imply that order is irrelevant.  It makes you think that you can make any number of AbstractPreProcessingSteps and apply them in however order you wish.  Even if that is not the case, I think it is generally better to present an interface which does not mislead a programmer.

Consider the following alternative pattern:  Chain of responsibility

Suppose you had class AbstractProcessor as such:

```<code>public abstract class AbstractProcessor {
    protected AbstractProcessor step;

    public void setNextStep(AbstractProcessor step) {
        this.step = step;
    }

    public abstract BufferedImage process(BufferedImage input);
}
</code>```

Then you could have your steps as such:

```<code>public class ColorInverter extends AbstractProcessor {
    public ColorInverter(AbstractProcessor step) {
        setNextStep(step);
    }

    public BufferedImage process(BufferedImage input) {
        // Perform color inverter process here
        return step != null ? step.process(output) : output;
    }
}
public class Rescaler extends AbstractProcessor {
    public Rescaler(AbstractProcessor step) {
        setNextStep(step);
    }

    public BufferedImage process(BufferedImage input) {
        // Perform rescalar process here
        return step != null ? step.process(output) : output;
    }
}
</code>```

Just like this, it is beautiful in its simplicity, however, you could override ordering for steps which must be performed at the end simply by calling "step.process(input)" and performing some operation on the returned result.

Also, if there were specific phases, you could override AbstractProcessor's setNextStep to require a certain type of AbstractProcessor to guarantee that certain phases are achieved.  Take for example the following:

```<code>public abstract class RasteringProcessingStep extends AbstractProcessor {
    public void setNextStep(RasteringProcessingStep step) {
        super.setNextStep(step);
    }
    public void setNextStep(PostProcessingStep step) {
        super.setNextStep(step);
    }
}
</code>```

In this way, you ensure that any step implementing RasteringProcessingStep must either be followed by another RasteringProcessingStep or it must be followed by a PostProcessingStep which also derives from AbstractPreProcessingStep.

To use it, you would see something like:

```<code>AbstractProcessor processor = new ColorInverter(new Rescaler(null));
File image = new File("strawberry.jpg");
BufferedImage output = processor.process(ImageIO.read(image));
</code>```

Please let me know what you think about this approach.

Title: Factory-Class versus Static Class

Body:
I'll make the following assumptions about your process:

One step does not need to know about the inner workings of another step.

Order of these steps is significant (you don't obtain the same results performing these operations in the opposite order).

In this situation, I can only really tell you what I would do.  I would avoid Factory pattern, simply because it implies you must have a factory method for every type of phase, and if you wanted to invent new stages, you'd also have to modify the factory as well.  Plus while it may be manageable in bite-sized pieces, if you had to deal with 50 phases, even if it didn't change often, it would still be very messy.  Not to mention that factory would seem to imply that order is irrelevant.  It makes you think that you can make any number of AbstractPreProcessingSteps and apply them in however order you wish.  Even if that is not the case, I think it is generally better to present an interface which does not mislead a programmer.

Consider the following alternative pattern:  Chain of responsibility

Suppose you had class AbstractProcessor as such:

public abstract class AbstractProcessor {
    protected AbstractProcessor step;

    public void setNextStep(AbstractProcessor step) {
        this.step = step;
    }

    public abstract BufferedImage process(BufferedImage input);
}

Then you could have your steps as such:

public class ColorInverter extends AbstractProcessor {
    public ColorInverter(AbstractProcessor step) {
        setNextStep(step);
    }

    public BufferedImage process(BufferedImage input) {
        // Perform color inverter process here
        return step != null ? step.process(output) : output;
    }
}
public class Rescaler extends AbstractProcessor {
    public Rescaler(AbstractProcessor step) {
        setNextStep(step);
    }

    public BufferedImage process(BufferedImage input) {
        // Perform rescalar process here
        return step != null ? step.process(output) : output;
    }
}

Just like this, it is beautiful in its simplicity, however, you could override ordering for steps which must be performed at the end simply by calling "step.process(input)" and performing some operation on the returned result.

Also, if there were specific phases, you could override AbstractProcessor's setNextStep to require a certain type of AbstractProcessor to guarantee that certain phases are achieved.  Take for example the following:

public abstract class RasteringProcessingStep extends AbstractProcessor {
    public void setNextStep(RasteringProcessingStep step) {
        super.setNextStep(step);
    }
    public void setNextStep(PostProcessingStep step) {
        super.setNextStep(step);
    }
}

In this way, you ensure that any step implementing RasteringProcessingStep must either be followed by another RasteringProcessingStep or it must be followed by a PostProcessingStep which also derives from AbstractPreProcessingStep.

To use it, you would see something like:

AbstractProcessor processor = new ColorInverter(new Rescaler(null));
File image = new File("strawberry.jpg");
BufferedImage output = processor.process(ImageIO.read(image));

Please let me know what you think about this approach.


问:
Preventing Web Site Users From Using Their Back Button To Get To Cached Screens After Logging Out?
I have a legacy Java webapp ( Spring 3.1 MVC, legacy servlest and JSPs ) I have modified to log the user out after s/he clicks an external link to leave the web site.

The last screen(s) s/he was on are getting cached in the browser, enabling them to see some data by hitting their back button.

I could put no-cache headers into those screens, and it works, but the site was poorly designed with multipage forms, some with one result screen doing post requests to get to another screen.

If those screens aren't cached, a user hitting his/her back button will find themselves on a blank page going backwards and forwards leaving him/her nowhere with no other choice except to login again.   A bigger mess.

Short of redesigning a site is there anything else I can do to prevent the user from using his/her back button, after logging out to get to cached screens?

I tried having the user go to a static redirect screen after logging out in the hope that s/he would just get bounced back to the external URL when using their back button, but at least two browsers don't appear to cache or navigate to such pages.

Any ideas would be welcome.

I am able to use javascript as well as server side code.

Even if I can't solve this problem, I may learn something for the future

Thanks

Steve

答:
So the page isn't cached but the user still has a history of pages they can "back" button to which just turns up blank pages? I assume if the user makes any request to the server it will redirect them to a log-in page.

It might be easiest rather than refusing to cache pages, to allow caching but a) to really ensure your forms cannot be resubmitted when they have been submitted once and b) to use a Javascript check against the cookies in the browser when the page is loaded, to ensure that they have a current session.

If you wanted to be fancy, you could use a bit of ajax to check the session Id with the server ( assuming you haven't just timed the session out when they left the page ) but you might also be able to set a "logged-out" cookie when you are unsetting the session and just check for that value.

You can also use Javascript to interact with the browser history as well, but this is a little bit newfangled- MDN has the lowdown. I wouldn't like to say whether you could do anything to adjust the browser history on logout so the user can be sent back to somewhere more friendly, but it may be worth looking into.


问:
XML/HTML: Do we need the element name in closing tags?
Compared to other serialization languages, one of the main criticisms directed at XML is its verbosity; JSON's more terse and readable for most cases, but not all.

But it seems to me that we could cut a lot of the excess from XML simply by stripping away the names from the closing tags. With proper indentation readability shouldn't be an issue (it should be an improvement, if you ask me), and since they're not structurally required any decent XML editor/viewer could easily be made to strip/hide or add them. As such, the two formats should be completely equivalent and interchangeable.

Compare the following (source taken from http://www.w3schools.com/xml/simple.xml):

```<code><breakfast_menu>
    <food>
        <name>Belgian Waffles</name>
        <price>$5.95</price>
        <description>
                    Two of our famous Belgian Waffles with plenty of real maple syrup
        </description>
        <calories>650</calories>
    </food>
    <food>
        <name>Strawberry Belgian Waffles</name>
        <price>$7.95</price>
        <description>
                    Light Belgian waffles covered with strawberries and whipped cream
        </description>
        <calories>900</calories>
    </food>
    <food>
        <name>Berry-Berry Belgian Waffles</name>
        <price>$8.95</price>
        <description>
                    Light Belgian waffles covered with an assortment of fresh berries and whipped cream
        </description>
        <calories>900</calories>
    </food>
    <food>
        <name>French Toast</name>
        <price>$4.50</price>
        <description>
                    Thick slices made from our homemade sourdough bread
        </description>
        <calories>600</calories>
    </food>
    <food>
        <name>Homestyle Breakfast</name>
        <price>$6.95</price>
        <description>
                    Two eggs, bacon or sausage, toast, and our ever-popular hash browns
        </description>
        <calories>950</calories>
    </food>
</breakfast_menu>
</code>```

and

```<code><breakfast_menu>
    <food>
        <name>Belgian Waffles</>
        <price>$5.95</>
        <description>
                        Two of our famous Belgian Waffles with plenty of real maple syrup
        </>
        <calories>650</>
    </>
    <food>
        <name>Strawberry Belgian Waffles</>
        <price>$7.95</>
        <description>
                        Light Belgian waffles covered with strawberries and whipped cream
        </>
        <calories>900</>
    </>
    <food>
        <name>Berry-Berry Belgian Waffles</>
        <price>$8.95</>
        <description>
                        Light Belgian waffles covered with an assortment of fresh berries and whipped cream
        </>
        <calories>900</>
    </>
    <food>
        <name>French Toast</>
        <price>$4.50</>
        <description>
                        Thick slices made from our homemade sourdough bread
        </>
        <calories>600</>
    </>
    <food>
        <name>Homestyle Breakfast</>
        <price>$6.95</>
        <description>
                        Two eggs, bacon or sausage, toast, and our ever-popular hash browns
        </>
        <calories>950</>
    </>
</>
</code>```

答:
I fail to see the big gain with the </> variant. Are you talking about readability for the human eye? In that case I would take ordinary XML any day rather than trying to figure out what the code is trying to tell me when I see something like this in the middle of a file:

```<code>    ...
    </></></></></></></>
    <something>
    ...
</code>```

An XML file is a data container. Just because you can read and edit it by hand in a text editor does not necessarily mean that it is a good idea to do so. It is primarily meant to convey data from one application to another (or, yes, to just store data).

So maybe you mean the actual file size? Well, if that is so important, then you are probably not using the most suitable file format anyway.

But a more important reason for keeping XML as it is, is that when there is a structural error in a real XML file, the tag/end-tag design of XML makes it very easy for a parser to determine where the problem lies, and thereby to determine if the rest of the file can still be used.

If there is an end tag missing in your </> variant, it is much more difficult for the parser find the cause of the problem. And if you do not have a good DTD, then the parser will not even see that anything is wrong until it reaches the end of the file and (hopefully) detects that there is a level imbalance. And at that point there is nothing to do but to reject the whole file since there is no way of telling where the error is.

Body:
I fail to see the big gain with the </> variant. Are you talking about readability for the human eye? In that case I would take ordinary XML any day rather than trying to figure out what the code is trying to tell me when I see something like this in the middle of a file:

    ...
    </></></></></></></>
    <something>
    ...

An XML file is a data container. Just because you can read and edit it by hand in a text editor does not necessarily mean that it is a good idea to do so. It is primarily meant to convey data from one application to another (or, yes, to just store data).

So maybe you mean the actual file size? Well, if that is so important, then you are probably not using the most suitable file format anyway.

But a more important reason for keeping XML as it is, is that when there is a structural error in a real XML file, the tag/end-tag design of XML makes it very easy for a parser to determine where the problem lies, and thereby to determine if the rest of the file can still be used.

If there is an end tag missing in your </> variant, it is much more difficult for the parser find the cause of the problem. And if you do not have a good DTD, then the parser will not even see that anything is wrong until it reaches the end of the file and (hopefully) detects that there is a level imbalance. And at that point there is nothing to do but to reject the whole file since there is no way of telling where the error is.


答:
You are consufing terms.

The problem is not Factory Class vs Static Class, but a method for each process vs a class for each process.

The "a class for each process" method that you seem to be considering has many advantages, mainly flexibility and scalability.

But in order to implement that, you will have to use some kind of Creational Pattern to help you keep your code decoupled from the concrete classes.

The Factory class approach you are using is OK.

The order or the way you call those processes is a matter of Behavioral Patterns like Chain of Responsability, Iterator, State, Command etc. These behavioral patterns are used for decoupling the requestor ( the class that needs to call a process ) from the concrete class that actually does the work.

Title: Factory-Class versus Static Class

Body:
I've got a little problem in choosing the best design.
I have some (5 at the moment) image processing operations in my coe (Java). Every processing step independent from the other ones and consoists of a small amount of code, 5-15 lines in general. These are mostly wrappers to JAI, AWT and so on.

My current design is an abstract class:

```<code>public abstract class AbstractPreProcessingStep {
    protected Logger logger = Logger.getLogger(this.getClass().getName());

    protected AbstractPreProcessingStep() {
    };

    public abstract BufferedImage startProcessing(BufferedImage input);

}
</code>```

Every processing step implements this class and can be called uniform. (like the Strategy-Pattern).

Since every processing step may have a different set of parameters, I created a factory class, like this:

```<code>public class PreProcessingFactory {

    public static AbstractPreProcessingStep createColorInverter() {
        return new ColorInverter();
    }

    public static AbstractPreProcessingStep createRescaler(float rescaleFactor) {
        return new Rescaler(rescaleFactor);
    }

    public static AbstractPreProcessingStep createEdgeDetector() {
        return new EdgeDetector();
    }

    public static AbstractPreProcessingStep createBlackAndWhite() {
        return new BlackAndWhite();
    }
...
</code>```

So, if you want to create a black and white image with inverted colors, you need to do this (pseude code)

```<code>bw = PreProcessingFactory.createBlackAndWhite();
inv = PreProcessingFactory.createInverter();
result = bw.startProcessing(result);
result = inv.startProcessing(result);
</code>```

In my mind, this is a good design since the implementation details are hidden and new processing steps can easily be add by adding a new class.

The other approach which was in my mind was to create a single class with every step as a static method - however, I've got dislike of 'static'

Do you have any suggestions to improve the code?


问:
Real time data feed, what requirements would I need to gather from the client's system interface?
How do I go about designing this particular application example below?

For example:

I have client, who would like to embed my data feed into this GUI interface. The data is made of names and and descriptions fields.  If a user comes along and searches a particular name of a products using the client's interface, then the name parameter will be passed down my data feed, and it will return a search for that query name, back to the clients interface, from my database.

I assume the my real-time data feed will be constructed as an API service.

What requirements would I need to gather from the client's system interface?

Would I need to ask them for the list of parameters they require to query through my data feed?

答:
Would I need to ask them for the list of parameters they require to query through my data feed?

In a way: yes.

But are probably two ways you can achieve this:

You ask them what they want to query on;

You tell them what they can query on;

With the former this can lead to opening a huge can of worms, where your client will want to query on EVERYTHING with no constraints at all. If this approach is agreed upon, be prepared to say No when necessary and use common sense where relevant. If a parameter offers no value to search on, don't agree to provide it as a searchable field.

With the latter you tell your client that all you provide to query on are parameters A, B, C. If they want more, i.e. customisation, then charge a few extra $$$

I suspect that you will come to some sort of common ground between your client asking for parameters and your decision to see that it adds value to use a field as a parameter.

Lastly, although the YANGI guys might saw something about this, will this be the only customer you have for your data? If you have 10 customers, do you really want to have 10 different custom search parameter criteria, that can take some time to program and configure for each customer? Or would you want to have a single set of possible search parameters that all customers use?


问:
Alternatives to Traditional Password Authentication
The third party login is excellent function that has come in recent years that relieves the load on a programmers mind so that I have to remember less useless passwords.

I don't use the same password for many sites, I use an algorithm: for instance if I make a password for StackOverflow its name starts with S so I'll put in an S and then with my secret sentence so the password for SO will be something like i81b4uS, e.g. my secret phrase plus some token that makes the password not the same for every since since I don't want the disaster if some site saves my password in plaintext and gets hacked (then somebody would have access to all my online material if I used the same password).

Biological metrics are good but this technology is not here. In the future we will probably only have to unlock at one point all our online material, instead of providing the system so many locks. Google's 2-step verification is flexible and goo but it's not perfect.

Are there other, perhaps newer, or less known, authentication methods for instance that simplifies the common use-cases of renewing a password (where it is often tedious to check your mail where you often get interrupted, and providing the old password to change it to a new etc) and reset password, which is a lot like renew a password?

I'm not asking for the detail of which algorithm, but rather if there are newer and more effective flows, like third party login which made me start an account at SO where I landed with me Google account, that puts less of a burden on the user's mind and manual memory and that are also safe?

At my site I offer authentication much like SO and SE, where you can login at my site just like SO with Google, FB, Linkedin, Yahoo or custom accounts. I've used webapp2's user model to facilitate my logins and the simpleauth library for GAE (python).

What would especially be good would be getting rid of email altogether and not bugging users about their email address at all. Some users are hesitant to leave their email, and email is often too much of a direct contact. So many users have smart-phones and androids so that there could be one app for many sites that does the authentication via smart-phone or a desktop app or a large third-party like Google, FB or Yahoo where I can offer Google, FB, Yahoo, LinkedIn so that a user can have a choice not to make up a new password, since that can be painful if you already have memorized 40 passwords for different sites and services.

答:
Mozilla Persona, that seem to be really great. I didn't have the opportunity to test it yet, but I saw some demos and it sure looks cool.

The coolest part is that it's decentralized.

"At Mozilla, we believe that your online identity should belong exclusively to you. With that in mind, we created Persona to improve the way you sign in to websites.

Persona allows you to sign in to sites using an email address you choose. So, instead of having to manage multiple usernames and passwords across your favorite sites and devices, you’ll have more time to do the important stuff. We’ll manage the details!"

http://www.mozilla.org/en-US/persona/

Sorry per my poor english.


问:
Git-friendly spreadsheet format?
We're trying to move our project documentation process from Google Documents to a set of self-hosted Git repositories.

Text documents are Git-friendly enough, since we usually do not need any fancy formatting, we'll just convert everything to, say, multimarkdown with an option to embed LaTeX for complex cases.

But spreadsheets are quite different story... Is there a spreadsheed(-like) format that is friendly to version control systems (and, preferably, is as human-readable as Markdown)?

"Friendly format": Git works well with the format (it doesn't with XML) and it generates human-readable diffs (extra configuration involving external tools is OK).

Obviously, Markdown flavors allow one to build static tables, but I'd like to be able to use stuff like SUM() etc... (Note that CSV has the same problem.) No WYSIWYG is OK, but decent editor/tool support would be nice.

Update: Linux-friendly answers only, please. No MS Office stuff.

答: This may not fit your needs, but may fit another's.  Org-mode for Emacs includes table.el, which, along with Org-mode's particular enhancements, provides an extremely robust solution for spreadsheets, all in plain text.  More information (much more than the scope of this site) is available at Org-mode's website and manual, particularly its spreadsheet tutorial.

Title: Git-friendly spreadsheet format?


问:
Is there real value in a portable language targeting very different runtimes?
Another question over on SO introduced me to Oxygene, formerly Chrome before the browser of the same name came to prominence. It's in the Pascal syntax family, but brings in a lot of object-oriented grammar and elements from the C family, notably Java/C#. One of its big advertised strengths is that the language is implemented as runtime-independent; programs written in Oxygene can target .NET, J2EE, Android, or Cocoa, making it a memory-managed language almost as portable as C/C++ is in unmanaged-land.

However, my question is whether that kind of independence is really useful, given that the frameworks and environments it targets are so different (and incompatible). There are a host of problems inherent in writing one program that can be compiled as-is to target all three of these runtimes, and a common language is only the tip of the iceberg. Java doesn't have a System.Windows.Forms namespace; it has java.swing, and the classes underneath are totally different. Similarly, Java's database interop is via JDBC, while .NET has the ADO.NET sub-framework. While having a common language is nice, being fluent in a "language" is as much (more, IMO) about being fluent in the targeted libraries as it is with the syntax of the language.

Does anyone have a common example of where runtime-independent languages have been leveraged to create truly portable programs across all supported runtimes?

答:
I'm not familiar with Oxygene but from time I spent looking into Fantom and similar other languages that do what you're referring to, what I found was that they weren't as you're suggesting requiring you to know the different libraries.

The killer functionality they have is a single library that translates to the independent separate ones; so you write code against the Fantom library using their UI functions, and it will translate it to Swing or WinForms depending on whether you compile it to .NET or Java. In this way you don't need to know anything about either the .NET or Java libraries, you know one library and it will handle the translation for you on those standard things like DB access, GUI, networking, et al.


答:
You're assuming the language is designed to be able to compile the exact same program as-is for different platforms.  That doesn't appear to be the case.  It's portable in the same way as C and C++ are portable.  Your core language is the same on all platforms, but you target the native runtime environments.  In other words, the language is cross platform, not the application.

Even for cross platform applications, maintaining different sets of platform-specific code is fairly common.  Even if you can't reuse the platform-specific code, using the same language allows a lot of code reuse, if you structure your application properly.

For example, I maintain a program for both Java/Swing and Java/Android, for which 75% of the code is reused between platforms, even though both apps are completely native.  That's not as nice as 100%, but it sure beats the 0% of common code I would get if I ported to Objective C/iOS.

Title: Is there real value in a portable language targeting very different runtimes?

Body:
Another question over on SO introduced me to Oxygene, formerly Chrome before the browser of the same name came to prominence. It's in the Pascal syntax family, but brings in a lot of object-oriented grammar and elements from the C family, notably Java/C#. One of its big advertised strengths is that the language is implemented as runtime-independent; programs written in Oxygene can target .NET, J2EE, Android, or Cocoa, making it a memory-managed language almost as portable as C/C++ is in unmanaged-land.

However, my question is whether that kind of independence is really useful, given that the frameworks and environments it targets are so different (and incompatible). There are a host of problems inherent in writing one program that can be compiled as-is to target all three of these runtimes, and a common language is only the tip of the iceberg. Java doesn't have a System.Windows.Forms namespace; it has java.swing, and the classes underneath are totally different. Similarly, Java's database interop is via JDBC, while .NET has the ADO.NET sub-framework. While having a common language is nice, being fluent in a "language" is as much (more, IMO) about being fluent in the targeted libraries as it is with the syntax of the language.

Does anyone have a common example of where runtime-independent languages have been leveraged to create truly portable programs across all supported runtimes?


问:
Will high reputation in Stack Overflow help to get a good job?
In a post, Joel Spolsky mentioned that 5 digit Stack Overflow reputation can help you to earn a job paying $100k+. How much of that is real?

Would anyone like to share their success in getting a high paid job by virtue of their reputations on Stack Exchange sites?

I read somewhere that, a person got an interview offer from Google because a recruiter found his Stack Overflow reputation to be impressive. Anyone else with similar stories?

答: When I start my own company in the next 1-2 years, high reputation score in stackoverflow will be the 1st criteria for me to hire developers. I hope when that time comes, stackoverflow still serving the humanity.</p>

ContentLicense: CC BY-SA 2.5


答:
Any checks on the user side cannot replace checks on the server. If your server can suffer from request with obsolete data (logged off user, or something like that), doing tricks with user's browser history is not a solution to the problem, but only dust in the eyes.

Also, user can save page and load it later from file. Some browsers and/or extensions even allow to save non-static content (generated by JavaScript after page load).

Title: Preventing Web Site Users From Using Their Back Button To Get To Cached Screens After Logging Out?

Body:
I have a legacy Java webapp ( Spring 3.1 MVC, legacy servlest and JSPs ) I have modified to log the user out after s/he clicks an external link to leave the web site.

The last screen(s) s/he was on are getting cached in the browser, enabling them to see some data by hitting their back button.

I could put no-cache headers into those screens, and it works, but the site was poorly designed with multipage forms, some with one result screen doing post requests to get to another screen.

If those screens aren't cached, a user hitting his/her back button will find themselves on a blank page going backwards and forwards leaving him/her nowhere with no other choice except to login again.   A bigger mess.

Short of redesigning a site is there anything else I can do to prevent the user from using his/her back button, after logging out to get to cached screens?

I tried having the user go to a static redirect screen after logging out in the hope that s/he would just get bounced back to the external URL when using their back button, but at least two browsers don't appear to cache or navigate to such pages.

Any ideas would be welcome.

I am able to use javascript as well as server side code.

Even if I can't solve this problem, I may learn something for the future

Thanks

Steve


答:
Have you considered a Password Manager (e.g. - KeePass, 1Password, etc.)?
There are many available, and they have been around for a while, well-developed, and analyzed.

They are based on some very sophisticated algorithms and incorporate various encryption techniques.

For example, I use KeePass, which is free and can be run off a USB drive.
It uses a pass phrase to log in, instead of a single word, if desired.
The database can be saved elsewhere for added security if desired.
When you would like to generate a new password for a specific site, the software offers that feature; you tell it how many characters and what kind (i.e. - upper case letters, lower case letters, numbers, special characters, etc.). It then creates the password and saves it. To enter it in the site log in field, right-click on the entry and you have 12 seconds to enter it in the password field before the Clipboard is automatically cleared.

Of course, if you ever forget your pass phrase, you are out of luck. But I find it a real convenient way of organizing all my passwords and generating some real long ugly ones for good security.

Title: Alternatives to Traditional Password Authentication

Body:
The third party login is excellent function that has come in recent years that relieves the load on a programmers mind so that I have to remember less useless passwords.

I don't use the same password for many sites, I use an algorithm: for instance if I make a password for StackOverflow its name starts with S so I'll put in an S and then with my secret sentence so the password for SO will be something like i81b4uS, e.g. my secret phrase plus some token that makes the password not the same for every since since I don't want the disaster if some site saves my password in plaintext and gets hacked (then somebody would have access to all my online material if I used the same password).

Biological metrics are good but this technology is not here. In the future we will probably only have to unlock at one point all our online material, instead of providing the system so many locks. Google's 2-step verification is flexible and goo but it's not perfect.

Are there other, perhaps newer, or less known, authentication methods for instance that simplifies the common use-cases of renewing a password (where it is often tedious to check your mail where you often get interrupted, and providing the old password to change it to a new etc) and reset password, which is a lot like renew a password?

I'm not asking for the detail of which algorithm, but rather if there are newer and more effective flows, like third party login which made me start an account at SO where I landed with me Google account, that puts less of a burden on the user's mind and manual memory and that are also safe?

At my site I offer authentication much like SO and SE, where you can login at my site just like SO with Google, FB, Linkedin, Yahoo or custom accounts. I've used webapp2's user model to facilitate my logins and the simpleauth library for GAE (python).

What would especially be good would be getting rid of email altogether and not bugging users about their email address at all. Some users are hesitant to leave their email, and email is often too much of a direct contact. So many users have smart-phones and androids so that there could be one app for many sites that does the authentication via smart-phone or a desktop app or a large third-party like Google, FB or Yahoo where I can offer Google, FB, Yahoo, LinkedIn so that a user can have a choice not to make up a new password, since that can be painful if you already have memorized 40 passwords for different sites and services.


问:
Is node.js a good fit for background processing?
I'm slowly learning node.js and have a small project I want to start.  The project will have a lot of background processes (downloading data from external sites, parsing CSV files, etc.).

A big "win" for me and node is the fact it uses JavaScript for both client and server.  I code in Java and JavaScript in my day job but am also pretty good at Ruby.

But, like I said, it seems attractive to use one language everywhere and JS seems to fit that bill.

However, I haven't had much experience in using JS for running background jobs.  Ruby seems to excel at this.  And I'm not opposed to using it.  So what are your thoughts on going 100% JS for this?  I realize very large projects require custom solutions.  I'm just wondering if it's worth the effort.  Or, should I just stick with Ruby on those kind of chores?

Opinions appreciated.

Thanks

答:
It's particularly strong at handling a ton of file I/O and I would expect it to handle a ton of network communication well too. It seems particularly popular for socket-driven apps. The important thing to keep in mind is that if your needs aren't met by existing libraries (there are many) you may need to dive into some C which can be bound to JS commands. You can also spawn additional Node processes but I suspect doing a lot of that could get taxing (I'm assuming - might be wrong - there's a V8 instance spawned for each one of those).

JS is single-threaded and blocking, meaning nothing else can execute until a function call has completed. This was a desired feature of JS, essentially taking all the threading and queuing concerns out of your hands. The JS doesn't stop the C/C++ stuff from from running in a more multi-threaded fashion under the hood so JS's role is really more architecture/messenger. If you're image-processing, you're not going to want to handle that with synchronous JavaScript commands because everything else on your app or server will be blocked until it's done. The idea is that you call for an image to be processed by bound C/C++ functionality, and then respond to the 'done' event when the image is finished being processed.

This requires that the JS in any Node.js app be heavily event and callback driven or it will likely perform very poorly. So you won't see a lot of method calls in Node that don't get handed a function for later use. One thing that becomes very clear very fast in Node is that you're in for a world of ugly if you don't find a way to handle the callback pyramid. e.g.

```<code>//event CBs are more DOM-style than Node style and this isn't built-in Node file I/O
//keeping it simple and quick since I'll just get Node stuff wrong from memory
file.get('someFile.txt', function(e){
    e.fileObj.find('some snippet', function(e){
        someFinalCallBackHandler( e.snippetLocations );
    } );
} );
</code>```

Fortunately there are plenty of tools and examples out there for handling this better. Most tend to revolve around promise mechanisms and simply chaining a series of functions meant to respond to each other's callback states in an array that does the ugly pyramid stuff for you under the hood.

Personally, I freaking love that we get JS at the high level and C/C++ closer to the chrome. It's the ultimate combo and it inspired me to start learning C. And don't let the lack of library potential freak you out until you've done some research. Node libraries are being produced at a very rapid pace and are maturing very rapidly. If you're not doing anything highly unusual odds are good somebody has it covered.

The biggest difference from Rails, is that JS is never likely to be on rails as it were. We tend to code for being able to have it however you want it very rapidly so there is the rope to hang yourself with factor and architecture has been pretty DIY in JS until more recent years. I call that freedom, but I realize that's not seen as ideal to a lot of devs.

Also, you will never ever have a "gem" problem in Node.js because you tried to install on something other than a Mac. Client-side web devs despise dependency issues and that's where a lot of Node's core is coming from. If it doesn't work out of the box in 5 minutes or less on every popular platform, we generally crumple it up and toss it. I have yet to run into a popular module that required I do anything special to get it working. The package system, is excellent.

But to answer your core question more explicitly/succinctly: Is it good with background processes?

Yes, Node basically IS background processes with a means of driving an app via events and callbacks.

Body:
It's particularly strong at handling a ton of file I/O and I would expect it to handle a ton of network communication well too. It seems particularly popular for socket-driven apps. The important thing to keep in mind is that if your needs aren't met by existing libraries (there are many) you may need to dive into some C which can be bound to JS commands. You can also spawn additional Node processes but I suspect doing a lot of that could get taxing (I'm assuming - might be wrong - there's a V8 instance spawned for each one of those).

JS is single-threaded and blocking, meaning nothing else can execute until a function call has completed. This was a desired feature of JS, essentially taking all the threading and queuing concerns out of your hands. The JS doesn't stop the C/C++ stuff from from running in a more multi-threaded fashion under the hood so JS's role is really more architecture/messenger. If you're image-processing, you're not going to want to handle that with synchronous JavaScript commands because everything else on your app or server will be blocked until it's done. The idea is that you call for an image to be processed by bound C/C++ functionality, and then respond to the 'done' event when the image is finished being processed.

This requires that the JS in any Node.js app be heavily event and callback driven or it will likely perform very poorly. So you won't see a lot of method calls in Node that don't get handed a function for later use. One thing that becomes very clear very fast in Node is that you're in for a world of ugly if you don't find a way to handle the callback pyramid. e.g.

//event CBs are more DOM-style than Node style and this isn't built-in Node file I/O
//keeping it simple and quick since I'll just get Node stuff wrong from memory
file.get('someFile.txt', function(e){
    e.fileObj.find('some snippet', function(e){
        someFinalCallBackHandler( e.snippetLocations );
    } );
} );

Fortunately there are plenty of tools and examples out there for handling this better. Most tend to revolve around promise mechanisms and simply chaining a series of functions meant to respond to each other's callback states in an array that does the ugly pyramid stuff for you under the hood.

Personally, I freaking love that we get JS at the high level and C/C++ closer to the chrome. It's the ultimate combo and it inspired me to start learning C. And don't let the lack of library potential freak you out until you've done some research. Node libraries are being produced at a very rapid pace and are maturing very rapidly. If you're not doing anything highly unusual odds are good somebody has it covered.

The biggest difference from Rails, is that JS is never likely to be on rails as it were. We tend to code for being able to have it however you want it very rapidly so there is the rope to hang yourself with factor and architecture has been pretty DIY in JS until more recent years. I call that freedom, but I realize that's not seen as ideal to a lot of devs.

Also, you will never ever have a "gem" problem in Node.js because you tried to install on something other than a Mac. Client-side web devs despise dependency issues and that's where a lot of Node's core is coming from. If it doesn't work out of the box in 5 minutes or less on every popular platform, we generally crumple it up and toss it. I have yet to run into a popular module that required I do anything special to get it working. The package system, is excellent.

But to answer your core question more explicitly/succinctly: Is it good with background processes?

Yes, Node basically IS background processes with a means of driving an app via events and callbacks.


问:
What must testers be able to do to be 'highly qualified'?
Are modern testers like 'stupid' users which try to find a bug clicking and filling fields or they have solid knowledge about product cores?

What modern testers must be able to do?

Must they be coders creating independant/embed tests?

Must they understand source code of products and even can fix easy bugs?

Other things?

I'm interested in real practice.

答:
A highly trained tester should have knowledge to translate specifications into testable requirements (s.m.a.r.t), so they can construct test scripts. That tester and his team should be able to verify if the product is conforming to the agreements and expectations of the client. Tne goal is to certify that the client can perform the actions for which the application is being developed.

By making testable specifications it can be determined if something works or not. By having the test scripts finished before the project, the project manager can be informed about progress, because there is a list of working and nonworking function points or nonfunctional requirements.

Testing should not be aimed at finding errors, but at defining product quality.


答:
This might not be exact what you want I believe that libre office lets you reference outside file. You could have a spreadsheet that you treat like a database and have a static libre file that would be your interface. You would lose easy access summing in your versioned files unless you call them back, but it would work.

Another rather big issue with this would be that it is one directional.

Title: Git-friendly spreadsheet format?

Body:
We're trying to move our project documentation process from Google Documents to a set of self-hosted Git repositories.

Text documents are Git-friendly enough, since we usually do not need any fancy formatting, we'll just convert everything to, say, multimarkdown with an option to embed LaTeX for complex cases.

But spreadsheets are quite different story... Is there a spreadsheed(-like) format that is friendly to version control systems (and, preferably, is as human-readable as Markdown)?

"Friendly format": Git works well with the format (it doesn't with XML) and it generates human-readable diffs (extra configuration involving external tools is OK).

Obviously, Markdown flavors allow one to build static tables, but I'd like to be able to use stuff like SUM() etc... (Note that CSV has the same problem.) No WYSIWYG is OK, but decent editor/tool support would be nice.

Update: Linux-friendly answers only, please. No MS Office stuff.


问:
How to save during real-time collaboration
I want multiple users to edit same document. Problem I'm facing is when a new user joins, he might see an outdated document. How do I make sure that new users get most recent changes?

Some solutions I thought of:

Save on every change. I don't like this solution because it will slow things down on UI and put load on db.

When new user joins, trigger save on all other clients. After other clients saved, load document.   With this there can be inconsistency still.

Any other suggestions would be helpful.

UPDATE: After looking into suggested solution, Google Realtime API, I found out that:

Users of your app must have Google Drive and give you access to their drive. This could at best present awkward UI flow or prevent users who don't have Google Drive from using realtime feature.

All the sharing settings that are done on your side, have to be replicated for Google document.

UPDATE 2: To acoomplish the goal, I went with Google's Firebase

答:
1) Have a look at Knockout.js

It follows an MVVM pattern and will automatically push out notifications to the View based upon changes to the Model.  For instance, look into their observable array to provide a little more information on how they do that.

2) Mix that in with SignalR and you should now have the ability to send out notifications to other users working on the document.  From their site:

SignalR also provides a very simple, high-level API for doing server to client RPC (call JavaScript functions in your clients' browsers from server-side .NET code) in your ASP.NET application, as well as adding useful hooks for connection management, e.g. connect/disconnect events, grouping connections, authorization.

So you'll need to have some hooks at your model level within Knockout.js to make some SignalR calls whenever a change occurs.  The other clients will receive the notice from SignalR and then trigger a corresponding change in their copy of the Model, which will push back up to their View.

It's an interesting combination of the two frameworks, and you should be able to search and gather more information to handle the particulars.

For example, this codeproject example specifically addresses Co Working UIs and Continuous Clients which seems to be exactly what you're trying to do.

New age web applications may need to offer new age user experiences - and should handle co-working and continuous client scenarios properly. This involves ensuring that the user interface is syncing properly itself across devices and across users to ensure the state of the application and user interface is maintained "as is".

This blog post looks to be an entry point into a series of blog posts discussing the use of the two packages and contrasts that with a traditional ASP.NET approach.  May provide some points for consideration while you're designing your site.

This blog post appears to be a little bit more basic and provides the groundwork for combining the two packages.

Disclosure: I'm not affiliated with any of the above links, nor have I really dug into their content to see how sound or correct it is.


答:
Node.js excels at IO. You are very unlikely to discover one day that your process jammed up since most of your threads are blocking in SQL calls.

However node.js is really bad at compute-bound work. When I hear "lots of IO" I think "yeah! go node!", but when I hear "parsing," I hesitate a little. I'm not sure if this is for any reason besides people not multithreading node properly, but thus far all of my product's compute-bound work happen outside of node.

Multithreading in node.js is tricky to set up right. Everything is single threaded by default and most code is written under the assumption that it will only run under one thread. You will certainly need to use domains to prevent an error on one thread from bringing down your whole application.

Also note that node may be a bit weaker in some enterprise capabilities. For instance, its logging libraries do not compare to Java's. At present there is no good logging framework that even supports and MDC, which in practice means you get to do a lot of var logPrefix = userId + ": " a lot.

I've also never run a private npm repo, you may need one of these depending on whether your code is proprietary.

Title: Is node.js a good fit for background processing?

Body:
I'm slowly learning node.js and have a small project I want to start.  The project will have a lot of background processes (downloading data from external sites, parsing CSV files, etc.).

A big "win" for me and node is the fact it uses JavaScript for both client and server.  I code in Java and JavaScript in my day job but am also pretty good at Ruby.

But, like I said, it seems attractive to use one language everywhere and JS seems to fit that bill.

However, I haven't had much experience in using JS for running background jobs.  Ruby seems to excel at this.  And I'm not opposed to using it.  So what are your thoughts on going 100% JS for this?  I realize very large projects require custom solutions.  I'm just wondering if it's worth the effort.  Or, should I just stick with Ruby on those kind of chores?

Opinions appreciated.

Thanks


问:
How to make sprint planning fun
Not only are our sprint planning meetings not fun, they're downright dreadful.

The meetings are tedious, and boring, and take forever (a day, but it feels like a lot longer).

The developers complain about it, and dread upcoming plannings.

Our routine is pretty standard (user story inserted into sprint backlog by priority >> story is taken apart to tasks >> tasks are estimated in hours >> repeat), and I can't figure out what we're doing wrong.

How can we make the meetings more enjoyable?

...

Some more details, in response to requests for more information:

Why are the backlog items not inserted and prioritized before sprint kickoff?

User stories are indeed prioritized; we have no idea how long they'll take until we break them down into tasks! From the (excellent) answers here, I see that maybe we shouldn't estimate tasks at all, only the user stories. The reason we estimate tasks (and not stories) is because we've been getting story-estimates terribly wrong -- but I guess that's the subject for an altogether different question.

Why are developers complaining?

Meetings are long.

Meetings are monotonous. Story after story, task after task, struggling (yes, struggling) to estimate how long it will take and what it involves.

Estimating tasks makes user-story-estimation seem pointless.

The longer the meeting, the less focus in the room. The less focused colleagues are, the longer the meeting takes. A recursive hate-spiral develops. We've considered splitting the meeting into two days in order to keep people focused, but the developers wouldn't hear of it. One day of planning is bad enough; now we'll have two?!

Part of our problem is that we go into very small detail (in order to get more accurate estimations). But when we estimate roughly, we go way off the mark!

To sum up the question:

What are we doing wrong?

What additional ways are there to make the meeting generally more enjoyable?

答:
At my previous job, the entire first day of each sprint (we called them iterations there) was taken up with:

Retrospective. We started out doing this in the afternoon of the last day, but we often found ourselves retrospecting about the sprint and then going back to work tying up the last loose ends of that sprint's work, so we figured it would be better to make sure the work was all behind us before retrospecting on it. It also seemed logical to consolidate all the meeting overhead of the Scrum process so the other days could be planned and spent in more ideal terms. This typically took 2 hours.

Sprint Planning. The backlog was estimated during a Milestone Planning Meeting (which could be an entire day in itself for both the Devs and POs), and had been prioritized by the POs prior to the beginning of each sprint. We figured out how many developer-days we had available (accounting for holidays, vaca, etc), grabbed the work we thought we could do off the top of the pile, and quickly reviewed the user requirements (previously vetted by our BAs) to get a more complete sense of what the work entailed than we got with the simple overview during the MPM. This typically took another 2 hours.

Task Planning. Knowing the stories and acceptance criteria, we broke down each story into bite-size tasks estimated in ideal hours (an hour spent focused solely on getting that task "done" with no distractions or roadblocks). The way our point scale ended up being calibrated, a 5 was a developer-sprint, so a 1 could be anything up to and including two developer-days. For that reason, virtually everything had to be broken down in order for team members to be able to show progress on the scrum board. This was another 2-hour block, with some give-and-take between this and the next item.

AAT Outlining. Our POs and BAs were not programmers and did not code. The POs hid behind a contract stipulating that they would deliver requirements in the form of a Word template and would work with the BAs to refine them in that form. BAs understood code, but their time was purely analysis and final testing (which required the system to exist, so they could record their macros into Selenium). So, to verify that our code would meet acceptance criteria when it came to that, we had to write our own AATs modelling the actions of the "paper" acceptance test. We typically did this in the same NUnit framework we used for unit and integration tests (we tried FitNesse and couldn't give it up fast enough). This was the rest of our first day of each sprint and continued into the second.

In my current job, we're still adopting the Scrum process, we didn't have a team-wide milestone planning, and a lot of what we're working on doesn't have strict acceptance criteria. So, our sprint planning is as much an explanation of what each story entails and what we'll call done as it is a commitment to grab the top X ideal hours of work off the top. We get away with it - for now at least - because we're an in-house team and each of us works personally with the end users of our software to gather requirements and design solutions. Even then, sprint planning is an all-morning thing every other Monday, and the afternoon is spent clearing any personal roadblocks to being able to start development in earnest on Tuesday.

To actually answer the OP's question rather than contrasting other comments/answers saying it shouldn't be taking that long, there are ways to approach Agile estimation, sprint planning and retrospectives that are a little more interesting than you might be using.

Specifically addressing your concerns:

Meetings are long - Time-box them. Each meeting, be it a retrospective, sprint planning, task breakdown, etc, should have a definite purpose and topic of discussion, and should be limited as much as possible to a set amount of time. It's the Scrum Master's job to keep these meetings on topic and rolling along to meet the time goals.

Meetings are monotonous - There will be some of that; you're working in bite-size chunks, one at a time, so you'll be doing the same thing over and over. Keeping the team focused and driving toward accomplishing the purpose of the meeting will help.

Something else I hear is that maybe your sprint planning meetings are trying to accomplish too much. At my last company, story estimation was done at "milestone planning meetings", which happened about once a quarter and took all day. In those meetings, everything that had built up on the backlog that we hadn't estimated was estimated in points. If you're doing story estimation in points, and then task estimation in hours, you don't want to do them both at the same time (maybe on the same day).

Estimating stories in points, then tasks in hours seems redundant - They have two different purposes. The purpose of story estimation is to provide a rough estimate of complexity, that you can use to fill your sprint backlog based on past velocity and expected bandwidth. The purpose of task estimation is to break the stories down into things that take one developer-day or less (and so can be assigned to a single guy who would be expected to have it all done in time), and ensure you haven't mis-estimated any story's complexity nor bitten off more than you can chew in the sprint.

If your stories all take one day or less, then it is redundant, but not all points scales are calibrated equally; at my last job, a 5 was two developer-weeks (because at the beginning we had a lot of epics to estimate), which on a linear scale made a point anything up to 2 developer-days. Given that kind of scale, virtually everything should get broken down into tasks. At my new company, a point is closer to half a developer day, so a 1 or even a 2 is definitely its own task, and 3-8 is nebulous with regard to forcing the team to split it up into tasks.

There's a vicious cycle of it taking longer making people less focused so it takes longer - Time-box your time-box. Take breaks, just like you should be when coding. Every 30 minutes, take 5 minutes to stretch your legs, regroup, etc. You can make it ten minutes every hour, but don't push a solid block of meeting time too much further than that. Your guys might be getting hungry, or need more coffee, or a bathroom break, etc. Don't deny them; if you make them suck it up you'll find their minds wandering. Beyond that, keeping discussions short, sweet and to the point will help as well, as previously mentioned.

Title: How to make sprint planning fun


问:
Clarify the Single Responsibility Principle
The Single Responsibility Principle states that a class should do one and only one thing.  Some cases are pretty clear cut.  Others, though, are difficult because what looks like "one thing" when viewed at a given level of abstraction may be multiple things when viewed at a lower level.  I also fear that if the Single Responsibility Principle is honored at the lower levels, excessively decoupled, verbose ravioli code, where more lines are spent creating tiny classes for everything and plumbing information around than actually solving the problem at hand, can result.

How would you describe what "one thing" means?  What are some concrete signs that a class really does more than "one thing"?

答:
The SRP is not just about dividing classes up, but also about delegating functionality.

In the Dog example used above, don't use SRP as justification to have 3 separate classes such as DogBarker, DogWalker, etc (low cohesion).  Instead, look at the implementation of a class's methods and decide if they "know too much".  You can still have dog.walk(), but probably the walk() method should delegate to another class the details of how walking is accomplished.

In effect we are allowing the Dog class to have one reason to change: because Dogs change.  Of course, combining this with other SOLID principles you would Extend Dog for new functionality rather than changing Dog (open/closed).  And you would Inject your dependencies such as IMove and IEat.  And of course you would make these separate interfaces (interface segregation).  Dog would only change if we found a bug or if Dogs fundamentally changed (Liskov Sub, don't extend and then remove behavior).

The net effect of SOLID is that we get to write new code more often than we have to modify existing code, and that is a big win.


问:
What licensing implications (if any) are there when porting code from one language to another?
I'm considering taking an old PHP4 web application and re-writing it using ASP.Net MVC4 in C#.

The old application was licensed under GPL2.

I'm unsure how this affects my new application, if at all.  I obviously can't directly copy any of the code from the old PHP application to my .Net application as the two languages are totally different.

Equally, the old application wasn't even OO in nature, nor did it follow any kind of design pattern (i.e. MVC).

In essence, my new application will only be taking the "ideas & features" of the original application.  Even the database schema will be significantly different.

Would I still have to GPL my new application or is it considered a new work where I choose a license myself?

答: As the link in the comments shows, this is borderline acceptable. It can be made safe by a cleanroom approach: make a specification, listing every idea and feature that you will copy. Your new code will implement the specification, and therefore not be a copy of the old code.</p>


问:
Keeping third-party source code up to date
What is the best way to keep third-party source code up to date?

For instance in my app, I'm using third-party source code from an open GitHub repository. What I've done is that I have downloaded the zip of the source code, unpacked it and imported it in my iOS app and then started modifying this source code to my hearts content.

So this third-party source code has been working great for me, but now some months later the developer of the third-party source code released an update to his code from 1.0 -> 2.0. Now of course I want to have this update as well in my iOS app. What would be the easiest way to migrate my 1.0 third-party source code (together with all my additions to the code) to 2.0?

答:
While you are using any code repository from github there is possibility of you 'forking' it. By forking it means that you can make your version of the repository. Then if you make changes(e.g. bug fixes) then you can send the original creator a 'merge` request. If the original creator accepts your changes will also be made into his repository.

In case your changes aren't something that original creator would accept then you can maintain your app in modular form. Try not to change the original interface of the 3rd party lib. That should make it possible for an update to take place.

If that isn't possible either than you can use diff to find the difference between the 2 versions and then manually make the changes. You can also find the difference by 'cloning' the git repo on your computer. Then going through the commits you can figure out the difference. That would be a longer path. I'd suggest using diff to find the difference between the 2 versions.

As MichaelT has pointed out diff3 can be more suitable for such a comparison.


问:
Web Developer and Math
I have just learned HTML/CSS and I practice everything I read to make it more understandable to me and I really enjoy it. My goal is to be a Modern Web Developer both front and back-end, so I won't stop learning. I'm planing to jump on JavaScript now but what I would like to know is how important is math to being a Web Developer.

Do I need to know math?

If so, what kind of math should I know and understand?

答:
You don't need to know more than perhaps trigonometry in order to develop web pages. But you should know the following if you want to be optimal:

Set Theory: This helps with more things that I can count in programming. You learn how to weed out duplicates more efficiently.

Graph Theory: If you want to understand networks at a fundamental level, this is helpful. It's also good for breaking down certain kinds of problems more easily.

Linear Algebra: This is huge if you want to do anything with 3D graphics like HTML5 Canvas.

Statistics: This is even bigger since you'll want to be able to understand things like web analytics and machine learning in order to fully optimize your website's features.

Understanding mathematics is also useful from the standpoint that it will generally improve your problem solving skills. You'll be able to draw analogies between difficult real world problems and mathematical models with known (often not easy) solutions.

Title: Web Developer and Math


问:
Are there any programming languages that make use of adjectives?
Are there any languages where something like the following might be possible?

```<code>people = [ ... a list of people ...]
Person jake = Person("Jake", 165, ...)
jake is Tall
people.add(jake)
for Person person in people where Tall:
    // ... do something terrible to them
jake is not Tall // ... Jake no longer wishes to be tall
</code>```

I hope that makes sense - basically, dynamic adjectives that affect something about an object's properties or methods.

答:
Prolog and other logic programming languages do this. They have identifiers with lists of characteristics which are then queried to do computation. Inferences about relationships can also be made.

This example from Wikipedia shows how:

```<code>mother_child(trude, sally).

father_child(tom, sally).
father_child(tom, erica).
father_child(mike, tom).

sibling(X, Y)      :- parent_child(Z, X), parent_child(Z, Y).

parent_child(X, Y) :- father_child(X, Y).
parent_child(X, Y) :- mother_child(X, Y).
</code>```

So you've described some family relations here. You can then ask Prolog a question about them:

```<code>?- sibling(sally, erica).
Yes
</code>```

Body:
Prolog and other logic programming languages do this. They have identifiers with lists of characteristics which are then queried to do computation. Inferences about relationships can also be made.

This example from Wikipedia shows how:

mother_child(trude, sally).

father_child(tom, sally).
father_child(tom, erica).
father_child(mike, tom).

sibling(X, Y)      :- parent_child(Z, X), parent_child(Z, Y).

parent_child(X, Y) :- father_child(X, Y).
parent_child(X, Y) :- mother_child(X, Y).

So you've described some family relations here. You can then ask Prolog a question about them:

?- sibling(sally, erica).
Yes


答:
FWIW, in a generic sense (i.e. programming, irrespective of language), the most valuable proof in terms of math for programming is algebra.   You don't use it directly, but it trains you in the kind of logical processes necessary to be successful as a programmer.  A lot of programming is math-orientated, too, but the algebra is best in teaching you how to think in order to solve problems you might encounter.

That said, if I were to teach an "Intro to Programming" course, I'd do an algebra pre-test that's heavy on logical process (word problems, solve for x, and so on) and then highly suggest anyone that washes out on that test to think very hard about finding another class because their chances of success would be slim.

And yes, this is opinion, but opinion based on several of my personal experiences, too.

Title: Web Developer and Math

Body:
I have just learned HTML/CSS and I practice everything I read to make it more understandable to me and I really enjoy it. My goal is to be a Modern Web Developer both front and back-end, so I won't stop learning. I'm planing to jump on JavaScript now but what I would like to know is how important is math to being a Web Developer.

Do I need to know math?

If so, what kind of math should I know and understand?


答:
Ok ruby answer:</p>

```<code>module Traity
  def initialize
    @traits = {}
  end
  def method_missing trait
    @traits[trait]
  end
  def give_trait trait
      @traits[trait] = true
  end
  def take_trait trait
      @traits[trait] = false
   end
end

class Tom
   include Traity
end

 t = Tom.new
 t.give_trait :tall
 puts t.tall
 t.take_trait :tall
 puts t.tall
</code>```

Title: Are there any programming languages that make use of adjectives?

Body:
Are there any languages where something like the following might be possible?

```<code>people = [ ... a list of people ...]
Person jake = Person("Jake", 165, ...)
jake is Tall
people.add(jake)
for Person person in people where Tall:
    // ... do something terrible to them
jake is not Tall // ... Jake no longer wishes to be tall
</code>```

I hope that makes sense - basically, dynamic adjectives that affect something about an object's properties or methods.

Body:
Ok ruby answer:

module Traity
  def initialize
    @traits = {}
  end
  def method_missing trait
    @traits[trait]
  end
  def give_trait trait
      @traits[trait] = true
  end
  def take_trait trait
      @traits[trait] = false
   end
end

class Tom
   include Traity
end

 t = Tom.new
 t.give_trait :tall
 puts t.tall
 t.take_trait :tall
 puts t.tall


答:
I think that you could view modifiers on declarations as adjectives.

For instance:

```<code>    static int foo;
</code>```

says "We declare foo to be a static int".  The word static an adjective, both in the Java context and in the English language.

Another example is Java annotations.

Note that since annotations can be user-defined, you have user-defined adjectives.

Java is a statically compiled language so it doesn't have dynamic adjectives in the broadest sense.  However, you could generalize this "analysis" to any (dynamic) language with these language features.

I'm not convinced it is particularly useful though.  The mere possibility of adjectival constructs is not sufficient.  You also need significant (application specific) support to make the constructs do something useful.  (For instance, in Java you need either application specific annotation processors or reflective code in the application to examine annotations at runtime.)

Body:
I think that you could view modifiers on declarations as adjectives.

For instance:

    static int foo;

says "We declare foo to be a static int".  The word static an adjective, both in the Java context and in the English language.

Another example is Java annotations.

Note that since annotations can be user-defined, you have user-defined adjectives.

Java is a statically compiled language so it doesn't have dynamic adjectives in the broadest sense.  However, you could generalize this "analysis" to any (dynamic) language with these language features.

I'm not convinced it is particularly useful though.  The mere possibility of adjectival constructs is not sufficient.  You also need significant (application specific) support to make the constructs do something useful.  (For instance, in Java you need either application specific annotation processors or reflective code in the application to examine annotations at runtime.)


答:
Your "adjectives" are basically just boolean attributes, which pretty much every programming language has, and your filter operatio is, well, a filter operation which any halfway decent collection framework has.

For example, in Ruby:

```<code>class Object
  def is(*attrs)
    attrs.each do |attr| define_singleton_method(:"#{attr}?") do true end end
  end

  def isnt(*attrs)
    attrs.each do |attr| define_singleton_method(:"#{attr}?") do nil end end
  end
end

Person = Struct.new(:name)

jake = Person.new('Jake')
bill = Person.new('Bill')

jake.is(:tall, :mean)
bill.isnt(:tall)
bill.is(:mean)

people = [jake, bill]

people.select(&:tall?)
# => [#<struct Person name="Jake">]

people.select(&:mean?)
# => [#<struct Person name="Jake">, #<struct Person name="Bill">]

jake.isnt(:mean)

people.select(&:mean?)
# => [#<struct Person name="Bill">]
</code>```

Maybe if you describe the actual problem you are having, you will get better answers, but for now, standard collection operations and a simple boolean attribute are plenty enough; there doesn't seem to be anything that requires sophisticated inference, backtracking, unification or anything like that.

Body:
Your "adjectives" are basically just boolean attributes, which pretty much every programming language has, and your filter operatio is, well, a filter operation which any halfway decent collection framework has.

For example, in Ruby:

class Object
  def is(*attrs)
    attrs.each do |attr| define_singleton_method(:"#{attr}?") do true end end
  end

  def isnt(*attrs)
    attrs.each do |attr| define_singleton_method(:"#{attr}?") do nil end end
  end
end

Person = Struct.new(:name)

jake = Person.new('Jake')
bill = Person.new('Bill')

jake.is(:tall, :mean)
bill.isnt(:tall)
bill.is(:mean)

people = [jake, bill]

people.select(&:tall?)
# => [#<struct Person name="Jake">]

people.select(&:mean?)
# => [#<struct Person name="Jake">, #<struct Person name="Bill">]

jake.isnt(:mean)

people.select(&:mean?)
# => [#<struct Person name="Bill">]

Maybe if you describe the actual problem you are having, you will get better answers, but for now, standard collection operations and a simple boolean attribute are plenty enough; there doesn't seem to be anything that requires sophisticated inference, backtracking, unification or anything like that.


答:
Adjectives are really just attribute evaluation. Here's how I might handle it in JavaScript.

function PersonAdjectiveConstructor(person) {
    this.isTall = (person.height >= 6);
    this.isRich = (person.pocketMoney >= 1000000);
    this.isSmart = (person.iq > person.shoeSize);
    this.isInsufferable = ( this.tall && this.rich && this.smart );
    //formerly (for comment context):
    //this.isInsufferable = ( this.smart && this.rich && this.smart );
}

function PersonConstructor(personAttributes){

    for(var x in personAttributes){
        this[x] = personAttributes[x];
    }

    var adjectives = new PersonAdjectiveConstructor(this);

    for(var x in adjectives){
        this[x] = adjectives[x];
    }
}

var bob = new PersonConstructor({ shoeSize:11, iq:12, height:6.25, pocketMoney:2000000 });

console.log(bob.isInsufferable);//true
```