答:
Your concerns are valid. You're using a strongly typed language, yet venturing into a weakly-typed or untyped area.  It happens, but this kind of error/constraint checking you're asking about (if nicely addressed) will increase maintainability by returning you to the benefits of being more strongly typed.

What I would probably do is analyze the template to see which variables it mentions.  So you can have a notion of a regular template, and also, a counterpart notion of an analyzed template that additionally has a list of required variables that need to be bound in order to instantiate.  Such analysis might plausibly be automated, or manually done with adornments, for example if you add type information not present in the template.

On the other hand, annotating the template (text) itself with type information might be a good approach, as it would allow automation in developing the analyzed template counterpart that has the variables listed.

Then you can have a notion of instantiation of the analyzed template, which can demand (or fail on lack of) the right variables.  (You can also check, if desired, whether some variables being supplied are not even used.)

I'm not sure from you question whether your concern goes more to the type of the various variables rather than making sure they are all supplied (say, more or less untyped).

In essence, I'd like to change the enum into a class (maybe a base class and set of classes, one for each template even) that is/are more descriptive of what is required regarding variables.

If you go far enough with changing the enum into classes, you might just find passing class(template)-specific (constructor) parameters instead of a dictionary to be workable.

As you're in C# (and presumably Visual Studio), you might use a T4 template to generate the classes of interest from some prototype .tt file, depending on how you like to author your templates.  This can work really nicely to provide proper OOP classes and types that you want from relatively easily edited data definitions.

Title: Alternatives to using dictionary in parameters in C#?

Body:
I have a method that takes in a dictionary and enum value and produces a string output. Enum value defines what template string to insert the dictionary key value pairs into.

```<code>public string InsertVariables(MessageType type, Dictionary<string, string> variables) { }
</code>```

It works fine, but every time I use it, I find that it's hard to know what I should add to variables to make sure all tokens in the template are replaced and I have to glance at the templates every time.

What I was thinking would work as solution in this case is enforcing proper values added to variables during compilation time like so:

```<code>public abstract class MessageVariables { }

public class NewUserMessageVariables : MessageVariables {
    // different values go here parameters go here instantiated in the constructor
}

public string InsertVariables(MessageType type, MessageVariables variables) {
    // converts variables object into dictionary for future insertion into the template.
}
</code>```

This seems to enforce having all parameters required in the messages.

I have about 16 messages with possibility to having a few more later.

QUESTION: Is this an overkill and I should stick to using dictionary?


问:
Optimizing and caching frequently accessed but rarely updated Tables
My app has some tables that will be rarely updated, probably just once in the beginning and at the system setup. Despite that, they will be frequently accessed. Almost every operation depends on querying them, but as I said they will not be changed.

I'm looking for advices for optimizing this web app.

I have defined indexes on most frequently searched columns. What else can I do? How should I cache this tables?

It's written in ASP.NET MVC and Entity Framework.

答:
Disclaimer: I am more familiar with standard LAMP  stack or equivalent frameworks.

If you have exhausted all the optimizations you can do at the db level (including  enabling query caches etc..), you could cache the results using memcache or equivalent in the windows world.

As you have infrequent updates, it seems like a good candidate to use a cluster of memcache servers (to distribute the load) - it is a simple key-value store and memcached servers listen on tcp (or udp) sockets, and it is very easy to setup, debug etc..:

http://memcached.org/

ContentLicense: CC BY-SA 3.0


问:
Changing requirements mid-sprint
I am in the middle of an agile sprint. Midway we realize that the requirement that we were working upon, could have been done in an easier fashion in a totally different way. The development work done on the current requirement wont be needed at all or needs to be changed totally. How is this handled in Agile? Even if we do communicate timeline and impact changes what is the formal method of handling this.</p>

答: Generally, the product owner would create a new story that describe new requirements and you would estimate and prioritize the new story as any other story.</p>

Title: Changing requirements mid-sprint


问:
Has variable width types been replaced by fixed types in modern C?
I came across an interesting point today in a review over on Code Review. @Veedrac recommened in this answer that variable size types (e.g. int and long) be replaced with fixed size types like uint64_t and uint32_t. Citation from the comments of that answer:

The sizes of int and long (and thus the values they can hold) are
  platform-dependent. On the other hand, int32_t is always 32 bits long.
  Using int just means that your code works differently on different
  platforms, which is generally not what you want.

The reasoning behind the standard not fixing the common types is partially explained here by @supercat. C was written to be portable across architectures, in contrary to assembly which was usually used for systems programming at the time.

I think the design intention was originally that each type other than
  int be the smallest thing that could handle numbers of various sizes,
  and that int be the most practical "general-purpose" size that could
  handle +/-32767.

As for me, I've always used int and not really worried about the alternatives. I've always thought that it is the most type with best performance, end of story. The only place I thought fixed width would be useful is when encoding data for storage or for transfer over a network. I've rarely seen fixed width types in code written by others either.

Am I stuck in the 70s or is there actually a rationale for using int in the era of C99 and beyond?

答:
For values closely related to pointers (and thus, to the amount of addressable memory) such as buffer sizes, array indexes, and Windows' lParam, it makes sense to have an integer type with an architecture-dependent size.  So, variable-sized types are still useful.  This is why we have the typedefs size_t, ptrdiff_t, intptr_t, etc.  They have to be typedefs because none of the built-in C integer types need be pointer-sized.

So the question is really whether char, short, int, long, and long long are still useful.

IME, it's still common for C and C++ programs to use int for most things.  And most of the time (i.e., when your numbers are in the range ± 32 767 and you don't have rigorous performance requirements), this works just fine.

But what if you need to work with numbers in the 17-32 bit range (like the populations of large cities)?  You could use int, but that would be hard-coding a platform dependency.  If you want to strictly adhere to the standard, you could use long, which is guaranteed to be at least 32 bits.

The problem is that the C standard doesn't specify any maximum size for an integer type.  There are implementations on which long is 64 bits, which doubles your memory usage.  And if these longs happen to be elements of an array with millions of items, you'll thrash memory like crazy.

So, neither int nor long is a suitable type to use here if you want your program to be both cross-platform and memory-efficient.  Enter int_least32_t.

Your I16L32 compiler gives you a 32-bit long, avoiding the truncation problems of int

Your I32L64 compiler gives you a 32-bit int, avoiding the wasted memory of the 64-bit long.

Your I36L72 compiler gives you a 36-bit int

OTOH, suppose you don't need huge numbers or huge arrays but you have a need for speed.  And int may be large enough on all platforms, but it isn't necessarily the fastest type: 64-bit systems usually still have 32-bit int.  But you can use int_fast16_t and get the “fastest” type, whether it's int, long, or long long.

So, there are practical use cases for the types from <stdint.h>.  The standard integer types don't mean anything.  Especially long, which may be 32 or 64 bits, and may or may not be large enough to hold a pointer, depending on the whim of the compiler writers.


问:
Avoid FileUtil that is made for tests
I'm constantly creating util classes like Files to be able to mock files functionality in tests.

It is convenient but violates basic idea - don't modify production code to comply with tests. I could also prepare test directory with test files but it is also sounds like not proper unit testing.

Are there good approach how to tackle this problem?

UPD

Here is example that illustrates the approach:

```<code>public class FileUtil {
    public File[] listFiles(String pathToFolder) {
        return new File(pathToFolder).listfiles();
    }
}

public class CSVImporter {
    ...
    public CSVImporter(FileUtil files) {
       ...
    }
    ...
    public void import(String pathToFolder) {
        File[] files = files.listfiles(pathToFolder);
        ...
    }
}
</code>```

答:
First, there is nothing wrong in modifying your production code if it becomes more testable that way.

What you ask depends on how your production code looks like and how it deals with files. If it just opens a file, works with the file stream and closes the file again, separate the "Open/Close file" part and implement the remaining "core" part in terms of streams. That way, you can replace the file stream by a memory stream for testing purposes, and create that memory stream "on the fly" in your unit tests.

To your edit: somewhere in your CSVImporter class is a method like

  void importFile(File file){
      FileStreamReader fsr = new FileStreamReader(file);
      // do something with fsr
  }
```

<p>Refactor the <code>do something with fsr</code> part into a function with just an <code>InputStreamReader</code> as a parameter.</p>

<pre class="lang-java prettyprint-override"><code>void importFile(File file){
     FileStreamReader fsr = new FileStreamReader(file);
     importStream(fsr);
}
void importStream(InputStreamReader isr)
{
    // here is the core logic, which is useful to be tested in a unit test
}
</code>```

Now make this method public or at least only package private, and test it by providing an InputStreamReader with data from memory:

 // somewhere in your unit test:
 isr = new InputStreamReader(new ByteArrayInputStream(...)) ;
 csvImporter.importStream(isr);
```

(and for testing the file processing logic, do not create unit tests - create separated, automatic integration tests instead, utilizing some real files).

Title: Avoid FileUtil that is made for tests

Body:
First, there is nothing wrong in modifying your production code if it becomes more testable that way.

What you ask depends on how your production code looks like and how it deals with files. If it just opens a file, works with the file stream and closes the file again, separate the "Open/Close file" part and implement the remaining "core" part in terms of streams. That way, you can replace the file stream by a memory stream for testing purposes, and create that memory stream "on the fly" in your unit tests.

To your edit: somewhere in your CSVImporter class is a method like

  void importFile(File file){
      FileStreamReader fsr = new FileStreamReader(file);
      // do something with fsr
  }

Refactor the do something with fsr part into a function with just an InputStreamReader as a parameter.

void importFile(File file){
     FileStreamReader fsr = new FileStreamReader(file);
     importStream(fsr);
}
void importStream(InputStreamReader isr)
{
    // here is the core logic, which is useful to be tested in a unit test
}

Now make this method public or at least only package private, and test it by providing an InputStreamReader with data from memory:

 // somewhere in your unit test:
 isr = new InputStreamReader(new ByteArrayInputStream(...)) ;
 csvImporter.importStream(isr);

(and for testing the file processing logic, do not create unit tests - create separated, automatic integration tests instead, utilizing some real files).


答:
Modifying code to be able to test it has nothing wrong. In fact, one of the points of TDD and unit testing in general is to encourage you to write a more maintainable code.

On the other hand, your example illustrates integration, system or functional testing, not unit testing. In unit testing, tests are as independent of the environment as possible, which, in your case, means that you are not expected to create a test directory with test files in it for the purpose of the unit test (unless your unit test is specifically focusing on a class which reads files).

You have already done the first step of introducing Dependency Injection in CSVImporter when it comes to FileUtil, and this is great. The next step is to create a stub FileUtilStub which implements IFileUtil interface, but doesn't do anything with real files: it merely returns demo data. For example, when listing files, it may return ["file1.txt", "file2.txt"], and when reading any file, it may return Hello,World.

Now come the edge cases. Since you are testing CSV stuff, what if you create a different stub FileUtilEmptyFileStub which returns an empty string when required to load a file? A FileUtilEmptyListStub may return an empty list of files. Others may return files which are very long, or files with Unicode characters, etc., to know how your class handles those cases.

A further refactoring may consist of creating a stub which takes the list of files and file contents as a parameter. This makes it possible to write less code while putting all the relevant code within the body of the unit test itself:

public void TestEmptyList()
{
    var stub = new FileUtilStub([], "hello,world");
    var importer = new CSVImporter(stub);
    // Do something with the importer and assert.
}

public void TestListWithNewlineInNames()
{
    var stub = new FileUtilStub(["file\n.txt"], "hello,world");
    var importer = new CSVImporter(stub);
    // Do something with the importer and assert.
}

...
```

Title: Avoid FileUtil that is made for tests

Body:
I'm constantly creating util classes like Files to be able to mock files functionality in tests.

It is convenient but violates basic idea - don't modify production code to comply with tests. I could also prepare test directory with test files but it is also sounds like not proper unit testing.

Are there good approach how to tackle this problem?

UPD

Here is example that illustrates the approach:

```<code>public class FileUtil {
    public File[] listFiles(String pathToFolder) {
        return new File(pathToFolder).listfiles();
    }
}

public class CSVImporter {
    ...
    public CSVImporter(FileUtil files) {
       ...
    }
    ...
    public void import(String pathToFolder) {
        File[] files = files.listfiles(pathToFolder);
        ...
    }
}
</code>```


问:
Efficiently find whether Binary Search Tree is Height Balanced or not?
A binary tree is height balanced if and only if the two subtrees of root are height balanced and the difference between the two subtrees height is at most 1.

I implemented a code in java to find whether a binary search tree is height balanced or not. I did it this way:

Recursively call the function isBalanced(Node) starting with root and the base condition being if node is null return true. But to calculate height of a subtree rooted at Node x, I have to call a separate function getHeight(Node) on that node and use this function to get and compare the height of two subtrees of a node and return a boolean value accordingly.

But this separate function call is making my code inefficient,because in case of skew tree when every node has one child this function will cause my program's time complexity to be O(N^2), N being number of vertices.

What I want to know is is there a way to remove this separate function call and still get the work done, so that I can have a linear time algorithm.

Here is my java code.

```<code>class BST
{
 public Node insert(Node x,int key)
 {
     if(x==null)
      return new Node(key,null,null);
     else if(key>x.key)
     {
         x.right=insert(x.right,key);
         return x;
     }
     else if(key<x.key)
     {
         x.left=insert(x.left,key);
         return x;
     }
     else {x.key=key;return x;}
 }
 public boolean isBalanced(Node root)
 {
     if(root==null)
      return true;
     else
     {
         if(isBalanced(root.left)&&isBalanced(root.right))
         {
             if(Math.abs(getHeight(root.left)-getHeight(root.right))<=1)
              return true;
             else return false;
         }
         else return false;
     }
 }
 public int getHeight(Node x)
 {
     return BFS(x,0);
 }
 public int BFS(Node x,int h)
 {
     if(x==null)
      return h;
     return Math.max(BFS(x.right,h+1),BFS(x.left,h+1));
 }
 public static void main(String []args)
 {
     BST tree1=new BST();
     Node root=null;
     root=tree1.insert(root,14);
     root=tree1.insert(root,16);
     root=tree1.insert(root,5);
     root=tree1.insert(root,3);
     root=tree1.insert(root,12);
     root=tree1.insert(root,10);
     root=tree1.insert(root,13);
     root=tree1.insert(root,20);
     root=tree1.insert(root,18);
     root=tree1.insert(root,23);
     root=tree1.insert(root,15);
     System.out.println(tree1.isBalanced(root));
 }
}
class Node
{
 Node left,right;
 int key;
 Node(int key,Node left,Node right)
 {
  this.key=key;
  this.left=left;
  this.right=right;
 }
}
</code>```

I am reposting this question here because I got a no response on Stack Overflow.

答:
To calculate the height, you have to traverse tree, possibly by using recursion. To check that it is balanced, you have to traverse it exactly the same way. So these ways can probably be combined.

I am tired and can't think of a good name for such a function right now, and I have a feeling the solution is ugly and there is probably a better way. But, it will work.

Say we make a function find_height_and_balance, that returns -1 if the tree isn't balanced, and the tree's height if it is.

Something like:

```<code>int find_height_and_balance(node) {
    if (node == null) {
        return 0  // A leaf is balanced and height 0
    }

    int left = find_height_and_balance(node.left)
    if (left == -1) { return -1 }
    int right = find_height_and_balance(node.right)
    if (right == -1) { return -1 }

    if (Math.abs(left - right) > 1) {
        return -1  // The difference in heights is larger than 1
    }

    return max(left, right) + 1 # Return height
</code>```

(if the function name looks like Python, that's because I wrote Python first and then changed it...)

Edit: Note that your definition of 'balanced' and the test case in User's answer are different; this code checks for your definition, but I think the definition is wrong.

Body:
To calculate the height, you have to traverse tree, possibly by using recursion. To check that it is balanced, you have to traverse it exactly the same way. So these ways can probably be combined.

I am tired and can't think of a good name for such a function right now, and I have a feeling the solution is ugly and there is probably a better way. But, it will work.

Say we make a function find_height_and_balance, that returns -1 if the tree isn't balanced, and the tree's height if it is.

Something like:

int find_height_and_balance(node) {
    if (node == null) {
        return 0  // A leaf is balanced and height 0
    }

    int left = find_height_and_balance(node.left)
    if (left == -1) { return -1 }
    int right = find_height_and_balance(node.right)
    if (right == -1) { return -1 }

    if (Math.abs(left - right) > 1) {
        return -1  // The difference in heights is larger than 1
    }

    return max(left, right) + 1 # Return height

(if the function name looks like Python, that's because I wrote Python first and then changed it...)

Edit: Note that your definition of 'balanced' and the test case in User's answer are different; this code checks for your definition, but I think the definition is wrong.


问:
Should you write your back-end as an API?
I had a heated discussion today about our MVC application. We have a website written in MVC (ASP.NET), and it usually follows the pattern of do something in the view -> hit the controller -> controller builds a model (calls a Manager that gets the data, builds the model in the controller method itself) -> model goes to view -> rinse & repeat.

He said that our code was too tightly coupled. For example, if we wanted a desktop application as well, we would not be able to use our existing code.

The solution and best practice he said is to build an API, and then build your website on top of your API, and then building a desktop application, mobile app, etc. is very simple.

This seems like a bad idea to me for various reasons.

Anyway I can't seem to find anything by googling that might discuss this practice. Does anyone have any information about pros, cons, why you should, why you shouldn't or further reading?

Some reasons I think it's a bad idea:

It's way too abstract to run your backend off an API. You're trying to make it too flexible which will make it an unmanagable mess.

All the stuff built into MVC seems useless, like roles and authentication. For example, [Authorize] attributes and security; you will have to roll your own.

All your API calls will require security information attached, and you will have to develop a token system and whatnot.

You will have to write complete API calls for every single function your program will ever do. Pretty much every method you want to implement will need to be ran off an API. A Get/Update/Delete for every user, plus a variant for each other operation eg update user name, add user to a group, etc. etc. and each one would be a distinct API call.

You lose all kinds of tools like interfaces and abstract classes when it comes to APIs. Stuff like WCF has very tenuous support for interfaces.

You have a method that creates a user, or performs some task. If you want to create 50 users, you can just call it 50 times. When you decide to do this method as an API your local webserver can named-pipes connect to it and no problem - your desktop client can hit it too, but suddenly your bulk user creation will involve hammering the API over the Internet 50 times which isn't good. So you have to create a bulk method, but really you're just creating it for desktop clients. This way, you end up having to a) modify your API based on what's integrating with it, and you can't just directly integrate with it, b) do a lot more work to create an extra function.

YAGNI. Unless you're specifically planning to write two identically functioning applications, one web and one Windows application for example, it is a huge amount of extra development work.

Debugging is much harder when you can't step through end-to-end.

Lots of independent operations that will require lots of back and forth, for example some code might get the current user, check the user is in the administrator role, get the company the user belongs to, get a list of other members, send them all an email. That would require a lot of API calls, or writing a bespoke method the specific task you want, where that bespoke method's only benefit would be speed yet the downside would be it would be inflexible.

Probably some more reasons these are just off the top of my head.

It just seems to me like unless you really need two identical applications, then it's really not worth it. I've never seen an ASP.NET application built like this either, you'd have to write two separate applications (the API and your code) and version control them both as well (if your user page gets a new field, you'd have to update the API and your consuming code simultaneously to ensure no ill-effects or put lots of extra work into keeping it robust).

Edit: Some great responses, really starting to get a good idea of what this all means now. So to expand on my question, how would you structure an MVC app to follow this API structure?

For example, you have a website that displays info about a user. Under MVC, you have:

View - (CS)HTML page that displays a UserViewModel
Controller - Calls GetUser() and creates a UserViewModel that it passes to the view
Manager class (sort of your API) that has a GetUser method.

The controller does GetUser() but you want a desktop app too. This means your GetUser needs to be exposed via some kind of API. You might want a TCP connection, either WCF, or perhaps Remoting. You also want a mobile app which will be RESTful since persistent connections are flaky.

So would you then write an API for each one, a WCF web service that has a method GetUser() and the code just does return new UserManager().GetUser() ? And an mvc 4 web api method that does the same thing? While continuing to call GetUser directly in your MVC controller method?

Or would you choose the solution that would work for all three (web api REST service) and build everything on that, so all three apps make API calls (the mvc ones, to the local machine).

And is this just a theoretical perfect scenario? I can see large overheads in developing this way, especially if you have to develop in a way that will let you do operations in a RESTful manner. I think some of this has been covered in the replies.

Edit 2: After reading more stuff, I've put a comment below that I think might explain it. The question is a bit of a trick question I think. Should you write your back-end as an API had me confused thinking there should be a single webservice that everything (mvc app, desktop app, mobile app) calls to do stuff.

The conclusion I have come to is that what you should really do is make sure your business logic layer is correctly decoupled. Looking at my code, I do this already - the controller will call GetUser() on a manager, then create a view model from it to render with a View. So really, the business logic layer is an API. If you want to call it from a desktop app though, you'll need to write something like a WCF service to facilitate calling it. Even just having a WCF method called GetUser() that contains the code return MyBusinessLayer.GetUser() would be sufficient. So the API is the business logic, and WCF / web api etc. are just titbits of code to let external applications in to call it.

So there is some overhead, in that you have to wrap your business logic layer in different APIs depending on what you need, and you will have to write an API method for each operation you want your other apps to do, plus you will need to sort out a way to do authentication, but for the most part it's the same. Stick your business logic in a separate project (class library), and you will probably have no issue!

Hopefully this interpretation is correct. Thanks for all the discussion/comments it has generated.

答:
He said that our code was too tightly coupled. For example, if we wanted a desktop application as well, we would not be able to use our existing code.

Well, do you? If not, then that's a pretty irrelevant statement.

I'd say, if you were going to build a new application in 2015, then seriously look into something with a user interface that involves an API and not server generated HTML pages. There are clear costs but also clear benefits.

But if you have an existing site with no concrete plans to have several different interfaces (as far as I can tell), then his comments are just irrelevant.


问:
Where to store (data) classes for webservices
So I'm pretty new in my current company and my current task is to create a webservice that sends some serialized java objects from service A to service B using jaxws (webservices). The senior on the team encouraged me to copy (ctrl + c) the beans from project A into project B. I think this is not a good idea. As soon as some attribute would be added to a bean of project A, project B wouldn't know of this attribute.

So I could fail or just ignore it - that would be terrible.

So basically my question is what is the normals solution for this? I thought about a project C that is a dependency of project A and project B and holds all the beans that both project send to each other. In project C I could also test the serialization.

答:
Best pracrice is to use different classes on both sides of the service. After all if you were an external client consuming the service you would hardly have access to the service classes.

However, as you point out, that is a pain. I would share the data classes. perhape compile them and stick on an internal nuget repo?


答:
(I assume, you do not mean "in Agile", but more specifically "in Scrum" - otherwise asking for "what is the formal method" does not make much sense).

If the change is so essential that the work on the sprint, as it was planned, becomes nonsensical, the product owner should cancel the current sprint and initiate a new one (see, for example, here). Of course, he should dicuss the issue with the team first.

This is hopefully a situation which does not occur too frequently in your team.

Title: Changing requirements mid-sprint

Body: I am in the middle of an agile sprint. Midway we realize that the requirement that we were working upon, could have been done in an easier fashion in a totally different way. The development work done on the current requirement wont be needed at all or needs to be changed totally. How is this handled in Agile? Even if we do communicate timeline and impact changes what is the formal method of handling this.</p>


答:
It depends on the type of application and the type of market you are in.

There are trade-offs and benefits to going this way. It is not a clear-cut answer that one way is better than the other.

I'll talk from personal experience. I was the one who decided to take the codebase that I work on in this direction back in 2007. That codebase is somewhere in the order of a million lines of code now, half of which is server code hidden behind a massive amount of web service API's, the other half is a flotilla of clients, desktop native, desktop web, mobile, back-end integrations, etc... This decision was not without its downsides, but with 20/20 hindsight I can say I would do it again. Let me indicate some of the trade-offs involved.

Benefits

Flexibility. Whether it's a request to build a mobile app to augment the desktop experience, or a request to integrate with SAP's back-end, it all becomes easier when you already have an API to call. When you get enough of these requests, you will organically evolve towards an API, and the only question is whether that has a standard web service in front of it, or whether it is an internal API where the web services are tailor-made.

Scalability (of the team). In our case we have many different groups of developers all building on top of this API. We even have dedicated API teams, who talk to the different groups, summarize the needs, and construct an all-purpose API out of it. It's gotten to the point where we're not even told anymore that people are building stuff on top of the API, and not everyone who does that works for our company.

Security. Having a clear-cut division between the unsafe and safe parts of your codebase is helpful in reasoning out security. Muddling the UI and back-end code together tends to confuse matters.

Trade-offs

Flexibility. You have to do the work to "properly" build something into the API. It's not possible to quickly run a DB query from inside the UI code to solve a specific problem. Also, API's which are actually reusable must take so many use-cases into account that the quick solution is usually the wrong solution. The API becomes less flexible to evolve, especially since there is so much client-code already out there (we're transitioning to a versioned API for that reason).

Initial development speed. It is slower to develop API-first, without a shred of a doubt. You only win it back when you have enough clients built on top of the API. But then you find that you need 3 different client implementations before your API has evolved to be generic enough. We found that most of our initial API designs were wrong and have had to strongly revise our guidelines for how to build web services.

Red herrings

You mentioned a bunch of these. They don't actually matter in practice.

Abstraction. Your API becomes abstract enough to cover all use cases that your product needs to serve, and no more than that. Even without web services you'll either have an internal API which does this, or have lots of duplicate code. I prefer abstraction over duplication.

Abandoning the server-side MVC stack. These days almost every system will after a while need a mobile app. When you then build web services to cater to that mobile app, you will have to figure out how to do authentication and authorization in an API context anyway. It is actually less work when you only have one way of doing that, the way you do it in your web services.

Bulk operations. Typically solved by creating a bulk API which launches a back-end job and returns a job id for status querying. It's not that big of a deal.

Debugging. I found that on the whole it became slightly easier to troubleshoot the system. You can still set breakpoints in both front-end and back-end code, so in practice it's not that harder to step through, and you gain the ability to build automated api tests and to instrument the api for monitoring production systems.

Lots of independent operations. That's a matter of how you design things. If you insist on having a pure CRUD API, then yes, you will suffer from this issue. But having some CQRS API's to augment that is typically a good idea, and if you have made sure that you have an internal API for which the services are a front-end, then you can easily reuse that internal API to construct services for those specific scenario's.

In Summary

In a system that is used in enough different contexts, an API will naturally evolve as it is the easiest way to cater to all the needs. But there is definitely a case of YAGNI going on. There are trade-offs and it doesn't make sense until it makes sense. The key point is to not be dogmatic and to keep an open mind towards different approaches in architecture to meet the evolving needs of the product.

Title: Should you write your back-end as an API?

Body:
I had a heated discussion today about our MVC application. We have a website written in MVC (ASP.NET), and it usually follows the pattern of do something in the view -> hit the controller -> controller builds a model (calls a Manager that gets the data, builds the model in the controller method itself) -> model goes to view -> rinse & repeat.

He said that our code was too tightly coupled. For example, if we wanted a desktop application as well, we would not be able to use our existing code.

The solution and best practice he said is to build an API, and then build your website on top of your API, and then building a desktop application, mobile app, etc. is very simple.

This seems like a bad idea to me for various reasons.

Anyway I can't seem to find anything by googling that might discuss this practice. Does anyone have any information about pros, cons, why you should, why you shouldn't or further reading?

Some reasons I think it's a bad idea:

It's way too abstract to run your backend off an API. You're trying to make it too flexible which will make it an unmanagable mess.

All the stuff built into MVC seems useless, like roles and authentication. For example, [Authorize] attributes and security; you will have to roll your own.

All your API calls will require security information attached, and you will have to develop a token system and whatnot.

You will have to write complete API calls for every single function your program will ever do. Pretty much every method you want to implement will need to be ran off an API. A Get/Update/Delete for every user, plus a variant for each other operation eg update user name, add user to a group, etc. etc. and each one would be a distinct API call.

You lose all kinds of tools like interfaces and abstract classes when it comes to APIs. Stuff like WCF has very tenuous support for interfaces.

You have a method that creates a user, or performs some task. If you want to create 50 users, you can just call it 50 times. When you decide to do this method as an API your local webserver can named-pipes connect to it and no problem - your desktop client can hit it too, but suddenly your bulk user creation will involve hammering the API over the Internet 50 times which isn't good. So you have to create a bulk method, but really you're just creating it for desktop clients. This way, you end up having to a) modify your API based on what's integrating with it, and you can't just directly integrate with it, b) do a lot more work to create an extra function.

YAGNI. Unless you're specifically planning to write two identically functioning applications, one web and one Windows application for example, it is a huge amount of extra development work.

Debugging is much harder when you can't step through end-to-end.

Lots of independent operations that will require lots of back and forth, for example some code might get the current user, check the user is in the administrator role, get the company the user belongs to, get a list of other members, send them all an email. That would require a lot of API calls, or writing a bespoke method the specific task you want, where that bespoke method's only benefit would be speed yet the downside would be it would be inflexible.

Probably some more reasons these are just off the top of my head.

It just seems to me like unless you really need two identical applications, then it's really not worth it. I've never seen an ASP.NET application built like this either, you'd have to write two separate applications (the API and your code) and version control them both as well (if your user page gets a new field, you'd have to update the API and your consuming code simultaneously to ensure no ill-effects or put lots of extra work into keeping it robust).

Edit: Some great responses, really starting to get a good idea of what this all means now. So to expand on my question, how would you structure an MVC app to follow this API structure?

For example, you have a website that displays info about a user. Under MVC, you have:

View - (CS)HTML page that displays a UserViewModel
Controller - Calls GetUser() and creates a UserViewModel that it passes to the view
Manager class (sort of your API) that has a GetUser method.

The controller does GetUser() but you want a desktop app too. This means your GetUser needs to be exposed via some kind of API. You might want a TCP connection, either WCF, or perhaps Remoting. You also want a mobile app which will be RESTful since persistent connections are flaky.

So would you then write an API for each one, a WCF web service that has a method GetUser() and the code just does return new UserManager().GetUser() ? And an mvc 4 web api method that does the same thing? While continuing to call GetUser directly in your MVC controller method?

Or would you choose the solution that would work for all three (web api REST service) and build everything on that, so all three apps make API calls (the mvc ones, to the local machine).

And is this just a theoretical perfect scenario? I can see large overheads in developing this way, especially if you have to develop in a way that will let you do operations in a RESTful manner. I think some of this has been covered in the replies.

Edit 2: After reading more stuff, I've put a comment below that I think might explain it. The question is a bit of a trick question I think. Should you write your back-end as an API had me confused thinking there should be a single webservice that everything (mvc app, desktop app, mobile app) calls to do stuff.

The conclusion I have come to is that what you should really do is make sure your business logic layer is correctly decoupled. Looking at my code, I do this already - the controller will call GetUser() on a manager, then create a view model from it to render with a View. So really, the business logic layer is an API. If you want to call it from a desktop app though, you'll need to write something like a WCF service to facilitate calling it. Even just having a WCF method called GetUser() that contains the code return MyBusinessLayer.GetUser() would be sufficient. So the API is the business logic, and WCF / web api etc. are just titbits of code to let external applications in to call it.

So there is some overhead, in that you have to wrap your business logic layer in different APIs depending on what you need, and you will have to write an API method for each operation you want your other apps to do, plus you will need to sort out a way to do authentication, but for the most part it's the same. Stick your business logic in a separate project (class library), and you will probably have no issue!

Hopefully this interpretation is correct. Thanks for all the discussion/comments it has generated.


问:
Why is JavaScript not used for classical application development (compiled software)?
During my years of web development with JavaScript, I come to the conclusion that it's an incredible powerful language, and you can do amazing things with it.

It offers a rich set of features, like:

Dynamic typing

First-class functions

Nested functions

Closures

Functions as methods

Functions as Object constructors

Prototype-based

Objects-based (almost everything is an object)

Regex

Array and Object literals

It seems to me that almost everything can be achieved with this kind of language, you can also emulate OO programming, since it provides great freedom and many different coding styles.

With more software-oriented custom functionalities (I/O, FileSystem, Input devices, etc.) I think it will be great to develop applications with.

Though, as far as I know, it's only used in web development or in existing softwares as a scripting language only.

Only recently, maybe thanks to the V8 Engine, it's been used more for other kind of tasks (see node.js for example).

Why until now it's only be relegated only to web development? What is keeping it away from software development?

答:
Most languages in common use are more powerful and better designed than JavaScript. All the features you mention are supported by other dynamic languages like Python or Ruby which are overall better designed. And some of the features you mention are not necessarily desirable anyway - many would consider static typing with type inference preferable to dynamic typing, if you have the choice.

I'm not saying this to diss JavaScript. I quite enjoy working with JS when developing web. But looking at it objectively, JS has a number of drawbacks compared to other languages:

Numerous unfixable flaws. Many mistakes were made when initially developing JS. No need to enumerate them here, they are well documented. All languages have mistakes in the initial design which are later fixed. The difference with JS is that the language was developed and released far to quickly and these mistakes can never be fixed due to the requirement of backwards compatibility in browsers.

Extremely slow process for introducing improvements and new features. Since all browser vendors have to agree and might even for various political reasons want to slow down the development of the language. Look at C# which is actually a newer language than JS. When C# was introduced it didn't have eg. closures or higher order functions like JS, but after multiple iterations it now has all that and furthermore features like Linq and async syntax which JavaScript developers can only envy.

Impoverished standard library. Modern languages like Python, Ruby or anything based on Java or .net have extensive standard libraries for almost anything you could need. In JS you can't even read a file without 3rd party libraries. You mention Regex, but all modern languages have that and a thousand things more.

Other languages have caught up with the few JavaScript advantages. Features like closures and first-class functions were powerful when compared to clunky static languages like Java ten years ago, but dynamic and functional languages have long have had these features, and even Java, a pretty conservative language, has added this in Java 8.

The only feature which really sets JavaScript apart from other modern languages is prototype-based inheritance (as opposed to class-based), and the advantage of this model is dubious since everyone just use it to emulate class based inheritance anyway.

There is simply no reason to choose JavaScript if you have the option of choosing another modern language. Only reason would be if it was the only language you know.


问:
How to change the same code stored in several places after I improve one of them?
I have some code written in Matlab. I use the code in different folders which contains different data. Because I want to change some parameters for each different data, I keep the code in the folder of each data to remember what parameters I have used.

The problem is that sometimes I improve the code and it is hard to go to each folder and change that part of code. Is there any solution to this problem? It would be good if I change some part of the code then it changes in all other places I have stored the same code.

Would version control help with this problem?

答:
Version control is not the issue here. It's a fundamental principle of programming that says "Don't repeat yourself". It's a time-honored maxim, largely for exactly the reason you cite.

If at all possible, arrange things so that the logic you write lives in one place and one place only. I know nothing about Matlab, so I have no diea whether it's possible to include code from another file, cal subroutines, etc., but it's worth finding out.

If it definitely isn't possible to refactor your code to obey DRY, the next biggest principle applies: "Don't write code. Write programs that write code." In other words, write a tiny shell script/Perl app/whatever you like that generates all the variants of this code at once. Then, the next time you change something you only have to change it in the helper script. (You do have to remember to re-run the helper script - that's the price you pay for using a tool that doesn't allow you to practice proper DRYness.)

OwnerDisplayName: yashar


答:
The point of contention is not if you should use an API, but what an "API" actually is. The only alternative to using a designed API is to use an API which is a random mess of code. You write that an API makes things "too flexible" which in turn makes things unmanageable. This points to a complete and thorough misunderstanding of what an API is. If that misunderstanding is not shared between you and your coworker, then you wasted a lot of time by arguing over completely different things.

By not using a well-defined API you can do whatever you want. By definition this is the most flexible option. Also, by definition "do whatever you want" is still an API.
The only job of an API is to remove flexibility. By removing flexibility a good API encourages a user to do similar things in similar ways.

Of course a bad API can either provide too much or too little flexibility, or even both at the same time. A really poorly designed API can kill a project even faster than the "anything goes" approach. However, best practice is simply to have competent programmers who develop and evolve the API alongside your application.

Example

•Lots of independent operations that will require lots of back and
  forth, for example some code might get the current user, check the
  user is in the administrator role, get the company the user belongs
  to, get a list of other members, send them all an email. That would
  require a lot of API calls, or writing a bespoke method the specific
  task you want, where that bespoke method's only benefit would be speed
  yet the downside would be it would be inflexible.

The number of API calls this would require on a decent API would probably be 1. Yes, it's inflexible, but why would you want it to be flexible?


问:
Does this code follow duck typing?

The principle of duck typing says that you shouldn't care what type of object you have - just whether or not you can do the required action with your object. For this reason the isinstance keyword is frowned upon. - -Definition

In below snippet(function) group_tweets_by_state, following definition of duck typing, action setdefault is performed on the object tweets_by_state by appending object tweet

```<code>def group_tweets_by_state(tweets):
    tweets_by_state = {}
    USA_states_center_position = {n: find_center(s) for n, s in us_states.items()}
    for tweet in tweets:                     # tweets are list of dictionaries
        if hassattr(tweet, 'setdefault'):    # tweet is a dictionary
            state_name_key = find_closest_state(tweet, USA_states_center_position)
            tweets_by_state.setdefault(state_name_key, []).append(tweet)
    return tweets_by_state
</code>```

My understanding is, function hasattr(tweet, 'setdefault') is type checking tweet to be of <class 'dict'> type in duck typing style, before append.

Is my understanding correct? Does function group_tweets_by_state follow duck typing?

答:
First, I want to say that by far not everybody agrees that duck typing is a good thing at all, let alone that it is some sort of holy principle that should be followed. Often duck typing leads to error prone, hard to debug code, although it can be very flexible in how you can use it.

Duck typing just takes an object and does with the object what it wants to do E.g. if it expects an open file object that it wants to call .write() on, then it just does that. If that throws an exception because the object doesn't have that method, then you passed in a non-duck. Your fault. If you passed in a completely different kind of object that also works because it has a .write(), that is the benefit of duck typing.

So your code would use "duck typing" if it simply assumes that tweets is a list of dictionaries (like the comment says), and doesn't go to any trouble to check that.

```<code>def group_tweets_by_state(tweets):
    tweets_by_state = {}
    USA_states_center_position = {n: find_center(s) for n, s in us_states.items()}
    for tweet in tweets:                     # tweets are list of dictionaries
        state_name_key = find_closest_state(tweet, USA_states_center_position)
        tweets_by_state.setdefault(state_name_key, []).append(tweet)
    return tweets_by_state
</code>```

Title: Does this code follow duck typing?

Body:
First, I want to say that by far not everybody agrees that duck typing is a good thing at all, let alone that it is some sort of holy principle that should be followed. Often duck typing leads to error prone, hard to debug code, although it can be very flexible in how you can use it.

Duck typing just takes an object and does with the object what it wants to do E.g. if it expects an open file object that it wants to call .write() on, then it just does that. If that throws an exception because the object doesn't have that method, then you passed in a non-duck. Your fault. If you passed in a completely different kind of object that also works because it has a .write(), that is the benefit of duck typing.

So your code would use "duck typing" if it simply assumes that tweets is a list of dictionaries (like the comment says), and doesn't go to any trouble to check that.

def group_tweets_by_state(tweets):
    tweets_by_state = {}
    USA_states_center_position = {n: find_center(s) for n, s in us_states.items()}
    for tweet in tweets:                     # tweets are list of dictionaries
        state_name_key = find_closest_state(tweet, USA_states_center_position)
        tweets_by_state.setdefault(state_name_key, []).append(tweet)
    return tweets_by_state


问:
Is anything in programming truly evil?
So, there are a bunch of questions appearing asking is X evil, is Y evil.

My view is that there are no language constructs, algorithms or whatever which are evil, just ones which are badly used.  Hell, if you look hard enough there are even valid uses of goto.

So does absolute evil, that is something which is utterly incompatible with best practice in all instances, exist in programming?  And if so what is it?  Or is it just bad programmers not knowing when something is appropriate?

Edit: To be clear, I'm not talking about things programmers do (such as not checking return codes or not using version control - they're choices made by bad programmers), I mean tools, languages, statements, whatever which are just bad...

答:
Programming, per se, I think, is not inherently evil. However, programming is very often a social activity, and disrespecting those around you can be very evil. People often forget that most code is going to be shared with others; mostly read, sometimes written too. Be it open source, a product that a company is releasing, or a small piece of patching up a consultant is hired for, programs are going to be read.

That's half the reason why so many "considered harmful" articles exist, or why people say "never". Making life difficult for others is the very root of all evil. Isn't it?

ContentLicense: CC BY-SA 2.5

Title: Is anything in programming truly evil?


答:
A test like hassattr(tweet, 'setdefault') to make sure tweet is a dictionary is not a good one, since it obviously does not assure tweet provides all methods/properties of a dictionary. So as long tweet.setdefault is not the only method called by find_closest_state (which I think is unlikely), this test is not strict enough. On the other hand, a test like isinstance(tweet, dict) is too strict, because it forbids the usage of other, dictionary-like structures, which is exactly the idea of duck typing.

In your example the requirement is not really that tweet is a dictionary, the requirement is that find_closest_state can process the tweet, whatever methods it calls from a tweet, independently of the real type. The following solution will handle this in a generic manner, without the need of knowing exactly what methods inside find_closest_state are used:

```<code>def group_tweets_by_state(tweets):
    tweets_by_state = {}
    USA_states_center_position = {n: find_center(s) for n, s in us_states.items()}
    for tweet in tweets:              # a  tweet should behave like a dictionary
        try:
            state_name_key = find_closest_state(tweet, USA_states_center_position)
            tweets_by_state.setdefault(state_name_key, []).append(tweet)
        except (AttributeError, TypeError):
            pass
    return tweets_by_state
</code>```

The code checks for an AttributeError because that is the exception you get when find_closest_state calls a method not provided by tweet. It also checks for a TypeError, because that is what you get when you call tweet["abc"] on a non-dictionary. You may need to add some other exceptions, depending on how find_closest_state is implemented internally, but you should not add any artificial constraints.

And that's how duck typing should really be applied - by not making assumptions about the type of the object passed, only by testing whether or not you can do the required action (here: call find_closest_state without getting one of the above exceptions).

Title: Does this code follow duck typing?

Body:
The principle of duck typing says that you shouldn't care what type of object you have - just whether or not you can do the required action with your object. For this reason the isinstance keyword is frowned upon. - -Definition

In below snippet(function) group_tweets_by_state, following definition of duck typing, action setdefault is performed on the object tweets_by_state by appending object tweet

```<code>def group_tweets_by_state(tweets):
    tweets_by_state = {}
    USA_states_center_position = {n: find_center(s) for n, s in us_states.items()}
    for tweet in tweets:                     # tweets are list of dictionaries
        if hassattr(tweet, 'setdefault'):    # tweet is a dictionary
            state_name_key = find_closest_state(tweet, USA_states_center_position)
            tweets_by_state.setdefault(state_name_key, []).append(tweet)
    return tweets_by_state
</code>```

My understanding is, function hasattr(tweet, 'setdefault') is type checking tweet to be of <class 'dict'> type in duck typing style, before append.

Is my understanding correct? Does function group_tweets_by_state follow duck typing?

Body:
A test like hassattr(tweet, 'setdefault') to make sure tweet is a dictionary is not a good one, since it obviously does not assure tweet provides all methods/properties of a dictionary. So as long tweet.setdefault is not the only method called by find_closest_state (which I think is unlikely), this test is not strict enough. On the other hand, a test like isinstance(tweet, dict) is too strict, because it forbids the usage of other, dictionary-like structures, which is exactly the idea of duck typing.

In your example the requirement is not really that tweet is a dictionary, the requirement is that find_closest_state can process the tweet, whatever methods it calls from a tweet, independently of the real type. The following solution will handle this in a generic manner, without the need of knowing exactly what methods inside find_closest_state are used:

def group_tweets_by_state(tweets):
    tweets_by_state = {}
    USA_states_center_position = {n: find_center(s) for n, s in us_states.items()}
    for tweet in tweets:              # a  tweet should behave like a dictionary
        try:
            state_name_key = find_closest_state(tweet, USA_states_center_position)
            tweets_by_state.setdefault(state_name_key, []).append(tweet)
        except (AttributeError, TypeError):
            pass
    return tweets_by_state

The code checks for an AttributeError because that is the exception you get when find_closest_state calls a method not provided by tweet. It also checks for a TypeError, because that is what you get when you call tweet["abc"] on a non-dictionary. You may need to add some other exceptions, depending on how find_closest_state is implemented internally, but you should not add any artificial constraints.

And that's how duck typing should really be applied - by not making assumptions about the type of the object passed, only by testing whether or not you can do the required action (here: call find_closest_state without getting one of the above exceptions).


问:
Automatic code correction, Good or Bad?
We have a large team comprising of developers, interns who write rails and backbone js code with large codebase.

We already have tools like JSCS and code climate to analyze the code and report errors to the developers so that they fix it.

I tried to introduce fixmyjs, tool which corrects silly syntax errors automatically. One other senior developer suggested to hold on to this since we are still in transition of team of developers who write code, to team of developers who understands what writing good code means.

I understand the concern that, if this is introduced, developers might find it easy to get their code approved without understanding how to write good code, since the tool will be doing that for them.

My argument is that ultimate aim of any organization/team is to deliver products as soon as possible without compromising on quality. And this tool helps us to do that.

Educating someone is not the primary concern when you are doing business. There should be equal responsibility on the developer to educate himself to understand what needs to be done.

I feel not using a tool, because that will make developers not learn what needs to be done is not correct.

Your thoughts please.

答:
Code correction is like auto-complete or auto-format, a tool that helps devs not worry about the minutiae of the code and focus more on what it should be doing.

However giving code correction to a dev that doesn't understand the syntax is like giving autocorrect to beginning English speakers, the result will often be readable/understandable but rarely correct. (Resulting in the now popular substitution of "ratchet" for "wretched")

Title: Automatic code correction, Good or Bad?


答:
we are still in transition of team of developers who write code, to team of developers who understands what writing good code means.

Guess what - you will never leave that transition path (because even if you do programming for more than a decade, you can still learn something about better coding)! So do your team a favor, let them use your tool now, but make sure the people make a diff comparison of how the code looks before and afterwards to learn something from this. It might be also a good idea to introduce your team to the tool by explaining each type of code improvement it does, and the reasoning behind it.

When you wait introducing that tool until your devs come to the point where they write only "perfect" code, they will probably do not need your tool any more.

Title: Automatic code correction, Good or Bad?

Body:
We have a large team comprising of developers, interns who write rails and backbone js code with large codebase.

We already have tools like JSCS and code climate to analyze the code and report errors to the developers so that they fix it.

I tried to introduce fixmyjs, tool which corrects silly syntax errors automatically. One other senior developer suggested to hold on to this since we are still in transition of team of developers who write code, to team of developers who understands what writing good code means.

I understand the concern that, if this is introduced, developers might find it easy to get their code approved without understanding how to write good code, since the tool will be doing that for them.

My argument is that ultimate aim of any organization/team is to deliver products as soon as possible without compromising on quality. And this tool helps us to do that.

Educating someone is not the primary concern when you are doing business. There should be equal responsibility on the developer to educate himself to understand what needs to be done.

I feel not using a tool, because that will make developers not learn what needs to be done is not correct.

Your thoughts please.


问:
Should constructors for API classes ever be public, or can a factory always be used?
I'm surprised this doesn't seem to have been asked before, or at least I can't find it anywhere.  I know this is more of a philosophical question, but is there any particular reason not to use a factory (I'm assuming everyone knows the benefits of the factory pattern, so I won't go into that) for instantiating public API classes?  In other words, is there some reason to use a public constructor for such classes other than the fact that it's quicker to code which is maybe better for really simple, small APIs?

答:
Simplicity.

Factory (not abstract factory, just an ordinary one in its simplest form) pattern is useful when initializing a class requires complex business logic. Putting this logic in the constructor is often out of question, and having the logic in a static method within the class leads to class pollution (and sometimes poor discoverability).

In a case where the initialization logic is very straightforward, you don't need to create additional classes and replicate this logic. Doing that will lead to more LOC, less maintainable code and more work overall, with the only benefit of uniformization (that is every object of the code base is necessarily created through a corresponding factory).

Examples:

A Product class constructor accepts a ProductId id argument and loads the additional information from the database.

This is a perfect candidate for factory pattern. Database access shouldn't happen in a constructor, the constructor is expected to be very simple, fast and are often not expected to throw exceptions.

A Price class constructor takes int amount and Money unit arguments.

This is a perfect example where you won't have a factory. Why would you? The only thing it will do is to pass the arguments to the constructor. More complexity, no benefits.

A Rebate class constructor takes int amount and AmountUnit unit arguments. Depending on the amount and the unit, it can express a percentage of the total price, an absolute rebate or a “this product is free” (which, for the business, needs to be considered differently from 100% rebate).

Here, you may start writing code within the constructor, and if the code grows, migrate it to a factory. At the first sight, it is unclear whether the complexity of the business rules justifies a creation of a dedicated factory class. Over the lifespan of Rebate class source code, the team may switch several times between the initialization within the constructor and the initialization through a factory class.


答:
You cannot possibly avoid building an API. Even if you build "just a Website", it will still need to get its data from your backend somehow. However you decide to do this, that is your de facto API.

Knowing this, the real question isn't whether to build an API, but how to build it. You can do it on-the-fly as an ad hoc thing -and indeed, many Websites are built exactly this way- or you can design it carefully to be usable in other contexts. Put into this context, it becomes pretty clear that your colleague is right: you should do the API first, and then build your site on top of it.

Nevertheless, this brings with it some concerns, as you point out. To address them:

It's way too abstract to run your backend off an API. You're trying to make it too flexible which will make it an unmanageable mess.

That depends on how you do it. As George Pólya points out in his excellent text How to Solve It, oftentimes "the more general problem may be easier to solve". This is called the Inventor's Paradox. In the case of programming, it often works by means of separation of concerns: your backend no longer has to be concerned with the format of the data that it puts in and takes out, and so its code can be much simpler. Your data parsers and renderers no longer have to be concerned with what happens to the data they create, so they, too, can be simpler. It all works by breaking the code down into more manageable chunks.

All the stuff built into MVC seems useless, like roles and authentication. For example, [Authorize] attributes and security; you will have to roll your own.

I confess that I find it extremely difficult to sympathize with people who refuse to learn their tools. Just because you do not understand their use does not mean that they are useless, and it certainly doesn't mean you should roll your own. Quite the contrary; you shouldn't go rolling your own tools until you understand the alternatives, so that you can be sure to address the same problems that they do (even if only in your own ways).

Consider Linus Torvalds, who is most famous for writing Linux, but who also wrote git: now one of the most popular version-control systems in the world. One of the driving factors in his design was a deep opposition to Subversion (another extremely popular VCS, and arguably the most popular at the time git was written); he resolved to take everything that Subversion could, and to whatever extent it was possible, solve those problems differently. To do this, he had to become an expert on Subversion in his own right, precisely so that he could understand the same problem domains and take a different approach.

Or, in the process of learning your tools, you may find yourself finding that they're useful as-is, and don't need to be replaced.

All your API calls will require security information attached, and you will have to develop a token system and whatnot.

Yes. This is how it should be.

You will have to write complete API calls for every single function your program will ever do. Pretty much every method you want to implement will need to be ran off an API. A Get/Update/Delete for every user, plus a variant for each other operation eg update user name, add user to a group, etc. etc. and each one would be a distinct API call.

Not necessarily. This is where architectures like REST come into play. You identify the resources your application works with, and the operations that make sense to apply to those resources, and then you implement these without worrying so much about the others.

You lose all kinds of tools like interfaces and abstract classes when it comes to APIs. Stuff like WCF has very tenuous support for interfaces.

On the contrary, interfaces become much more important when you're using an API, not less. They come out in the representations you render them into. Most people nowadays specify a JSON-based format for this, but you can use any format you wish, as long as you specify it well. You render the output of your calls to this format on the backend, and parse it out into whatever you wish (likely the same kind of object) on the frontend. The overhead is small, and the gains in flexibility are huge.

You have a method that creates a user, or performs some task. If you want to create 50 users, you can just call it 50 times. When you decide to do this method as an API your local webserver can named-pipes connect to it and no problem - your desktop client can hit it too, but suddenly your bulk user creation will involve hammering the API over the Internet 50 times which isn't good. So you have to create a bulk method, but really you're just creating it for desktop clients. This way, you end up having to a) modify your API based on what's integrating with it, and you can't just directly integrate with it, b) do a lot more work to create an extra function.

Creating a bulk version of an existing method is hardly something I would call "a lot more work". If you're not worried about things like atomicity, the bulk method can wind up being not much more than a very thin frontend for the original.

YAGNI. Unless you're specifically planning to write two identically functioning applications, one web and one Windows application for example, it is a huge amount of extra development work.

No, YANI (You Already Need It). I outlined that as above. The only question is how much design work to put into it.

Debugging is much harder when you can't step through end-to-end.

Why wouldn't you be able to step through end-to-end?

But more to the point, being able to examine the data going back and forth in an easily-recognized format that cuts out all the display cruft actually tends to make debugging easier, not harder.

Lots of independent operations that will require lots of back and forth, for example some code might get the current user, check the user is in the administrator role, get the company the user belongs to, get a list of other members, send them all an email. That would require a lot of API calls, or writing a bespoke method the specific task you want, where that bespoke method's only benefit would be speed yet the downside would be it would be inflexible.

REST solves this by working on complete objects (resources, to use REST theory's terms), rather than the individual properties of objects. To update a user's name, you GET the user object, change its name, and PUT the user back. You might make other changes at the same time as you change the user name too. The more general problem becomes easier to solve, because you can eliminate all those individual calls for updating individual properties of an object: you just load it and save it.

In some ways, this is not unlike RISC architectures on the hardware side. One of the key difference between RISC and CISC (its predecessor) is that CISC architectures tend to include many instructions that operate directly on memory, while RISC architectures tend to operate mostly in registers: in a purely RISC architecture, the only operations on memory are LOAD (copy something from memory into a register) and STORE (take a value from a register and put it into memory).

You'd think that this would mean taking many more trips from registers out to memory, which would slow down the machine. But in practice, the opposite often happens: the processor (client) does more work between trips to memory (server), and this is where the speedup comes from.

Long story short: your colleague is right. This is the way to go. In exchange for a little up-front work, it will dramatically simplify the code for your Website and enable better integration with other Websites and apps. That is a price worth paying.

Further reading:

REST API Design - Resource Modeling


答:
One example worth looking at involves Java collections. The type hierarchy beneath Collection<T> has quite a few subinterfaces and concrete types. Each data structure has advantages and disadvantages. Sometimes they have additional properties above and beyond the basics of a particular data structure such as thread-safety or maintaining insertion order in an otherwise jumbled structure (e.g. some maps and sets).

To help with this, there are several factories built-in to the JFC. The Collections class can wrap an existing collection in one that is unmodifiable (the collection itself is immutable, the elements it contains may or may not be). It can wrap a collection in a synchronized wrapper, offering basic thread-safety (might not work as well as the specialized collections in the concurrency package). It can wrap a single element in a singleton collection (not the singleton pattern, just a collection with one element).

Those are all factory methods: one calls a method that returns an object rather than calling a constructor directly. They are useful because it allows one to adapt a collection that might be created out of one's control (e.g. in a framework or library) with additional constraints (e.g. mutability or concurrency) without explicitly creating a new object.

Guava takes this a step further with its Collection Utilities. It contains many more factory methods for creating new collections of various types with various properties. Construction can be more concise and expressive this way. At a conceptual level there is nothing more to explain beyond the JFC Collections class, but I will note that Google went through quite a bit of effort to build these factories because they add value.

This is just one example of where factories can be useful, but should they always be used?

There are two main reasons for using a factory:

Construction is complex. Constructors should be simple: do they need additional data or processing? For example, loading data from a file or database should not be done in a constructor, but may be needed to create an object. It makes more sense to put that extra processing in a factory method.

The implementation needs to vary independent of where objects are created. Might you want to use a different implementation at a future time? Might it be variable through a plugin architecture? Might you want to inject a mock for testing?

Many API classes fail these tests. For example, a string will always have the same implementation and does not require much extra processing. The core API of most languages/runtimes should be fairly simple for two reasons:

It is solving simple problems, e.g. "represent a sequence of characters in a string."

It needs to be applicable to a wide range of problems and highly reusable, which is at odds with a highly specialized class.

This simplicity is at odds with the requirements for using a factory. When a type is simple enough that a no-arg or one-arg constructor is all that is ever needed, and the implementation will always be the same, there is no point to using a factory.

Note that I am talking about the core API here (strings, collections, streams), not stuff like databases, GUI, or other more complex libraries.

Title: Should constructors for API classes ever be public, or can a factory always be used?

Body: I'm surprised this doesn't seem to have been asked before, or at least I can't find it anywhere.  I know this is more of a philosophical question, but is there any particular reason not to use a factory (I'm assuming everyone knows the benefits of the factory pattern, so I won't go into that) for instantiating public API classes?  In other words, is there some reason to use a public constructor for such classes other than the fact that it's quicker to code which is maybe better for really simple, small APIs?


问:
Design Pattern - Adding features to a class
I'm finding myself unable to solve a design problem.

For the sake of my simplicity, I'm going to use C# (Web API).

Let's say I have an abstract class RestController:

```<code>public abstract class RestController
{
    // ... Irrelevant code here

    protected virtual async Task<IHttpActionResult> UseAuthorization(HttpMethod method, Func<Task<IHttpActionResult>> operation)
    {
         return await operation();
    }

    protected virtual async Task<IHttpActionResult> UseHttpCache(Func<Task<IHttpActionResult>> operation)
    {
         return await operation();
    }

    // ... Irrelevant code here
}
</code>```

These two methods would be overriden and reimplemented by child classes. Any class that would just want to extend from RestController and don't want to use authorization or cache features, might just want to leave those methods untouched, as the default base implementation, does nothing.

Now, I was thinking of having something like this:

```<code>public abstract class CachedRestController : RestController
{
      protected override async Task<IHttpActionResult> UseHttpCache(Func<Task<IHttpActionResult>> operation)
      {
            IHttpActionResult result = await operation();
            return new HttpCachedResult(result);
      }
}

public abstract class AuthenticatedRestController : RestController
{
      protected override async Task<IHttpActionResult> UseAuthorization(HttpMethod method, Func<Task<IHttpActionResult>> operation)
      {
            return IsAuthenticated(method) ?
                   await operation() :
                   Unauthorized();
      }
}
</code>```

My goal is to achieve something similar to the following:

```<code>public class MyController : CachedRestController, AuthenticatedRestController
{

}
</code>```

Adding or removing features (caching, authentication, etc.), would be as easy as adding or removing parent classes.

Unfortunately, as we all know, multiple inheritance is not supported in C#, so I can not go with that solution.

I'm looking for a good design pattern (C# compliant) that would more or less achieve what I'm looking for.

I know of the Decorator Design Pattern, but having a controller as a field pretty much scares me as I am responsible for creating it (the Web Api framework should be responsible for that).

答:
This seems like one of those common "favor composition over inheritance" scenarios. A RestController serves as an endpoint for REST calls. Not something to govern Authorization. Not something to control the HttpCache. It's a violation of the Single Responsibility Principle.

Instead, you should have classes (strategies if you'd prefer) to govern these two responsibilities. Then you can compose them as needed into other controllers.


问:
How to avoid ...Helper or ...Manager classes
I have quite a few Helper classes in my project. I have read that this is a bad thing, but I suspect that "Helper" is the wrong suffix for them. I'll give an example.

First, I have a User class. I need a method GetSuggestedFriends() for a user. I want to keep the logic for determining the list of suggested friends out of the User class, so it doesn't get bloated. Right now, I have a FriendshipHelper which receives a User in its constructor. It contains the logic for getting suggested friends, and I can now call myUser.FriendshipHelper.GetSuggestedFriends().

Originally FriendshipHelper had static methods only, and a User object was passed into each one. If I was writing the class from scratch now, maybe I'd call it FriendshipManager - it also does things like adding and removing friends.

I've also read that ...Manager classes are bad, though. What should I call this class? Or, is this "bad code"? Where should the logic for getting suggested friends, current friends, and adding and removing friends live? Surely not all in a giant User class?

答:
I would suggest that you have a FriendshipService class that has a (non-static) GetSuggestedFriends(User) method. Avoid static methods since you cannot implement an interface which makes it more difficult to test. Avoid adding the user object to the constructor since you might want to extend your FriendshipService with methods not specifically related to a single user. (For example, you might want to suggest friends to a set of users, or suggest friends based on something else)

A user should most likely not be aware of the FriendshipService (due to the Single Responsibility Pattern)


问:
Can you implement "object-oriented" programming without the class keyword?
Say we want to provide an abstraction of an "account" in a bank. Here's one approach, using a function object in Python:

def account():
    """Return a dispatch dictionary representing a bank account.

    >>> a = account()
    >>> a['deposit'](100)
    100
    >>> a['withdraw'](90)
    10
    >>> a['withdraw'](90)
    'Insufficient funds'
    >>> a['balance']
    10
    """
    def withdraw(amount):
        if amount > dispatch['balance']:
            return 'Insufficient funds'
        dispatch['balance'] -= amount
        return dispatch['balance']
    def deposit(amount):
        dispatch['balance'] += amount
        return dispatch['balance']
    dispatch = {'balance': 0,
                'withdraw': withdraw,
                'deposit': deposit}
    return dispatch
```

<p>Here's another approach using type abstraction (i.e., <code>class</code> keyword in Python):</p>

<pre class="lang-py prettyprint-override"><code>class Account(object):
    """A bank account has a balance and an account holder.

    >>> a = Account('John')
    >>> a.deposit(100)
    100
    >>> a.withdraw(90)
    10
    >>> a.withdraw(90)
    'Insufficient funds'
    >>> a.balance
    10
    """

    def __init__(self, account_holder):
        self.balance = 0
        self.holder = account_holder

    def deposit(self, amount):
        """Add amount to balance."""
        self.balance = self.balance + amount
        return self.balance

    def withdraw(self, amount):
        """Subtract amount from balance if funds are available."""
        if amount > self.balance:
            return 'Insufficient funds'
        self.balance = self.balance - amount
        return self.balance
</code>```

My teacher started the topic "Object oriented programming" by introducing the class keyword, and showing us these bullet points:

Object-oriented programming

A method for organizing modular programs:

Abstraction barriers

Message passing

Bundling together information and related behavior

Do you think the first approach would suffice to satisfy the above definition? If yes, why do we need the class keyword to do object-oriented programming?

答:
Your teacher's definition completely misses the most important point of object-oriented programming, the one thing that makes it useful and unique.  "Message passing" is a bunch of nonsense dreamed up by the Smalltalk folks, and it's been a failure everywhere it's been tried.  The true power of OOP is something known as Liskov substitution, and while the concept is fairly simple to describe and understand, the underlying implementation is complex enough that it's essentially impossible to do right without language-level support.

The idea of Liskov substitution is that anywhere where your code is expecting a variable of a certain type, it should be able to accept any type derived from that type and still work correctly without having to have knowledge of the details of the derived type.

For example, GUI frameworks use Liskov substitution all over the place.  They tend to have a base Control class that can represent "any control", which defines an interface that knows about basic actions like drawing, resizing, and responding to user input.  If you click on a control, the UI framework will call a Click method on the control without having to care about what kind of control it is, and then let the control handle the click in the appropriate way for its own class.  A Button control should do something completely different when clicked on than a TextBox control, to give just one example.

So yes, you can create something kind of similar to objects using the nested functions trick described above, but because you can't get inheritance and Liskov substitution that way, it's an extremely limited substitute for true OOP.


问:
Saving Multiple Sizes of Images
We have lots of user-generated images on our site.  When users upload their images, we only store the original.  However, depending on the page, we show different sizes of those images (small, medium, large, original).  Is it necessary to store all sizes of these images or is there a better way?  Currently, we are resizing them with CSS but this is really slow.  </p>

答:
I disagree on the file storage, if possible, those interim images should never be stored as they always create clutter.

Disk space is dirt cheap, but serving files from disk is slow, and SSDs - that are fast - are not that dirt cheap yet.
This "generate all image size we can think of" model is not future proof and it works until you can predefine all the image resolutions that you need to display. There is always the problem of leftover content that is a pain to maintain, but at least it is the same problem always.
Business specification can ruin this model quite easily. If it requires that you need a new resolution of the images, you have to write resizing scripts that walks through your entire existing image library and creates the new resolution so your old images can work in a new design.
It is doable, but it needs system admins. However if business specification requires you to be very responsive and always changing image size, which cannot be predefined, this model is screwed.

We have been there and done that, now instead we use varnish cache and a resizing application combination to serve arbitrarily resized images without explicitly storing them on disk. As the images are served from cache, their delivery is lightning fast.
With this solution there is no need to:

create every image version, especially when you don't know what to create

delete leftover images

running async processes to resize the image

re-resize old images to new resolutions

create differently named files because of file system restrictions.

In our model resize happens in the request-response process when the visitor requests the resized image. In other words, the visitor who loads a resized image into the browser - an image that has never been displayed - will have to wait a little extra time, while the system creates the new, resized image.

Bonus feature: everything is testable by calling a simple URL, no need to run the image resizer app to create the different versions of the image. The image will be created on-the-fly.

Original image: http://myserver.com/imagename.jpg

Resized image: http://myserver.com/imagename.jpg?w=317 (creating a 317 pixels wide image)

Every request to http://myserver.com will arrive to a Varnish that handles those incoming requests. Varnish is configured so that when it gets a request that has no query parameters, serves the request from static filesystem without caching the content. Turning off cache in this case is a good idea only if the original image will never be shown to visitors, only the resized ones (maybe because the original is a fairly large one).

If the incoming request has query parameters, Varnish dispatches the request to the resizing application. The application gets the base image by re-running the original request without the query string, which means Varnish will serve the original image to the application. As Varnish can act as a load-balancer, it can even mitigate problems, like application timeout.

The application then does the appropriate resizing (checking parameter validity, rules, etc.), and makes a response with the resized image. The response goes back in the response chain, which is Varnish, and that caches the resized image, and serves it back to the client.

Any subsequent request to the same size image (aka: the same URL with the same query parameters) will be served from cache until the cache expires.

This way Varnish is used as the storage device, with the added bonus of being a cache.

Title: Saving Multiple Sizes of Images


答:
What your colleague is describing is a service oriented architecture. This can be a tremendously scalable, testable and sane way to code, but it really depends on what you are making.

There are some significant benefits to SOA, which I will attempt to ennumerate:

Scalability

Since your back end is decoupled, your front end becomes just a series of templates, even flatfiles. Flatfiles are tremendously quick and cheap to serve from any CDN. They can be minified and precompiled into static HTML, then populated with data clientside.

Your API has to remain consistent, but can be swapped for a faster technology without breaking your stack if you outgrow your existing technology. You could remake it in Go for example. You could rebuild it piecemeal and spread the load across servers. As long as the interface remains the same the technology is abstracted.

Testability

MVC usually starts out clean, but in practice controllers rarely stay focussed on a single resource. The more things your controller methods do the less testable they become.

An API sidesteps this issue. Each API call pulls a resource and serves it. Clean and testable.

Guaranteed separation of concerns

Your front end and back end are fully divorced. You can give the front end to another developer or a designer. This is MVC taken to another level. I'm sure you wouldn't want to give up on MVC. SOA is MVC but more-so.

Downsides

There are of course some downsides. A monolith is often faster to get going with. It may be what you are used to. It may fit more nicely into your stack. Your tools may be optimised for monolith creation.

None of these are particularly good reasons in my opinion, and you may wish to consider retooling if they apply to you.


答:
How to avoid …Helper or …Manager classes«

In general: by good Design

First, I have a User class. I need a method GetSuggestedFriends() for a user.

Yes. A user has a relationship to other users. And the relationship could be expressed as a method on user, e.g. user.isFriend(user2).
This is the responsibility of the user-object.
Besides that, you ask another object for help finding other friends.
You delegate the responsibility for finding friends to another object and that's quite fine.

Right now, I have a FriendshipHelper which receives a User in its constructor. It contains the logic for getting suggested friends, and I can now call myUser.FriendshipHelper.GetSuggestedFriends()

That is not per se bad, but has one downside: initializing the "Helper" with one user limits the possibilities to that one user.

What you need is an object, which helps finding friends to any user. So a generic method would make sense: userMatcher.findFriendsFor(user) which in return delivers a collection of possible friends (user).

If I was writing the class from scratch now, maybe I'd call it FriendshipManager

Your problem is not writing "helper classes", it is finding the right names. ;)

it also does things like adding and removing friends.

That is a wrong design. Take yourself for example: Does your mommy add friends to your life or do you add them by yourself?

Of course the collection of friends is a property of user itself and so is the method user.addFriend(user) or user.removeFriend(user)

What should I call this class?

As said before: you only have a naming issue and your "helpers" are okay. But you have to think more carefully about the responsibilities of each object.

Where should the logic for getting suggested friends, current friends, and adding and removing friends live? Surely not all in a giant User class

No. These are two jobs for which you need one separate object, like in real life where you have people and a dating agency.

Title: How to avoid ...Helper or ...Manager classes

Body:
I have quite a few Helper classes in my project. I have read that this is a bad thing, but I suspect that "Helper" is the wrong suffix for them. I'll give an example.

First, I have a User class. I need a method GetSuggestedFriends() for a user. I want to keep the logic for determining the list of suggested friends out of the User class, so it doesn't get bloated. Right now, I have a FriendshipHelper which receives a User in its constructor. It contains the logic for getting suggested friends, and I can now call myUser.FriendshipHelper.GetSuggestedFriends().

Originally FriendshipHelper had static methods only, and a User object was passed into each one. If I was writing the class from scratch now, maybe I'd call it FriendshipManager - it also does things like adding and removing friends.

I've also read that ...Manager classes are bad, though. What should I call this class? Or, is this "bad code"? Where should the logic for getting suggested friends, current friends, and adding and removing friends live? Surely not all in a giant User class?


问:
Is there a difference between SQL INSERT patterns
SQL inserts are usually documented like so:

```<code>INSERT TableName (Column1, Column2) VALUES ('Value1', 'Value2')
</code>```

However, in TSQL it's also possible to write the (seemingly) same statement like so:

```<code>INSERT TableName (Column1, Column2) SELECT 'Value1', 'Value2'
</code>```

Explain Plan seems to think they're identical.

Are they? Is there any hidden difference or any argument for doing it the INSERT () Values () way?

答:
In SQL there are many times where different syntax do the same thing

At just one static insert then no difference

Clearly the limit of values is static (hard coded) values

You cannot reference a table

A select statement can be used to present static (hard coded) value as you have shown.  And you can even combine hard coded with columns in a select from.

What you are missing is the s in values

```<code>INSERT TableName (Column1, Column2)
VALUES ('Value1a', 'Value2a')
     , ('Value1b', 'Value2b')
</code>```

The above is more efficient than multiple insert statements

With select the syntax is

```<code>INSERT TableName (Column1, Column2)
select 'Value1a', 'Value2a'
union
select 'Value1b', 'Value2b'
</code>```

In this case values is more convenient (in my opinion)

Body:
In SQL there are many times where different syntax do the same thing

At just one static insert then no difference

Clearly the limit of values is static (hard coded) values

You cannot reference a table

A select statement can be used to present static (hard coded) value as you have shown.  And you can even combine hard coded with columns in a select from.

What you are missing is the s in values

INSERT TableName (Column1, Column2)
VALUES ('Value1a', 'Value2a')
     , ('Value1b', 'Value2b')

The above is more efficient than multiple insert statements

With select the syntax is

INSERT TableName (Column1, Column2)
select 'Value1a', 'Value2a'
union
select 'Value1b', 'Value2b'

In this case values is more convenient (in my opinion)