答:
After coming across the same problem, here is the solution I implemented for it.

Domain

```<code>public class DomainObject : AggregateRootBase //implements IAggregateRoot
{
    private ChildEntity _ChildEntity = null;
    public ChildEntity ChildEntity
    {
        get
        {
            OnChildEntityRequested();
            return _ChildEntity;
        }
    }

    public event EventHandler ChildEntityRequested;
    protected void OnChildEntityRequested()
    {
        if (ChildEntityRequested != null) { ChildEntityRequested(this, new EventArgs()); }
    }

    public static void SetChildEntity(DomainObject destination, ChildEntity child)
    {
        //To set or not to set, that is the question.
        destination._ChildEntity = child;
    }
}
</code>```

Repository Implementation

```<code>public class DomainObjectRepository : List<DomainObjectTracker>, IDomainObjectRepository
{
    private void Load() //Method called by constructor or other loading mechanism.
    {
        foreach (DomainObjectDataModel dodm in ORMSystem) //Iterating through each object returned from ORM.
        {
             DomainObject do = Translate(dodm); //Translate into domain object.
             do.ChildEntityRequested += new EventHandler(DomainObject_ChildEntityRequested);
             DomainObjectTracker tracker = new DomainObjectTracker(do, dodm.Key);
             base.Add(tracker);
        }
    }

    protected void DomainObject_ChildEntityRequested(object sender, EventArgs e)
    {
        DomainObject source = sender as DomainObject;
        //Here, you could check to see if it is null or stale before loading it.
        //if (source.ChildEntity == null || IsStale(source.ChildEntity))

        DomainObjectTracker tracker = base[IndexOf(source)];
        ChildEntity entity = LoadChildEntity(tracker.Key); //Load the child entity from ORM.
        DomainObject.SetChildEntity(source, entity);
    }
}
</code>```

After examining my solution, you may be thinking, "Isn't calling an event infrastructure related code, it certainly doesn't relate to my domain?".  While that may be true, if you think about it solely in terms of PI, then you realize that you're just offering a message from your domain saying, "Hey, I'm about to access this child entity." which allows your repository to respond with, "Hold on, if you need one (or a new one), I got it right here in my db so let me give this to you before you continue!".

There are a few caveats here.  One, it means that you need an event for every child entity within an aggregate.  Two, it breaks encapsulation because you are allowing a public way of setting the child entity.  On the flip side, the benefits are expressive code, infrastructure implementations are easily separated from the domain, domain objects are PI, and the ORM remains encapsulated behind the repository implementation.

If someone has a better way of solving this problem, I'm all eyes!

EDIT
Also, even though my answer provides a solution for PI, I agree with the commenters above.  You need to evaluate if DDD is even the right answer for you because, while it makes a project easier to maintain and simplifies what would otherwise be a highly complex project, it comes at a cost (usually up-front development time and training your team to organize code properly and utilize the various patterns).

Title: Do we achieve 100% Persistence Ignorance solution if we're not using ORM's POCO objects to model the Domain?

Body:
Persistence ignorance is ability to retrieve/persist standard objects, where standard objects are considered as classes focused on particular business problem  and thus don't contain any infrastructure-related logic. In DDD a Repository pattern is used to achieve PI.

Assuming we don't use ORM's POCO objects to model the Domain, then our Domain objects don't have to adhere to design requirements of a particular O/RM ( such as using default constructor or marking properties as virtual ). Such Domain objects would be considered Persistence Ignorant.

But if we want these Domain Objects to also support features such as lazy loading, then their properties must contain some logic which at some point would need to check whether related data was already loaded and if it wasn't, it would contact the appropriate Repository and request the related data.

Now even though these Domain Object are completely unaware of how they are being persisted and as such their Domain is completely decoupled from the underlying DAL provider, couldn't we still argue that such Domain Ojects contain Infrastructure-related logic and thus still violate PI?

Body:
After coming across the same problem, here is the solution I implemented for it.

Domain

public class DomainObject : AggregateRootBase //implements IAggregateRoot
{
    private ChildEntity _ChildEntity = null;
    public ChildEntity ChildEntity
    {
        get
        {
            OnChildEntityRequested();
            return _ChildEntity;
        }
    }

    public event EventHandler ChildEntityRequested;
    protected void OnChildEntityRequested()
    {
        if (ChildEntityRequested != null) { ChildEntityRequested(this, new EventArgs()); }
    }

    public static void SetChildEntity(DomainObject destination, ChildEntity child)
    {
        //To set or not to set, that is the question.
        destination._ChildEntity = child;
    }
}

Repository Implementation

public class DomainObjectRepository : List<DomainObjectTracker>, IDomainObjectRepository
{
    private void Load() //Method called by constructor or other loading mechanism.
    {
        foreach (DomainObjectDataModel dodm in ORMSystem) //Iterating through each object returned from ORM.
        {
             DomainObject do = Translate(dodm); //Translate into domain object.
             do.ChildEntityRequested += new EventHandler(DomainObject_ChildEntityRequested);
             DomainObjectTracker tracker = new DomainObjectTracker(do, dodm.Key);
             base.Add(tracker);
        }
    }

    protected void DomainObject_ChildEntityRequested(object sender, EventArgs e)
    {
        DomainObject source = sender as DomainObject;
        //Here, you could check to see if it is null or stale before loading it.
        //if (source.ChildEntity == null || IsStale(source.ChildEntity))

        DomainObjectTracker tracker = base[IndexOf(source)];
        ChildEntity entity = LoadChildEntity(tracker.Key); //Load the child entity from ORM.
        DomainObject.SetChildEntity(source, entity);
    }
}

After examining my solution, you may be thinking, "Isn't calling an event infrastructure related code, it certainly doesn't relate to my domain?".  While that may be true, if you think about it solely in terms of PI, then you realize that you're just offering a message from your domain saying, "Hey, I'm about to access this child entity." which allows your repository to respond with, "Hold on, if you need one (or a new one), I got it right here in my db so let me give this to you before you continue!".

There are a few caveats here.  One, it means that you need an event for every child entity within an aggregate.  Two, it breaks encapsulation because you are allowing a public way of setting the child entity.  On the flip side, the benefits are expressive code, infrastructure implementations are easily separated from the domain, domain objects are PI, and the ORM remains encapsulated behind the repository implementation.

If someone has a better way of solving this problem, I'm all eyes!

EDIT
Also, even though my answer provides a solution for PI, I agree with the commenters above.  You need to evaluate if DDD is even the right answer for you because, while it makes a project easier to maintain and simplifies what would otherwise be a highly complex project, it comes at a cost (usually up-front development time and training your team to organize code properly and utilize the various patterns).


问:
how do you seperate from designing question to programming questions?
As i try to program a solution to a request arise. I can't separate the difference between implementation problems and design problems.

How do you specifically express the design problem?

答: Usually there is design before implementation, if I recall my Waterfall methodology stuff.  What is the general idea being used to solve the problem is how I see design and possibly picking design patterns or other existing solutions to problems are at the design level.  The implementation has all the details of taking what was general and hypothetical and making it real.  This is kind of like Neil's answer.  Another way to see this is that the design is what an architect has when he is done while the implementation is what the developer does, at least in bigger projects I believe.</p>

ContentLicense: CC BY-SA 3.0

ContentLicense: CC BY-SA 2.5


问:
Does the state Pattern violate Liskov Substitution Principle?
This image is taken from Applying Domain-Driven Design and Patterns: With Examples in C# and .NET

This is the class diagram for the State Pattern where a SalesOrder can have different states during its life time. Only certain transitions are allowed between the different states.

Now the OrderState class is an abstract class and all its methods are inherited to its subclasses. If we consider the subclass Cancelled which is a final state that doesn't allow any transitions to any other states, we'll have to override all its methods in this class to throw exceptions.

Now doesn't that violate Liskov's substitution principle since a sublcass shouldn't alter the behavior of the parent? Does changing the abstract class  into an interface fixes this?

How can this be fixed?

答:
(This is written from the point of view of C#, so no checked exceptions.)

According to Wikipedia article about LSP, one of the conditions of LSP is:

No new exceptions should be thrown by methods of the subtype, except where those exceptions are themselves subtypes of exceptions thrown by the methods of the supertype.

How should you understand that? What exactly are “exceptions thrown by the methods of the supertype” when the methods of the supertype are abstract? I think those are the exceptions that are documented as the exceptions that can thrown by the methods of the supertype.

What this means is that if OrderState.Ship() is documented as something like “throws InvalidOperationException if this operations is not supported by the current state”, then I think this design does not break LSP. On the other hand, if the supertype methods are not documented this way, LSP is violated.

But this does not mean this is good design, you should not use exceptions for normal control flow, which this seems very close to. Also, in a real application, you would probably want to know whether an operation can be performed before you attempt to do it, for example to disable the “Ship” button in the UI.


问:
Different Project Type in a Single Website
I have developed a website in asp.net and I have some additional tasks, improvements to develop. In order to get experience in asp.net/mvc, I want to create an admin panel using asp.net mvc.

Is this a logical next step?

P.S. The project is small and 20% of the website is mine, so there are not any restrictions. There is no problem if I do not meet deadlines! :)

答:
It is fairly common to transition from one web framework over to another, doing new development in the once and future framework and migrating the older projects as there is time (frequently, there is never time).

It would generally be a little more frowned upon to maintain two web applications written in the same language running different frameworks as a planned way of life--in most corporate settings, homogeneity in framework choice is encouraged.

That said, for smaller projects or personal projects, I would not really worry about it.


问:
Is every number in the code considered a "magic number"?
So every number in the code that we are sending to a method as an argument is considered as a Magic Number?
To me, it shouldn't.  I think if some number is let's say it is for minimum length of user name and we start using "6" in the code...then yeah we have a maintenance problem and here "6" is a magic number....but if we are calling a method that one of its arguments accept an integer for example as the ith member of a collection and then we pass "0" to that method call, in this case I don't see that "0" as a magic number.
What do you think?</p>

答:
I would suggest three key factors in deciding whether something should be a constant declaration:

Is the number something that is precisely and concisely representable

Are there any plausible scenarios under which the value would have to change, but the code would not have to be rewritten

Would someone who sees the number be apt to recognize it more quickly or less quickly than someone who sees a named constant

Something like pi should probably be written as a named constant, rather than as a numeric literal, since a numeric literal is apt to be needlessly verbose, needlessly imprecise, or both.  Something like the number of slots in a cache should likely be a named constant (though see note below) to allow for the possibility of expanding the cache without having to modify all the code that uses it.  Things like the numbers "4", "28", and "29" in the statement if ((year % 4)==0) FebruaryDays = 29; else FebruaryDays = 28; should probably not be named constants, since the expression is almost certainly more readable than if ((year % YearsBetweenLeapYears)==0) FebruaryDays = FebruaryDaysInLeapYear; else FebruaryDays = FebruaryDaysInNonLeapYear;.  Note that the maintainers of standards have indicated that the length of February 2100 in that year will not match the above formula, but I would recommend not handling that case unless it would be the only impediment to correctly handling such dates (i.e. the code won't get tripped by integer overflow or other such problems).

An important caveat with rule #2 is that in some cases code may rely upon hard-coded numbers in a way which cannot readily be represented by a named constant.  For example, a method which computes a cross product of two vectors passed as discrete parameters will only be meaningful when used on three-dimensional vectors.  The required number of dimensions is not a value that could meaningfully be changed without completely rewriting the routine.  Even if one foresaw a possible need for computing the cross product of three 4-dimensional vectors, using a named constant for the value "3" would do little to make it easier to satisfy that need.


问:
What are the challenges related to typing in writing a compiler for a dynamically typed language?
In this talk, Guido van Rossum is talking (27:30) about attempts to write a compiler for Python code, commenting on it saying:

turns out it's not so easy to write a compiler that maintains all the
  nice dynamic typing properties and also maintains semantic correctness
  of your program, so that it actually does the same thing no matter
  what kind of weirdness you do somewhere under the covers and actually
  runs any faster

What are the (possible) challenges related to typing in writing a compiler for a dynamically typed language like Python?

答:
The hardest problem is to figure out what type everything has at any given time.

In a static language like C or Java, once you have seen the type declaration, you know what that object is and what it can do.  If a variable is declared int, it is an integer.  It is not, for example, a callable function reference.

In Python, it can be.  This is horrible Python, but legal:

```<code>i = 2
x = 3 + i

def prn(s):
    print(s)

i = prn
i(x)
</code>```

Now, this example is pretty stupid, but it illustrates the general idea.

More realistically, you might replace a built-in function with a user-defined function that does something slightly different (like a version that logs its arguments when you call it).

PyPy uses Just-In-Time compilation after watching what the code actually does, and this lets PyPy speed things up a lot.  PyPy can watch a loop, and verify that every time the loop runs, variable foo is always an integer; then PyPy can optimize away the code that looks up the type of foo on every pass through the loop, and can often even get rid of the Python object that represents an integer, and foo can just become a number sitting in a register on the CPU.  This is how PyPy can be faster than CPython; CPython does the type lookup as fast as possible, but not even doing the lookup is even faster.

I don't know the details, but I remember there was a project called Unladen Swallow that was trying to apply static compiler technology to speed up Python (using LLVM).  You might want to Google search for Unladen Swallow and see if you can find a discussion of why it didn't work out as they had hoped.

OwnerDisplayName: REACHUS

Body:
The hardest problem is to figure out what type everything has at any given time.

In a static language like C or Java, once you have seen the type declaration, you know what that object is and what it can do.  If a variable is declared int, it is an integer.  It is not, for example, a callable function reference.

In Python, it can be.  This is horrible Python, but legal:

i = 2
x = 3 + i

def prn(s):
    print(s)

i = prn
i(x)

Now, this example is pretty stupid, but it illustrates the general idea.

More realistically, you might replace a built-in function with a user-defined function that does something slightly different (like a version that logs its arguments when you call it).

PyPy uses Just-In-Time compilation after watching what the code actually does, and this lets PyPy speed things up a lot.  PyPy can watch a loop, and verify that every time the loop runs, variable foo is always an integer; then PyPy can optimize away the code that looks up the type of foo on every pass through the loop, and can often even get rid of the Python object that represents an integer, and foo can just become a number sitting in a register on the CPU.  This is how PyPy can be faster than CPython; CPython does the type lookup as fast as possible, but not even doing the lookup is even faster.

I don't know the details, but I remember there was a project called Unladen Swallow that was trying to apply static compiler technology to speed up Python (using LLVM).  You might want to Google search for Unladen Swallow and see if you can find a discussion of why it didn't work out as they had hoped.

OwnerDisplayName: steveha


答:
As the other answer says, the key problem is figuring out type information.  To the extent you can do that statically, you can directly generate good code.

But even if you can't do it statically, you can still generate reasonable code, just at runtime, when you get actual type information.   This information turns out often to be stable, or have at most a few different values for any particular entity at a particular code point.   The SELF programming language pioneered many of the ideas of aggressive runtime type collection and runtime code generation.  Its ideas are widely used in modern JIT-based compilers like Java and C#.

Title: What are the challenges related to typing in writing a compiler for a dynamically typed language?

Body:
In this talk, Guido van Rossum is talking (27:30) about attempts to write a compiler for Python code, commenting on it saying:

turns out it's not so easy to write a compiler that maintains all the
  nice dynamic typing properties and also maintains semantic correctness
  of your program, so that it actually does the same thing no matter
  what kind of weirdness you do somewhere under the covers and actually
  runs any faster

What are the (possible) challenges related to typing in writing a compiler for a dynamically typed language like Python?

OwnerDisplayName: Ira Baxter


答:
You oversimplified Guido's statement in phrasing your question. The problem isn't writing a compiler for a dynamically-typed language. The problem is writing one that is (criteria 1) always correct, (criteria 2) keeps dynamic typing, and (criteria 3) is noticeably faster for a significant amount of code.

It's easy to implement 90% (failing criteria 1) of Python and be consistently fast at it. Similarly, it's easy to create a faster Python variant with static typing (failing criteria 2). Implementing 100% is also easy (insofar implementing a language that complex is easy), but so far every easy way to implement it turns out to be relatively slow (failing criteria 3).

Implementing an interpreter plus JIT that's correct, implements the entire language, and is faster for some code turns out to be feasible, though significantly harder (cf. PyPy) and only so if you automate the creation of the JIT compiler (Psyco did without it, but was very limited in what code it could speed up). But note that this is explicitly out of scope, as we're talking about static (aka ahead-of-time) compilers. I only mention this to explain why its approach does not work for static compilers (or at least there's no existing counterexample): It first has to interpret and observe the program, then generate code for a specific iteration of a loop (or another linear code path), then optimize the hell out of that based on assumptions only true for that specific iteration (or at least, not for all possible iterations). The expectation is that many later executions of that code will also match the expectation and thus benefit from the optimizations. Some (relatively cheap) checks are added to assure correctness. To do all this, you need an idea of what to specialize for, and a slow but general implementation to fall back to. AOT compilers have neither. They can't specialize at all based on code they can't see (e.g. dynamically loaded code), and specializing carelessly means generating more code, which has a number of problems (icache utilization, binary size, compile time, additional branches).

Implementing an AOT compiler that correctly implements the entire language is also relatively easy: Generate code that calls into the runtime to do what the interpreter would do when fed with this code. Nuitka (mostly) does this. However, this doesn't yield much performance benefit (failing criteria 3), as you still have to do just as much unnecessary work as an interpreter, save for dispatching the bytecode to the block of C code which does what you compiled in. But that's only a rather small cost -- significant enough to be worth optimizing in an existing interpreter, but not significant enough to justify a whole new implementation with its own problems.

What would be needed to fulfill all three criteria? We have no idea. There are some static analysis schemes which can extract some information about concrete types, control flow, etc. from Python programs. The ones that yield accurate data beyond the scope of a single basic block are extremely slow and need to see the whole program, or at least most of it. Still, you can't do much with that information, other than perhaps optimize a few operations on builtin types.

Why's that? To put it bluntly, a compiler either removes the ability to execute Python code loaded at runtime (failing criteria 1), or it does not make any assumptions that can be invalidated by any Python code at all. Unfortunately, that includes pretty much everything useful for optimizing programs: Globals including functions can be rebound, classes can be mutated or replaced entirely, modules can be modified arbitrarily too, importing can be hijacked in several ways, etc. A single string passed to eval, exec, __import__, or numerous other functions, may do any of that. In effect, that means almost no big optimizations can be applied, yielding little performance benefit (failing criteria 3). Back to the above paragraph.


问:
Versioned Resources to Improve Cacheability
Here's an API concept which could be useful for performance optimisation. It's an example of key-based cache expiry applied to a broader internet-wide context instead of the internal Memcached-style scenario it seems to be mostly used for.

I want to make API calls almost as cacheable as static images. Using a news/feed subscriber as an example, which we might poll hourly, the idea is to send a last-updated timestamp along with each topic (it could just as easily be a version number or checksum):

```<code>{
  username: "Wendy",
  topics: [{
    name: "tv",
    updated: 1357647954355
  },
  {
    name: "movies",
    updated: 1357648018817
  },
  {
    name: "music",
    updated: 1357648028264
  }]
}
</code>```

To be clear, this resource itself comes directly from the server every time and is not cached on the edge or by the client. It's our subsequent calls for topics that we can aggressively cache, thanks to the timestamp.

Assuming we want to sync all topics, we'd have "N" further calls to make in a naieve implementation (/topics/tv etc). But because of the timestamp, we can construct a URL like /topics/tv/1357647954355.json. The client usually doesn't make a call at all if it's already seen (and cached) the same version of that resource. Furthermore, even if it's new to the client, an edge cache (e.g. a reverse-proxy like Squid, Varnish, or service like Cloudflare) probably has seen it before, because some other user has probably opened the latest version of this topic already. So we still bypass the application server; the server only ever creates topic JSON once after the underlying resource has updated. So instead of N+1 calls to the server, the client probably makes a much smaller number of calls, and those calls will rarely hit the app server anyway.

Now for my question All this seems feasible and worth doing, but my question is if there's any prior art for this kind of thing and in particular, any HTTP standards to support it. I initially thought of conditional caching (ETags and modified dates), and I think they'd help to optimise this setup further, but I don't believe they are the answer. They are subtly different, because they require calls to be passed through to the application server in order to check something's changed. The idea here is the client saying "I already know the latest version, please send that resource back to me". I don't think there's any HTTP standard for it, which is why I propose a URL scheme like /topics/tv/1357647954355.json instead of some ETag-like header. I believe some CDNs work this way and it's surprising to me if there's no real HTTP standard around it.

Update:
On reflection, an important special case of this is what a web browser does when it fetches a new HTML page. We know it will immediately be requesting CSS+JS, so the same versioning/timestamp trick can be used to ensure those static resources are cache-friendly. That this trick has not been formalised by the spec gives me confidence that unfortunately there is no HTTP standard for it. http://www.particletree.com/notebook/automatically-version-your-css-and-javascript-files/

答:
As far as I can tell, you don't really need any specific HTTP support for what you want to do.  At the core, you seem to want to be able to take a json fragment like

```<code>topics: [{
    name: "tv",
    updated: 1357647954355
},
</code>```

and turn it into

```<code>GET /topics/tv/1357647954355.json
</code>```

and have that returned from an edge cache or other store without hitting your server, presuming of course that a neighbour (to some Internet definition of local) has already requested the same page and therefore the local edge cache has it (assuming good cache-hints, etc)?

So long as your javascript processing your original json can perform the second AJAX-GET, then you should get pretty much what you are expecting to happen, that the number of requests hitting the central server for the individual tv/ URL are few, given their high cachability.

Body:
As far as I can tell, you don't really need any specific HTTP support for what you want to do.  At the core, you seem to want to be able to take a json fragment like

topics: [{
    name: "tv",
    updated: 1357647954355
},

and turn it into

GET /topics/tv/1357647954355.json

and have that returned from an edge cache or other store without hitting your server, presuming of course that a neighbour (to some Internet definition of local) has already requested the same page and therefore the local edge cache has it (assuming good cache-hints, etc)?

So long as your javascript processing your original json can perform the second AJAX-GET, then you should get pretty much what you are expecting to happen, that the number of requests hitting the central server for the individual tv/ URL are few, given their high cachability.


问:
How to organize MVVM files in solution
I'm fairly new to the MVVM concept but like a lot of the flexibility it gives me so far.  However, I'm struggling to find a good way to manage my code.  I have several classes that are just sitting in a folder in my solution such as xxxView.cs, xxxViewModel.cs, yyyView.cs, yyyViewModel.cs, zzzView.cs, zzzViewModel.cs you get the idea.  It has started to crowd my solution, making it harder to find the files I'm looking for.  Is there some standard way to organize these files?  Do I create a View and ViewModel folder to separate and clean up the solution or have people found a better way?

答:
We use separate projects for

View

ViewModel

Model

And within those projects, we'll potentially add folders to provide additional structure.

The View project references ViewModel, and the ViewModel project references the Model.

Images often receive their own folder.  So far, resource dictionaries, converters, and extended objects have been placed in the main project folder for the layer.

An alternative is to have "major application areas" as projects. Then you have either have V / VM / M folders within each area or you just place the related MVVM files in the area project folder.

I don't like this approach as much since I'll frequently have to work on multiple Views at a time so I end up navigating through a lot more project structure than I would like.

This approach kind of limits re-use when it comes to resource dictionaries or similar.  The cross-referencing of projects can become difficult to maintain.  However, creating a dedicated "common resource" project would be an approach to easing this problem.

Title: How to organize MVVM files in solution


问:
Does the use of personas in Agile have any value during implementation?
This is about the use of personas, primarily in the agile development realm.

What value, if any, do personas give during implementation?

On agile modeling, the discussion about personas remains in the context of requirements investigation.

On wikipedia, the benefits are described to "assist with brainstorming, use case specification, and features definition."

I'm familiar with personas in use while writing user stories such as the following:

As Willow, I want ordering a combo meal to give me the option to select alternate sides.

  As Xander, I want the default side to be selected when I order a combo meal.

In these examples, Willow is the nutrition-conscientious user of meal-ordering software and Xander is the hungry, impatient user that thinks "fast food should be fast."

When coming up with these requirements, it may have been helpful to have the personas in mind. I imagine a possible discussion:

Person 1: Willow needs to have more options than fries for the combo meal, otherwise she would never order a combo.

  Person 2: But Xander doesn't want to have to sift through different options when ordering a combo! He just wants fries and he'll probably always want fries.

This discussion may have created the two requirements above, but once the requirements have been created, why do we mark each requirement with a persona? I wouldn't code the 'default side' requirement any differently knowing that it is for Xander. What value does retaining the "As Willow" and "As Xander" starts to the requirements once they have been written? What value does the persona give to the one who implements the requirement?

答:
It can do, particularly if you're using a BDD / specification framework, such as Cucumber.

In those, you need to write your test cases using Given (And) When (And) Then (And) format. This can be a bit unwieldy when you start writing

```<code>Given a user is logged in
And the user has administration rights
And the user is based in the US
And the user has brown hair
And the user is French-speaking
And there is a product available costing less than $80
And the product is less than 5 cubic feet
And the product is less than 15kg
And the user has paged to that product
When the user clicks Add to Basket
Then the product should be added to the user's basket
</code>```

And maybe you have to write 40 test cases that are all similar. In that case, it is significantly easier to have a known user Xander, who fits the description above, and the product "Buffy the Vampire Slayer Season 7 box set", which also fits the description above, and write the test

```<code>Given that Xander is logged in
And has paged to the Buffy the Vampire Slayer Season 7 box set
When the user clicks Add to Basket
Then the product should be added to the user's basket
</code>```

Body:
It can do, particularly if you're using a BDD / specification framework, such as Cucumber.

In those, you need to write your test cases using Given (And) When (And) Then (And) format. This can be a bit unwieldy when you start writing

Given a user is logged in
And the user has administration rights
And the user is based in the US
And the user has brown hair
And the user is French-speaking
And there is a product available costing less than $80
And the product is less than 5 cubic feet
And the product is less than 15kg
And the user has paged to that product
When the user clicks Add to Basket
Then the product should be added to the user's basket

And maybe you have to write 40 test cases that are all similar. In that case, it is significantly easier to have a known user Xander, who fits the description above, and the product "Buffy the Vampire Slayer Season 7 box set", which also fits the description above, and write the test

Given that Xander is logged in
And has paged to the Buffy the Vampire Slayer Season 7 box set
When the user clicks Add to Basket
Then the product should be added to the user's basket


问:
Are exceptions an OOP concept?
Having read a post yesterday, I realized I did not know much about the origin of exceptions. Is it an OOP related concept only? I tend to think it is, but again there are database exceptions.</p>

答:
Exceptions are not an OOP concept.

But they are not completely unrelated either in one little tiny point.

As other answers have shown: The concept of exceptions has made it in several non-OOP languages. Nothing in that concept requires something from OOP.

But any if not all OOP languages which takes OOP seriously require exceptions because the other methods of error-handling fail at one specific point: The constructor.

One of the points of OOP is that an object shall encapsulate and manage its internal state completely and consistently. This also means that in pure OOP you need a concept to create a new object with a conistent state "atomically" - everything from memory allocation (if required) to the initialisation to a meaningful state (i.e. simple zeroing the memory is not enough) must be done in one expression. Hence a constructor is required:

```<code>Foo myFoo = Foo("foo", "bar", 42);
</code>```

But this means that the constructor can also fail due to some error. How to propagate the error information out from the constructor without exceptions?

Return value? Fails since in some languages new could return only null but not any meaningfull information. In other languages (e.g. C++) myFoo is not a pointer. You could not check it against null. Also you cannot ask myFoo about the error - it is not initialized and therefore "does not exist" in OOP thinking.

Global error flag? So much about encapsulating state and then some global variable? Go to h... ;-)

A mixture? In no way better.

?

So exceptions are a more fundamental concept than OOP but OOP builds upon them in a natural way.

Title: Are exceptions an OOP concept?

Body:
Exceptions are not an OOP concept.

But they are not completely unrelated either in one little tiny point.

As other answers have shown: The concept of exceptions has made it in several non-OOP languages. Nothing in that concept requires something from OOP.

But any if not all OOP languages which takes OOP seriously require exceptions because the other methods of error-handling fail at one specific point: The constructor.

One of the points of OOP is that an object shall encapsulate and manage its internal state completely and consistently. This also means that in pure OOP you need a concept to create a new object with a conistent state "atomically" - everything from memory allocation (if required) to the initialisation to a meaningful state (i.e. simple zeroing the memory is not enough) must be done in one expression. Hence a constructor is required:

Foo myFoo = Foo("foo", "bar", 42);

But this means that the constructor can also fail due to some error. How to propagate the error information out from the constructor without exceptions?

Return value? Fails since in some languages new could return only null but not any meaningfull information. In other languages (e.g. C++) myFoo is not a pointer. You could not check it against null. Also you cannot ask myFoo about the error - it is not initialized and therefore "does not exist" in OOP thinking.

Global error flag? So much about encapsulating state and then some global variable? Go to h... ;-)

A mixture? In no way better.

?

So exceptions are a more fundamental concept than OOP but OOP builds upon them in a natural way.


答:
Every unnamed number that's not immediately obvious from context is a magic number.  Its a little silly to define numbers that have meaning that is immediately obvious from context.

In django (python web framework), I may define some database field with a raw number like:

```<code>firstname = models.CharField(max_length=40)
middlename = models.CharField(max_length=40)
lastname =  models.CharField(max_length=40)
</code>```

which is clearer (and the recommended practice ) than say

```<code>MAX_LENGTH_NAME = 40
...
firstname = models.CharField(max_length=MAX_LENGTH_NAME)
middlename = models.CharField(max_length=MAX_LENGTH_NAME)
lastname =  models.CharField(max_length=MAX_LENGTH_NAME)
</code>```

as I'm unlikely to ever need to change the length (and can always compare to the max_length of the field).  If I do need to change the length of the field after initially deploying the application, I need to change it in exactly one location per field in my django code, and then additionally write a migration to change the schema of the DB.  If I ever need to reference max_length of a defined field of a type of object, I can do it directly -- if those fields were defining a Person class, I can use Person._meta.get_field('firstname').max_length to obtain the max_length being used (which is defined in one place).  The fact that the same 40 was used for multiple fields is irrelevant as I may want to change them independently.  The length of firstname should never depend on the length of middlename or lastname; they are separate values and can change independently.

Often array indices can use unnamed numbers; like if I have a CSV file of data that I want to put in a python dictionary, with the first element in the row as the dictionary key I would write:

```<code>mydict = {}
for row in csv.reader(f):
    mydict[row[0]] = row[1:]
</code>```

Sure I could name index_column = 0 and do something like:

```<code>index_col = 0
mydict = {}
for row in csv.reader(f):
    mydict[row[index_col]] = row[:index_col] + row[index_col+1:]
</code>```

or worse define after_index_col = index_col + 1 to get rid of the index_col+1, but that doesn't make the code clearer in my view.  Also, if I give the index_col a name, I better make the code work even if the column is not 0 (hence the row[:index_col] + part).

Title: Is every number in the code considered a "magic number"?

Body:
So every number in the code that we are sending to a method as an argument is considered as a Magic Number?
To me, it shouldn't.  I think if some number is let's say it is for minimum length of user name and we start using "6" in the code...then yeah we have a maintenance problem and here "6" is a magic number....but if we are calling a method that one of its arguments accept an integer for example as the ith member of a collection and then we pass "0" to that method call, in this case I don't see that "0" as a magic number.
What do you think?</p>

Body:
Every unnamed number that's not immediately obvious from context is a magic number.  Its a little silly to define numbers that have meaning that is immediately obvious from context.

In django (python web framework), I may define some database field with a raw number like:

firstname = models.CharField(max_length=40)
middlename = models.CharField(max_length=40)
lastname =  models.CharField(max_length=40)

which is clearer (and the recommended practice ) than say

MAX_LENGTH_NAME = 40
...
firstname = models.CharField(max_length=MAX_LENGTH_NAME)
middlename = models.CharField(max_length=MAX_LENGTH_NAME)
lastname =  models.CharField(max_length=MAX_LENGTH_NAME)

as I'm unlikely to ever need to change the length (and can always compare to the max_length of the field).  If I do need to change the length of the field after initially deploying the application, I need to change it in exactly one location per field in my django code, and then additionally write a migration to change the schema of the DB.  If I ever need to reference max_length of a defined field of a type of object, I can do it directly -- if those fields were defining a Person class, I can use Person._meta.get_field('firstname').max_length to obtain the max_length being used (which is defined in one place).  The fact that the same 40 was used for multiple fields is irrelevant as I may want to change them independently.  The length of firstname should never depend on the length of middlename or lastname; they are separate values and can change independently.

Often array indices can use unnamed numbers; like if I have a CSV file of data that I want to put in a python dictionary, with the first element in the row as the dictionary key I would write:

mydict = {}
for row in csv.reader(f):
    mydict[row[0]] = row[1:]

Sure I could name index_column = 0 and do something like:

index_col = 0
mydict = {}
for row in csv.reader(f):
    mydict[row[index_col]] = row[:index_col] + row[index_col+1:]

or worse define after_index_col = index_col + 1 to get rid of the index_col+1, but that doesn't make the code clearer in my view.  Also, if I give the index_col a name, I better make the code work even if the column is not 0 (hence the row[:index_col] + part).


问:
Want some architecture input to help with current requirements and future (unknown) requirements :-)
BACKGROUND: I am starting to architect a web project using asp.net mvc.

I'm going to use a very common architecture where I have the following layers:

Service

Biz

Data

Domain

The Service layer interacts with the Biz, Data and Domain layers.  The mvc controllers will have the service layer injected into them using a DI framework.  The controllers will need to be aware of the Service layer interfaces and will reference the Domain objects (POCOs).

The front end will be HTML5 + Javascript.

I have been told to keep in mind we need to expose portions of this website to mobile devices.  The portions to expose via mobile devices is to be defined :-).

When rendering the site I can simply have a mobile layout that renders to a mobile device.  But one thing management told me is mobile users might want additional functionality the website doesn't expose.

Maybe they want to access a feature that only a native mobile application can provide.  Hey,  I don't make up these requirements, this is what I was told :-).

THOUGHTS:   My service layer is the gateway to storing objects in my database.

For any potential native mobile devices I was thinking about using the Web API to wrap my service layer.

What I want to do NOW is focus on on my asp.net mvc application and only worry about native mobile apps when those requirements become more defined.

QUESTION: would it provide any benefits to code the Web API layer now and have my mvc controllers use it?

Pros for creating the Web API now

It will be coded and ready if / when a native mobile app comes online.

Cons for creating the Web API now

It is overhead that is not needed, especially if I host the WebAPI in a seperate process or another site besides my original asp.net mvc site.

The technology is fairly new and enhancemens will be forthcoming.  If i wait until later some of the issues will be fixed.

Who knows,  my users may never want a native mobile device and the feature is never utilized.

The code becomes more complex because of having to maintain the web api layer now.

I'm looking at not worrying about the Web API layer for now and simply coding it when necessary.

Typically I don't worry about writing for functionality that is yet to be defined.   But I thought it might not hurt to ask, you never know what some brilliant maverick programmer is doing out in the wild :-).

答:
I totally agree with the YAGNI approach, however, I see the YWBFI or You Will Benefit From It (just made that up) "principle?" sneaking in. Accessing data / objects from a Service layer through a URL "schema" will give you great flexibility, and the Web API is literally just some attributes you put on your existing / highly usable classes and you get great RESTful routing, which again provides great flexibility.

I would build as much into an API type access layer, and then each client can decide for themselves how to implement the API, including your own apps.

Since utilizing the WEB API functionality is so simple, I don't see how much overhead it could really add compared to the benefits you'll receive both short term and long term.


问:
How to document a dual open source license?
If a project is dual-licensed GPL & BSD, should there be one LICENSE file with the text of both licenses? Or two separate files, one for each license?

And I think I should put a copyright/license comment at the top of each source file. How should that comment indicate the dual-licensed status of the project?

答:
Multi-licensing allows recipients to choose from the defined list of licenses. Common practices are to provide a separate file for each license. When stating the license under which the project is being offered, make it clear that it is dual-licensed (here's an example: https://github.com/lojjic/PIE/blob/master/LICENSE)

You will also need to include your copyright statement at the top of the source (sample format: "Copyright © [year of completion] [entity name]. All rights reserved.")

Entente Software LLC (www.ententesoftware.com)


答:
I would consider your WebAPI layer to be a (non-graphical) user interface layer, equal to the MVC layer.

Put as much of the non-UI code in the Service layer (or below) as possible, and write the MVC layer to access it, keeping the MVC controllers as absolutely thin as you can.

Then, later, when you want to provide access to mobile (or other) clients, write your WebAPI layer to access the same Service layer, keeping the WebAPI controllers as thin as possible, exposing only the features you want to expose through the API.

I would not bother writing your MVC layer to access the Service layer through the WebAPI. I don't see the point, as long as all of the common business logic is in the Service layer; You don't really gain anything (except another layer of indirection).

The WebAPI piece will be relatively quick to write, assuming you've written your Service layer well during the MVC-building phase.

Title: Want some architecture input to help with current requirements and future (unknown) requirements :-)

Body:
BACKGROUND: I am starting to architect a web project using asp.net mvc.

I'm going to use a very common architecture where I have the following layers:

Service

Biz

Data

Domain

The Service layer interacts with the Biz, Data and Domain layers.  The mvc controllers will have the service layer injected into them using a DI framework.  The controllers will need to be aware of the Service layer interfaces and will reference the Domain objects (POCOs).

The front end will be HTML5 + Javascript.

I have been told to keep in mind we need to expose portions of this website to mobile devices.  The portions to expose via mobile devices is to be defined :-).

When rendering the site I can simply have a mobile layout that renders to a mobile device.  But one thing management told me is mobile users might want additional functionality the website doesn't expose.

Maybe they want to access a feature that only a native mobile application can provide.  Hey,  I don't make up these requirements, this is what I was told :-).

THOUGHTS:   My service layer is the gateway to storing objects in my database.

For any potential native mobile devices I was thinking about using the Web API to wrap my service layer.

What I want to do NOW is focus on on my asp.net mvc application and only worry about native mobile apps when those requirements become more defined.

QUESTION: would it provide any benefits to code the Web API layer now and have my mvc controllers use it?

Pros for creating the Web API now

It will be coded and ready if / when a native mobile app comes online.

Cons for creating the Web API now

It is overhead that is not needed, especially if I host the WebAPI in a seperate process or another site besides my original asp.net mvc site.

The technology is fairly new and enhancemens will be forthcoming.  If i wait until later some of the issues will be fixed.

Who knows,  my users may never want a native mobile device and the feature is never utilized.

The code becomes more complex because of having to maintain the web api layer now.

I'm looking at not worrying about the Web API layer for now and simply coding it when necessary.

Typically I don't worry about writing for functionality that is yet to be defined.   But I thought it might not hurt to ask, you never know what some brilliant maverick programmer is doing out in the wild :-).


答:
Everything we do in software should be about the user. Design, coding, testing, documentation... Everything goes toward enabling the end user to accomplish their task.

Knowing your users, and knowing for which users a feature is for, is crucial for making good decisions. Your story card is usually not a detailed specification. It should be emough to start a conversation with the product owner, but there are still decisions to be made during development. Knowing your users helps you make those decisions.

Title: Does the use of personas in Agile have any value during implementation?

Body:
This is about the use of personas, primarily in the agile development realm.

What value, if any, do personas give during implementation?

On agile modeling, the discussion about personas remains in the context of requirements investigation.

On wikipedia, the benefits are described to "assist with brainstorming, use case specification, and features definition."

I'm familiar with personas in use while writing user stories such as the following:

As Willow, I want ordering a combo meal to give me the option to select alternate sides.

  As Xander, I want the default side to be selected when I order a combo meal.

In these examples, Willow is the nutrition-conscientious user of meal-ordering software and Xander is the hungry, impatient user that thinks "fast food should be fast."

When coming up with these requirements, it may have been helpful to have the personas in mind. I imagine a possible discussion:

Person 1: Willow needs to have more options than fries for the combo meal, otherwise she would never order a combo.

  Person 2: But Xander doesn't want to have to sift through different options when ordering a combo! He just wants fries and he'll probably always want fries.

This discussion may have created the two requirements above, but once the requirements have been created, why do we mark each requirement with a persona? I wouldn't code the 'default side' requirement any differently knowing that it is for Xander. What value does retaining the "As Willow" and "As Xander" starts to the requirements once they have been written? What value does the persona give to the one who implements the requirement?


答:
Probably the simplest example of personas being important in actual coding is the story "As an Administrator, I must be able to assign security roles to other Users". The unspoken requirement here is that personas other than Administrators must not be able to do this same thing.

Personas, where differentiated, are thus very important in coding, if for no other reason at all than because they identify the persona that can or cannot use the system to perform a certain action.


问:
Shipping my first class library. Any gotchas I need to be aware of?
I'm a Web Developer about to unlock the "First Class Library Published" achievement in my career and I'm sweating bullets (I was up all night stressing out).  I'd love to tap the experience of the community to see if anyone has any suggestions or recommendations for making sure this goes as smoothly as possible.  Are there any specifics or gotchas I need to be aware of?  Anything special about the build process that can come back to bite me?

Here's where I'm at:

Library is unit tested and has approx 97% code coverage

API is well documented and xml docs for intellisense support have been created

I've ensured that public/private class accessors are accurate and correct. The same goes for all getters/setters

Error handling isn't as graceful as I'd like it to be, but I'm up against a deadline and have accepted that its an "as good as its going to be" for now

No friendly logging.  Debug.Writeline was used extensively...I've learned recently that this is a reflection of my inexperience :(

Your advice is greatly appreciated!

The library will be used to generate reports.  Standard hat -- connects to readonly database, performs calcs, formats and outputs data to response stream.

I was tapped as a fringe resource to fill in for one of the programmers that quit, and this task was given to me as a "cut your teeth" project.  The class library is going to be released for other programmers in the company to use while they write production code.

答:
Lock-in the API

The art of effectively building an API is as much about managing expectations as it is about structure.

When I say API I'm specifically referring to how the public/internal classes/methods are named and what their access level is (ie private/public/internal).

If you're worried that the code may not be completely ready for prime-time you could always initially publish it as beta.

Releases:

Beta (ie pre 1.0)

may contain multiple API breaking changes

may lack backwards-compatibility changes between versions

may have a lack of polish

Official (1.0+)

API is locked in until the next major release

any changes introduced should guarantee backward compatibility

Minor (ex 1.1)

contain bug-fixes and-or feature implementations

may add-to but not take away from the defined API

If you think the API needs to be battle-hardened some then release it for a while as beta. That signals that it is available for use but shouldn't be used for production and/or mission-critical code.

Many people treat numbered versioning schemes like hogwash but when they're used effectively they can be used to provide some wiggle room until you get the structure sorted out.

Your assumptions about how it will be used are wrong

No matter how well something is designed, people will find a way to abuse or create an alternate use.

One way to handle this is to lock down as much of the implementation as possible using accessors (ie private/public/internal) but no amount of design or engineering will give you as much insight as releasing the code to the users.

It really doesn't matter how 'perfect' you think your code can become, your users will prove that it's not.

I would argue that this is the primary reason why it's always better to use an existing codebase rather than do a full rewrite. At best a complete rewrite will trim the bloat but there's a high likelihood that the new codebase will contain as many (and possibly more) bugs as the original codebase.

In your case you're battle-hardening from scratch so you might as well get started.

It sounds like you have the rest of your bases covered. API documentation is vital and tests will be good for ensuring stability when changes are made in the future.

Implementing a consistent logging scheme will be important before the code is released for production because you'll need a way to globally enable/disable/filter the logs. BTW, in most cases logging only really involves importing a library and changing the output calls from Debug.WriteLine() to something like Logging.Debug(), Logging.Info(), Logging.Error(). The logger itself just provides a standard implementation for configuration, filtering, and a wider range of output schemes (ex files, console, etc).

Other than that, I'd look to get the code out and being used. Even if only by a small number of users to start.


问:
Establishing an API to provide end-user apps/scripts access to multiple types of databases

Question and Context

I am currently working on a project where the main question is, how do we insert an API between the database and end-users who may develop applications/scripts of their own that will work with or on top of the database?

The database type I am working with is Postgresql, and this project is in-house, so the end-users are users in other development groups.

Aims

What I am looking to satisfy are the following:

Avoid a wide-interface.

Require authentication from the application that is to use the API - provide end-user a single unique token or key to access the application.  No user/password management.

Have the option to make it open - no authentication required.

Allow users to create and read records.

Restrict users from deleting and updating existing records.

(Optional) Track who is using the API - number of requests, records, etc.

(Optional) Track amount of time spent completing a request.

Some Thoughts

My initial thought is to establish a RESTful API by building my own servlet to handle the requests, and of course, customize it to meet my aims.  However, I have a feeling there are already many versions of this wheel out there so I would like to avoid reinventing it.

An additional question to this would be, what is this kind of API/layer called (aside from DAL)?

Update

How would the advantages of putting a common API in place be if there are multiple databases of varying types e.g. postgres, ms sql, oracle, etc.?

答:
My initial thought is to establish a RESTful API by building my own servlet to handle the requests, and of course, customize it to meet my aims. However, I have a feeling there are already many versions of this wheel out there so I would like to avoid reinventing it.

There probably are but REST APIs are like Database ORMs, they can potentially speed up development a bit but they come with overhead and most of the work will still be focused in defining your interfaces.

Your best bet is to pick a low-level server platform that allows you to control routing, requests, and responses directly (ie URIs + GET/POST/PUT/DELETE).

In fact, if you take some time to read up on the HATEOAS approach to REST APIs you will start to realize how simple and powerful REST can be if fully utilized. Resist the urge to use hacky Ruby-style REST anti-patterns.

Update:

Here's a good link to some good REST anti-pattern examples.

By Ruby-style REST anti-patterns I'm referring to unnecessarily creating URIs for specific actions.

For the URI:

```<code>// a URI representing a post
example.org/post/456
// another URI representing a post edit
example.org/post/456/edit
</code>```

As opposed to using POST (ie create), PUT (ie update), DELETE (ie remove).

Another example is the the blog anti-pattern:

```<code>// filter by date
example.com/posts/2012/12/1/
// load by ID
example.com/posts/id/456
// load by title
example.com/posts/title/example-post-title
</code>```

Basically, what this is searching and returning the first instance that matches the date parameters. The RESTful way to do a filter is by using a querystring on the URI.

```<code>// the post uri represents a post
example.com/post/456
// the posts uri represents a filtered list of posts
// think of a filtered ATOM feed
example.com/posts?date=12/12/1
example.com/posts?title=example-post-title
</code>```

Ruby was one of the first widespread platforms that enabled custom/advanced routing schemes without obscure configurations like apache mod_rewrite. Unfortunately, at the time a lot of people started considering custom routing schemes RESTful when then don't really follow the definition.

The idea is that a there should be a single URI representing each resource. Resources are created via POST, updated via PUT, read/filtered via GET, etc... Funneling everything through GET/POST and/or creating URIs to represent actions on other URIs are common but not ideal.

Transforms can be handled using MIME-Types:

```<code>example.org/post/456+json
</code>```

Note: Also, don't forget to send the response with the correct Content-Type in the header so the client knows how to handle it. In this case the Content-Type would be 'application/json'.

Authentication can be very simple if you don't need a complicated ACL. Just create a Controller base class where POST/PUT/DELETE requests all require authentication. GET requests are usually read-only.

The differences may seem trivial but imagine REST as a class interface. Everything that inherits it is expected to act in a manner that complies with the interface definition. Breaking the pattern means breaking the interface contract at which point the abstraction leaks. Every anti-pattern you implement will then need to be re-implemented on every client and the interface becomes implementation-specific.

Optional:

Analytics Tracking:

Tracking is just as easy. Setup a URI for the tracker that's setup to accept POST requests. When you send the response to the user, send a second response to the tracker URI with the user's agent info in the body.

```<code>// POST tracking info to this URI with user agent info in the body
example.org/tracking/
</code>```

Request Time Tracking:

This really depends. Do you want the time from the request is received by the server and a response is sent? If that's the case, just mark Date.now() at the start of the controller, do it again after the response is sent, and compare the two.

Body:
My initial thought is to establish a RESTful API by building my own servlet to handle the requests, and of course, customize it to meet my aims. However, I have a feeling there are already many versions of this wheel out there so I would like to avoid reinventing it.

There probably are but REST APIs are like Database ORMs, they can potentially speed up development a bit but they come with overhead and most of the work will still be focused in defining your interfaces.

Your best bet is to pick a low-level server platform that allows you to control routing, requests, and responses directly (ie URIs + GET/POST/PUT/DELETE).

In fact, if you take some time to read up on the HATEOAS approach to REST APIs you will start to realize how simple and powerful REST can be if fully utilized. Resist the urge to use hacky Ruby-style REST anti-patterns.

Update:

Here's a good link to some good REST anti-pattern examples.

By Ruby-style REST anti-patterns I'm referring to unnecessarily creating URIs for specific actions.

For the URI:

// a URI representing a post
example.org/post/456
// another URI representing a post edit
example.org/post/456/edit

As opposed to using POST (ie create), PUT (ie update), DELETE (ie remove).

Another example is the the blog anti-pattern:

// filter by date
example.com/posts/2012/12/1/
// load by ID
example.com/posts/id/456
// load by title
example.com/posts/title/example-post-title

Basically, what this is searching and returning the first instance that matches the date parameters. The RESTful way to do a filter is by using a querystring on the URI.

// the post uri represents a post
example.com/post/456
// the posts uri represents a filtered list of posts
// think of a filtered ATOM feed
example.com/posts?date=12/12/1
example.com/posts?title=example-post-title

Ruby was one of the first widespread platforms that enabled custom/advanced routing schemes without obscure configurations like apache mod_rewrite. Unfortunately, at the time a lot of people started considering custom routing schemes RESTful when then don't really follow the definition.

The idea is that a there should be a single URI representing each resource. Resources are created via POST, updated via PUT, read/filtered via GET, etc... Funneling everything through GET/POST and/or creating URIs to represent actions on other URIs are common but not ideal.

Transforms can be handled using MIME-Types:

example.org/post/456+json

Note: Also, don't forget to send the response with the correct Content-Type in the header so the client knows how to handle it. In this case the Content-Type would be 'application/json'.

Authentication can be very simple if you don't need a complicated ACL. Just create a Controller base class where POST/PUT/DELETE requests all require authentication. GET requests are usually read-only.

The differences may seem trivial but imagine REST as a class interface. Everything that inherits it is expected to act in a manner that complies with the interface definition. Breaking the pattern means breaking the interface contract at which point the abstraction leaks. Every anti-pattern you implement will then need to be re-implemented on every client and the interface becomes implementation-specific.

Optional:

Analytics Tracking:

Tracking is just as easy. Setup a URI for the tracker that's setup to accept POST requests. When you send the response to the user, send a second response to the tracker URI with the user's agent info in the body.

// POST tracking info to this URI with user agent info in the body
example.org/tracking/

Request Time Tracking:

This really depends. Do you want the time from the request is received by the server and a response is sent? If that's the case, just mark Date.now() at the start of the controller, do it again after the response is sent, and compare the two.


答:
This may sound flippant but its not. Why not use SQL.

It covers all the bases in your requirements.

```<code>Avoid a wide-interface.
       -- SQL is wide by default but there are some tricks you can use to narrow it down.
Require authentication from the application that is to use the API.
       -- Postgres comes with strong authentication and fine grained security.
Allow users to create and read records.
       -- Just "GRANT" them the privilege.
Restrict users from deleting and updating existing records.
       -- Do not grant them the privilege.
(Optional) Track who is using the API - number of requests, records, etc.
       -- Postgres will log most of this.
(Optional) Track amount of time spent completing a request.
       -- Possible with some low level trickery.
</code>```

If you do go down this route I would strongly recommend you expose only views to your external users. In fact you should consider views as an Interface definition, which
would allow you to modify the underlying implementation without affecting you users.

Title: Establishing an API to provide end-user apps/scripts access to multiple types of databases

Body:
Question and Context

I am currently working on a project where the main question is, how do we insert an API between the database and end-users who may develop applications/scripts of their own that will work with or on top of the database?

The database type I am working with is Postgresql, and this project is in-house, so the end-users are users in other development groups.

Aims

What I am looking to satisfy are the following:

Avoid a wide-interface.

Require authentication from the application that is to use the API - provide end-user a single unique token or key to access the application.  No user/password management.

Have the option to make it open - no authentication required.

Allow users to create and read records.

Restrict users from deleting and updating existing records.

(Optional) Track who is using the API - number of requests, records, etc.

(Optional) Track amount of time spent completing a request.

Some Thoughts

My initial thought is to establish a RESTful API by building my own servlet to handle the requests, and of course, customize it to meet my aims.  However, I have a feeling there are already many versions of this wheel out there so I would like to avoid reinventing it.

An additional question to this would be, what is this kind of API/layer called (aside from DAL)?

Update

How would the advantages of putting a common API in place be if there are multiple databases of varying types e.g. postgres, ms sql, oracle, etc.?

Body:
This may sound flippant but its not. Why not use SQL.

It covers all the bases in your requirements.

Avoid a wide-interface.
       -- SQL is wide by default but there are some tricks you can use to narrow it down.
Require authentication from the application that is to use the API.
       -- Postgres comes with strong authentication and fine grained security.
Allow users to create and read records.
       -- Just "GRANT" them the privilege.
Restrict users from deleting and updating existing records.
       -- Do not grant them the privilege.
(Optional) Track who is using the API - number of requests, records, etc.
       -- Postgres will log most of this.
(Optional) Track amount of time spent completing a request.
       -- Possible with some low level trickery.

If you do go down this route I would strongly recommend you expose only views to your external users. In fact you should consider views as an Interface definition, which
would allow you to modify the underlying implementation without affecting you users.


问:
R vs Python for data analysis
I have been programming for about a year and I am really interested in data analysis and machine learning. I am taking part in a couple of online courses and am reading a couple of books.

Everything I am doing uses either R or Python and I am looking for suggestions on whether or not I should concentrate on one language (and if so which) or carry on with both; do they complement each other?

-- I should mention that I use C# in school but am familiar with Python through self-study.

答:
So, I have primarily done data analysis in Matlab, but have done some in Python (and more used Python for general purpose) and also I've started a bit of R. I am going to go against the grain here and suggest you use Python. The reason why is because you are doing data analysis from a Machine Learning perspective, not stats (where R is dominant) or digital signal processing (where Matlab is dominant).

There is obviously heavy overlap between Machine Learning and Stats. But overlap is not identity. Machine Learning uses ideas from CS that I for one would not want to implement in R. Sure, you can compute a minimal spanning tree in R. It may look like an ugly mess though. Machine learning people will assume you have easy access to hash tables, binary search trees, and so on. It is easier in my mind to implement a stats algorithm afresh when necessary, than to try to shoehorn what is basically a domain specific language into a general programming language.

The side benefits of Python for data analysis are much higher too. You will learn a real programming language at the same time, which can handle scripting, create larger applications, etc. R is really a niche language of the stats community, even Matlab is far more widely used.

I guess, I would look at some of the papers first, and see in what language they post code. If it's not in R, then don't use it.

Title: R vs Python for data analysis


问:
Why is the UI of nowadays application getting so "plain"?
Take a look at Google, Windows 8, etc.

Why does everything look so plain now? Looks really ugly to me.

Is it all because of smartphones and tablets?

Do I have to follow that trend?

答:
It's for simplicity's sake, and no, you do not have to follow that trend. </p>

<p>I suggest that you do conduct your own usability tests and work from there.  </p>

Body:
It's for simplicity's sake, and no, you do not have to follow that trend.

I suggest that you do conduct your own usability tests and work from there.


答:
I'd like to bring the opinion that I heard from a professor at the university I study in and from my sister who is a graphic designer (surprisingly they had the same opinion though their professions have very little in common).

They say that the plainer the interface is, the harder is to make it look good. With the shiny and volume stuff that Windows 7 has, it is very easy to make things look "cool" without any much effort. This means that it doesn't matter if you are a professional or an amateur _ your application has a big chance to look good. You could compare this with drawing with pencils and with felt pen.

Besides, plain applications look more simple and intuitive, which is very important since no one likes to read big instructions in order to be able to use an application.

Title: Why is the UI of nowadays application getting so "plain"?

Body:
Take a look at Google, Windows 8, etc.

Why does everything look so plain now? Looks really ugly to me.

Is it all because of smartphones and tablets?

Do I have to follow that trend?


问:
How do you approach database design?
I am primarily a web developer and I have a couple of personal projects which I want to kick off.

One thing that is bugging me is database design. I have gone through in school db normalization and stuff like that but it has been a couple of years ago and I have never had experience with relational database design except for school.

So how you do you approach database from a web app perspective? How do you begin and what do you look out for? What are flags for caution?

答: I design my database schema first, then use an ORM to create the objects from it.  I'm a bit old school that way; I don't trust ORM's to create an intelligent, efficient database schema.  That is the work of humans, and part of the craft of software design.</p>

Title: How do you approach database design?


问:
What's a schrödinbug?
This wiki page tells :

A schrödinbug is a bug that manifests only after someone reading
  source code or using the program in an unusual way notices that it
  never should have worked in the first place, at which point the
  program promptly stops working for everybody until fixed. The Jargon
  File adds: "Though... this sounds impossible, it happens; some
  programs have harbored latent schrödinbugs for years."

What is being talked about is very vague..

Can someone provide an example of how a schrödinbug is like (like with a fictional / real-life situation)?

答:
A corollary to the Schrödinbug is the Heisenbug - which describes a bug that disappears (or occasionally appears) when attempting to investigate and/or fix it.

Heisenbugs are mythical clever little blighters that run and hide when a debugger is loaded, but come out of the woodwork once you've stopped watching.

In reality, these are usually seem to be caused by one or other of the following:

the impact that optimization, where code compiled with -DDEBUG is optimized to a different level from the release build

subtle timing differences due to real-world communication buses or interrupts being subtly different from simulated "perfect" dummy loads

Both highlight the importance of testing release code on release equipment, as well as unit/module/system test using emulators.

Title: What's a schrödinbug?


答:
I think a big part of it is reducing visual noise. The less "Stuff" there is on the screen, the less complicated the program feels, and users' sense of confidence in their ability to grasp the software increases. This was as true in the 90's as it is today, but the reason you're noticing it now is that we are starting to re-evaluate our assumptions about which UI elements are necessary and which are just training wheels which we as users outgrown.

A classic example is visual borders. Visual borders were used much more extensively in the past than they are used today. In the 90s they served the purpose of spelling out to users how information is organized. While grouping items together creates a sense of organization in itself, the convention that grouping is most likely intentional is not necessarily a conclusion you'll jump to. It's something you need to arrive to by examining the screen for signs that confirm this suspicion, and that's effort. Visual borders were used to reaffirm that the groupings are intentional, and to emphasize the apparent structure of the program. Nowadays we've mostly outgrown visual borders as necessary training wheels; people will readily assume the grouping is intentional and meaningful, and will even expect it. In fact, people don't even need pressable items to look pressable, they can infer from context that this text/flat box can be clicked on to have effect. You may be asking yourself "but does the button have to be flat?", and the answer is that if you want to maximize visual simplicity: it does. A plain blue rectangle over white background is one change from blue to white. A plain blue rectangle surrounded by a black border, placed over white background is two changes: from blue to black and to white. Add shadows, and you get a third change.

I also believe that developers are starting to assume less expertise on the user's part. For example, a typical rationalization for not putting in yet another button on the interface is that we ask ourselves "will this be something the user will have to actively ignore 90% of the time?". If that's the case, then the user's ability to find the button they do need is reduced, because it's hidden in a bigger collection of buttons. In the 90's the average developer would probably think "well, once the user does know where their button is, this problem disappears. They do not need to search for it anymore", and this is a point of view that assumes the user can be expected to rise up to some standard of familiarity with the program. Nowadays we prefer not to assume this. We prefer to create software that will also be usable by the most clueless user possible, that sees the program for the first time, or even sees a program for the first time. This is definitely a business-oriented constraint. We live in a world where high end technology is being targeted at mainstream markets. It's not a niche anymore, it's not only aimed towards high earners or hobbyists. A $400 iPhone can be a present to your grandma. She should be able to figure it out, and if you care about her figuring it out, you should pay attention to the trend.

Your feelings of dissonance are understandable but not warranted. Simplicity and function are not necessarily mutually exclusive. Stack Overflow is simple compared to the UI cacophonies that many news sites are, but it's also useful. The iPod when it came out was simpler in terms of hardware buttons than other players, but it was just as capable. The average smartphone app has less buttons at any screen than old Symbian phones had (before the advent of touch screens), yet they are easier to use and more capable. In short, there's a difference between function and design. They're not strongly coupled (perhaps loosely coupled, but not strongly). When you understand that, most reservations about the simplification of UIs go away. It's a paradigm shift, not a step back.


答:
Fancy interfaces tend to start looking extremely cluttered very quickly. Interfaces that require a lot of components must be plain for that reason. Were those buttons all to have flashy bling effects on rolling over them, textured edges with frilly gold trim, maybe even sound effects (and yes, I've seen all that and more) the application becomes impossible to use productively.

And productivity is what most applications (including most websites) are all about. Not everything is a game, get used to it. I don't want a cluttered, fancy looking, user interface. I want something that's instantly and intuitively useful to me, where my eye is guided to the most common components simply by their size and placement, where the rest is tugged away where it's easy to find yet does not intrude on my more common tasks.

Hence Google with its simple layout of an input box with 2 large buttons underneath. And hence the light grey colour of the comment and tag links here (among other things).


问:
Is this statement from Knuth's fundamental algorithms still applicable today?

In a sense, 10! (ten factorial) represents an approximate dividing
  line between things which are practical to compute and things which
  are not.

This is from Knuth's TAOCP Fundamental Algorithms book (1973).
Is this still a valid statement or has computing power rendered it obsolete ?

答:
It is still reasonable.

10! = 3,628,880.  Every step after that goes up by AT LEAST an order of magnitude.

```<code>(fact 10)
3628800

(fact 11)
39916800 -- about 40 million

(fact 12)
479001600 -- almost 500 million

(fact 13.0)
6227020800.0 -- over 6 billion
</code>```

Pretty soon, you're talking about Congressional spending numbers.

Body:
It is still reasonable.

10! = 3,628,880.  Every step after that goes up by AT LEAST an order of magnitude.

(fact 10)
3628800

(fact 11)
39916800 -- about 40 million

(fact 12)
479001600 -- almost 500 million

(fact 13.0)
6227020800.0 -- over 6 billion

Pretty soon, you're talking about Congressional spending numbers.


问:
What is the aim of software testing?
Having read many books, there is a basic contradiction:

Some say, "the goal of testing is to find bugs" while other say "the goal of the testing is to equalize the quality of the product", meaning that bugs are its by-products.

I would also agree that if testing would be aimed primarily on a bug hunt, who would do the actual verification and actually provide the information that the software is ready?

Even e.g. Kaner changed his original definition of testing goal from bug hunting to quality assessment provision but I still cannot see the clear difference. I perceive both as equally important.

I can verify software by its specification to make sure it works and in that case, bugs found are just by products. But also I perform tests just to break things.

Also what definition is more accurate?

Note above I am primarily referring to software testing as a process.

答:
A software with a great quality is, among other things, a software with 0 (or very few) bugs. So a bug hunting is a process to improve the quality.

A software which meets all its features is also a great quality software, so testing to validate the features is a process to improve the quality.

A software which a good user experience is a great quality software, and so on...

Well, I think the aim of sotware testing is to improve the quality, then you can do some bug hunting tests, some validation and verification of features, some tests on UI, etc.

Title: What is the aim of software testing?


答:
Here's a real Schrödinbug I saw in some system code. A root daemon needs to communicate with a kernel module. So the kernel code creates some file descriptors:

```<code>int pipeFDs[1];
</code>```

then sets up communication over a pipe that will be attached to a named pipe:

```<code>int pipeResult = pipe(pipeFDs);
</code>```

This shouldn't work. pipe() writes two file descriptors into the array, but there's only space for one. But for about seven years it did work; the array happened to be before some unused space in memory that got coopted into being a file descriptor.

Then, one day, I had to port the code to a new architecture. It stopped working, and the bug that never should have worked was discovered.

Title: What's a schrödinbug?

Body:
This wiki page tells :

A schrödinbug is a bug that manifests only after someone reading
  source code or using the program in an unusual way notices that it
  never should have worked in the first place, at which point the
  program promptly stops working for everybody until fixed. The Jargon
  File adds: "Though... this sounds impossible, it happens; some
  programs have harbored latent schrödinbugs for years."

What is being talked about is very vague..

Can someone provide an example of how a schrödinbug is like (like with a fictional / real-life situation)?

Body:
Here's a real Schrödinbug I saw in some system code. A root daemon needs to communicate with a kernel module. So the kernel code creates some file descriptors:

int pipeFDs[1];

then sets up communication over a pipe that will be attached to a named pipe:

int pipeResult = pipe(pipeFDs);

This shouldn't work. pipe() writes two file descriptors into the array, but there's only space for one. But for about seven years it did work; the array happened to be before some unused space in memory that got coopted into being a file descriptor.

Then, one day, I had to port the code to a new architecture. It stopped working, and the bug that never should have worked was discovered.


问:
Is looking at random code snippets useful to quickly determine the quality of a project?
To get an idea of the quality of a project that I've never seen before (usually open source projects that I'm considering whether or not to use), I often start by opening random files and eyeballing fine details of the code.

I look for things like:

Style (does it follow accepted conventions for the language and is it consistent)

Quality and consistency of comments

Common language specific gotchas (e.g. consistently not using === in javascript)

Does it look logically structured

I find this gives me a good idea of the skill of the developer/s that wrote the code, even if I know absolutely nothing about what the code is meant to be doing.

Do people think this is useful? What does one need to take into account for quickly assessing the quality of a project's code base, assuming no knowledge of how it actually works?

答:
Yes, I think that it's a good idea. Projects which are poorly written is more likely to get abandoned.

But don't base your decision just on that. imho source code history and number of committers are a far more important factor.


答:
I think this method rather reveals styling skills and the ability of making code readable, but it tells nothing about logical, analytical, problem-solving skills of the developer(s) working on the code.

So when you analyse code this way, you gain information only about how "good" the code looks and whether it is readable or not. But still you have no idea if the code is optimized, if it works well, if it well structured, etc.

The characteristics you pay attention on are very important. They show if the code is readable and maintainable. But there are many programmers who give excellent solutions but don't really pay attention to comments and styling (which I thinks is much easier to learn than programming itself).

Title: Is looking at random code snippets useful to quickly determine the quality of a project?

Body:
To get an idea of the quality of a project that I've never seen before (usually open source projects that I'm considering whether or not to use), I often start by opening random files and eyeballing fine details of the code.

I look for things like:

Style (does it follow accepted conventions for the language and is it consistent)

Quality and consistency of comments

Common language specific gotchas (e.g. consistently not using === in javascript)

Does it look logically structured

I find this gives me a good idea of the skill of the developer/s that wrote the code, even if I know absolutely nothing about what the code is meant to be doing.

Do people think this is useful? What does one need to take into account for quickly assessing the quality of a project's code base, assuming no knowledge of how it actually works?


答:
If you make only one pick, you're likely doing it wrong. :) Other than that this is essentially a random sampling, a pretty respectable approach to gather information in cases like you describe. For more scientific details on how this could be done, study about Monte Carlo method.

Regarding things to look for, consider finding, studying and tailoring to your specific needs some tried and true code-review checklist.

Some other aspects worth considering when evaluating a project are listed below (check list summarized from my past experience):

Releases (along with changelog), versioning and publishing discipline

It's generally much easier to investigate issues when one can tell bug was found in release 1.2.3, avaiable for download at some URL than oh two years ago someone sent me a mail with attached binary.

Developer documentation, API reference and code examples

Helps to avoid efforts wasted on reinventing the wheel and learning basics by trial and error.

Note these can be also randomly sampled for a quick study.

Bug tracking

If there's no tracking at all, it's a huge red flag; if there's one, consider quickly checking it using the same random sampling approach as you do for source code

Positive feedback

Find out about project users and try to do a random sampling study of their feedback.


问:
Language agnostic programming books
Are there any great programming or software development books that are language agnostic?  Why should I read it?</p>

答:
The Pragmatic Programmer: From Journeyman to Master - Andrew Hunt and David Thomas

This book is all about how to write code that works and is maintainable. A key concept is being practical. Everything in the book is boiled down to 70 tips that are easy to remember that help you deliver better, higher-quality software.

Title: Language agnostic programming books


问:
Do people in non-English-speaking countries code in English?
I've heard it said (by coworkers) that everyone "codes in English" regardless of where they're from. I find that difficult to believe, however I wouldn't be surprised if, for most programming languages, the supported character set is relatively narrow.

Have you ever worked in a country where English is not the primary language?

If so, what did their code look like?

答:
I'm form Quebec and I saw a lot of programmers prefer to code in English. I got a good quote for you.

Let them program in English and you will see they don't know English.

So you could find gems like :

```<code>//putting the conter to 0
i=0
</code>```

In clear, it's better to code in your native language if you don't master the target language. otherwise, it's just obfuscate the code.

Body:
I'm form Quebec and I saw a lot of programmers prefer to code in English. I got a good quote for you.

Let them program in English and you will see they don't know English.

So you could find gems like :

//putting the conter to 0
i=0

In clear, it's better to code in your native language if you don't master the target language. otherwise, it's just obfuscate the code.


答:
How easy would it be for me to fix a bug in this code?

Whenever I encounter a new code base I ask myself that question.

Quickly familiarising myself with the code enables me to identify common ground with the developer(s) who created it. I tend to look for the following (in no particular order):

consistent use of naming conventions

an aversion to making code complex - adhering to the KISS principle

unit tests that work out of the box

a short readme file that describes the project with helpful hints to understanding

good comments

use of design patterns where appropriate

consistent style in comments and code layout

use of well-known and respected supporting libraries (e.g. Boost, Guava etc)

presence of language idioms

The more of the above are present then the more confidence I have in the skills and experience of the developers so that when the inevitable WTF?! moment occurs I am much more inclined to look to myself for a lack of understanding of the problem domain than assume that the original developer has made an error.


问:
Developing a GPL replacement from public documentation. Any legal problems?
In a program I am developing, I need to use an improved ListView. The ObjectListView seems to satisfy my needs, except it is GPL and thus unusable in my commercial application. I believe, however, that we can develop our own replacement in-house, using the documentation from the site, without looking at the code.

Is there any legal risk in doing so? Does our control need to be GPL or any other license restrictions?

答:
There will sort of always be legal risk whatever you do. But relating to your scenario, not so long ago Oracle sued Google claiming that Google had infringed their copyright by implementing several Java APIs. Oracle lost and the judge said

So long as the specific code used to implement a method is different, anyone is free under the Copyright Act to write his or her
  own code to carry out exactly the same function or specification of
  any methods used in the Java API. It does not matter that the
  declaration or method header lines are identical. Under the rules of
  Java, they must be identical to declare a method specifying the same
  functionality - even when the implementation is different.

What you describe seems similar and from that perspective it should be OK for you to write your own implementation of ObjectListView.


答: unless the samples are many and large, there's a very good chance you'll not going to get a good cross section of the codebase. You could end up with either the few good pieces or the few bad apples quite easily.</p>


问:
Difference between daemon and child thread?
As per my knowledge daemon thread is a thread that runs in background(low priority thread) and also a child thread runs in the background when the parent thread runs foreground so where does the difference lie between a child and a daemon thread?

It's in case of java and can you explain referring to other languages too.

答:
Java does not use the term child thread.

A thread is either a daemon-thread or a non-daemon-thread.

A non-daemon-thread must be stopped manually and keeps the VM running as long as the thread is running.

A daemon-thread cannot keep the VM running. When the VM stops all daemon-threads will stop running.

You can group threads together with a ThreadGroup. Groups can itself be grouped together that means that you can have a parent and a child ThreadGroups.

The priority of a thread has nothing to do with the explained concepts of threads. Any thread can have any priority.

For other languages/OS I cannot tell how the concepts are there.


问:
How to structure unit testing of huge libraries?
I am writing unit tests for a library written in Qt/C++.

The library is rather big, with lots of functionalities. I have a separate unitTest folder which I have my UnitTest.cpp in there. Having all test case / unit tests in the same file, makes it one very big .cpp file.

I was wondering what is the best approach to unit test huge libraries. Should I have different UnitTest.cpp files in different folder? Like one for every class? or every name space?

答:
As you already discovered, putting all unit tests into one huge file is not a good practice (same as putting all classes into one file is bad as well, although it compiles a bit faster).

You should create a subdirectory unittests where all unit tests go. It should be one file per class. This way you do not clutter your code with unit tests.

If you can, split your big library into several small libraries (each in it's own directory). Each should have it's own namespace, and directory structure (main directory where the code is, and two subdirectories: one for unit tests, and other for mock classes).


问:
How to verify data from localStorage on a server
On my mobile app, I am storing the username of a logged in person, and downloading some data for the given/stored username. When the user checks for updates to his data content on the server, the server dishes out a delta of the content, based on the username. The app then updates its local display accordingly.

The problem is, since I am using localStorage, there is no guarantee that someone will not edit the username stored locally and try to request data meant for someone else.

What would be the best way of getting around this possible security hole? Please comment on this method that I am planning to implement:

Each time you login, a random string is generated and stored for future checking in a database, along with your username, and date/time of request.

Whenever a request to download data for a username comes in, it must be accompanied by the string from the previous attempt. Also, each fresh update for the client is accompanied by a new random string, which is stored in the database and the old one is deemed expired.

If the random string is not provided correctly, the user is logged out of the mobile app (as this could potentially be someone tampering with the app).

The advantage I see for this method is that I have an audit trail as well for later verification and forensics. What are the flaws?

答:
I suppose you need some sort of session which does not expire fast (say lasts a couple of weeks). In most mobile apps I have used you have to "create account" and login at the first time (maybe imitating their web counterparts) and then an occasional log in after some time or after a firmware update erases local storage.

Alternatively you can have the user provide to you a public key keeping the private. You can then encrypt the data with the public and the mobile phone will have to decrypt them using the local stored private key (which would bring the issue of how you persist the private key from firmware update erases). I would also consider a hybrid (public key from password): http://www.rsa.com/rsalabs/node.asp?id=2127