答:
Telastyn's answer is pretty good. I'd add that comments are very useful when you need to explain something that literally cannot be expressed in valid, legible syntax. In other words, sometimes you just need a diagram or image.

ASCII art may not be the best, but it can be better than nothing, and pretty much guaranteed to be viewable if the source if viewable (accounting for both availability and rendering). Note that including a link to more in depth (and better diagrams/images) can be a good idea, but keep in mind the possibility that external resources may be unavailable, or not easily viewed.

Shamus Young has an article about comments, which starts off with an actual comment nearly fifty lines long from one of his projects. Part of that comment has a diagram used to demonstrate a hexagonal grid built from a square grid:

```<code>[...snip...]

+--|--+--|--+--|--+--|--+
   |     |     |     |
   |  .  |  .  |  .  |
  / \   / \   / \   / \
 /   \ /   \ /   \ /   \
|  .  |  .  |  .  |  .  |
|     |     |     |     |
+--+--+--+--+--+--+--+--+
   |     |     |     |
   |  .  |  .  |  .  |
  / \   / \   / \   / \
 /   \ /   \ /   \ /   \
|  .  |  .  |  .  |  .  |
|     |     |     |     |
+--+--+--+--+--+--+--+--+
   ^
   |
   +---This column gets shifted down.

[...snip...]
</code>```

Try expressing that clearly in variable and function names.

Title: Best possible way to comment?

Body:
My question is simple, how should I comment during development so that it can be beneficial in the following cases:

Understandable for my seniors while code reviewing.

Should be able to search my work after sometime.

Can be made in pseudo code form.

Should be able to help juniors or other developers when they work on it.

Any real world examples will highly be appreciated.

PS: I am not debating whether we should write comments or not.

Body:
Telastyn's answer is pretty good. I'd add that comments are very useful when you need to explain something that literally cannot be expressed in valid, legible syntax. In other words, sometimes you just need a diagram or image.

ASCII art may not be the best, but it can be better than nothing, and pretty much guaranteed to be viewable if the source if viewable (accounting for both availability and rendering). Note that including a link to more in depth (and better diagrams/images) can be a good idea, but keep in mind the possibility that external resources may be unavailable, or not easily viewed.

Shamus Young has an article about comments, which starts off with an actual comment nearly fifty lines long from one of his projects. Part of that comment has a diagram used to demonstrate a hexagonal grid built from a square grid:

[...snip...]

+--|--+--|--+--|--+--|--+
   |     |     |     |
   |  .  |  .  |  .  |
  / \   / \   / \   / \
 /   \ /   \ /   \ /   \
|  .  |  .  |  .  |  .  |
|     |     |     |     |
+--+--+--+--+--+--+--+--+
   |     |     |     |
   |  .  |  .  |  .  |
  / \   / \   / \   / \
 /   \ /   \ /   \ /   \
|  .  |  .  |  .  |  .  |
|     |     |     |     |
+--+--+--+--+--+--+--+--+
   ^
   |
   +---This column gets shifted down.

[...snip...]

Try expressing that clearly in variable and function names.


问:
Best possible way to comment?
My question is simple, how should I comment during development so that it can be beneficial in the following cases:

Understandable for my seniors while code reviewing.

Should be able to search my work after sometime.

Can be made in pseudo code form.

Should be able to help juniors or other developers when they work on it.

Any real world examples will highly be appreciated.

PS: I am not debating whether we should write comments or not.

答:
I often maintain up-to-date documentation written with Doxygen ( or Doxygen-like ) comments. So, every method/function has one/two sentences describing what it does.

And when one/two sentences are not enough, then IMHO you should refactor it and break into smaller pieces ( see Unix philosophy ).

Also, all "complex" algorithms should be depicted with graphs, images and easly-readable pseudo-code in additional documentation.

ContentLicense: CC BY-SA 3.0

Title: Best possible way to comment?


问:
What's the name for the 'spec' of a function/method?
I'm pretty sure there is a special name for the 'spec' of a function/method.  It's a word that refers to

how many arguments it takes

the order of arguments

which arguments are optional

Is there a name for that?

答: I believe the term is "contract". It defines the interface and what's expected of caller and callee; however it also covers things like allowed values of parameters which is not something many languages allow to be defined by the function or class definition, so the term "contract" might be broader in meaning than what you meant. I have seen it in several object oriented and Java specific programming books. I'm not sure if it's Java specific but I don't see why would it need to be. Signature is the other commonly used term but I grew to like "contract".</p>


问:
The present and future of programming in local languages
Can programming become language-independent? Will we always program in English? Will we ever be able to program in our local languages? Is there any research that addresses the matter? Are there any such developments?</p>

答:
English is the lingua franca of programming, like Latin for doctors.

Consider why you want alternative keywords and then consider what you Will have to give up.

ContentLicense: CC BY-SA 2.5


问:
Scripting custom drawing in Delphi application with IF/THEN/ELSE statements?
I'm building a Delphi application which displays a blueprint of a building, including doors, windows, wiring, lighting, outlets, switches, etc. I have implemented a very lightweight script of my own to call drawing commands to the canvas, which is loaded from a database. For example, one command is ELP 1110,1110,1290,1290,3,8388608 which draws an ellipse, parameters are 1110x1110 to 1290x1290 with pen width of 3 and the color 8388608 converted from an integer to a TColor.

What I'm now doing is implementing objects with common drawing routines, and I'd like to use my scripting engine, but this calls for IF/THEN/ELSE statements and such. For example, when I'm drawing a light, if the light is turned on, I'd like to draw it yellow, but if it's off, I'd like to draw it gray. My current scripting engine has no recognition of such statements. It just accepts simple drawing commands which correspond with TCanvas methods.

Here's the procedure I've developed (incomplete) for executing a drawing command on a canvas:

```<code>function DrawCommand(const Cmd: String; var Canvas: TCanvas): Boolean;
type
  TSingleArray = array of Single;
var
  Br: TBrush;
  Pn: TPen;
  X: Integer;
  P: Integer;
  L: String;
  Inst: String;
  T: String;
  Nums: TSingleArray;
begin
  Result:= False;
  Br:= Canvas.Brush;
  Pn:= Canvas.Pen;
  if Assigned(Canvas) then begin
    if Length(Cmd) > 5 then begin
      L:= UpperCase(Cmd);
      if Pos(' ', L)> 0 then begin
        Inst:= Copy(L, 1, Pos(' ', L) - 1);
        Delete(L, 1, Pos(' ', L));
        L:= L + ',';
        SetLength(Nums, 0);
        X:= 0;
        while Pos(',', L) > 0 do begin
          P:= Pos(',', L);
          T:= Copy(L, 1, P - 1);
          Delete(L, 1, P);
          SetLength(Nums, X + 1);
          Nums[X]:= StrToFloatDef(T, 0);
          Inc(X);
        end;
        Br.Style:= bsClear;
        Pn.Style:= psSolid;
        Pn.Color:= clBlack;
        if Inst = 'LIN' then begin
          Pn.Width:= Trunc(Nums[4]);
          if Length(Nums) > 5 then begin
            Br.Style:= bsSolid;
            Br.Color:= Trunc(Nums[5]);
          end;
          Canvas.MoveTo(Trunc(Nums[0]), Trunc(Nums[1]));
          Canvas.LineTo(Trunc(Nums[2]), Trunc(Nums[3]));
          Result:= True;
        end else
        if Inst = 'ELP' then begin
          Pn.Width:= Trunc(Nums[4]);
          if Length(Nums) > 5 then begin
            Br.Style:= bsSolid;
            Br.Color:= Trunc(Nums[5]);
          end;
          Canvas.Ellipse(Trunc(Nums[0]),Trunc(Nums[1]),Trunc(Nums[2]),Trunc(Nums[3]));
          Result:= True;
        end else
        if Inst = 'ARC' then begin
          Pn.Width:= Trunc(Nums[8]);
          Canvas.Arc(Trunc(Nums[0]),Trunc(Nums[1]),Trunc(Nums[2]),Trunc(Nums[3]),
            Trunc(Nums[4]),Trunc(Nums[5]),Trunc(Nums[6]),Trunc(Nums[7]));
          Result:= True;
        end else
        if Inst = 'TXT' then begin
          Canvas.Font.Size:= Trunc(Nums[2]);
          Br.Style:= bsClear;
          Pn.Style:= psSolid;
          T:= Cmd;
          Delete(T, 1, Pos(' ', T));
          Delete(T, 1, Pos(',', T));
          Delete(T, 1, Pos(',', T));
          Delete(T, 1, Pos(',', T));
          Canvas.TextOut(Trunc(Nums[0]), Trunc(Nums[1]), T);
          Result:= True;
        end;
      end else begin
        //No space found, not a valid command
      end;
    end;
  end;
end;
</code>```

What I'd like to know is what's a good lightweight third-party scripting engine I could use to accomplish this? I would hate to implement parsing of IF, THEN, ELSE, END, IFELSE, IFEND, and all those necessary commands. I need simply the ability to tell the scripting engine if certain properties meet certain conditions, it needs to draw the object a certain way.

The light example above is only one scenario, but the same solution needs to also be applicable to other scenarios, such as a door being open or closed, locked or unlocked, and draw it a different way accordingly. This needs to be implemented in the object script drawing level. I can't hard-code any of these scripting/drawing rules, the drawing needs to be controlled based on the current state of the object, and I may also wish to draw a light a certain shade or darkness depending on how dimmed the light is.

答:
Lua integration?

http://www.lua.org/docs.html

Lua is language designed for embedding (can be run standalone too)

High speed like in interpreter class, good controlled RAM use. Very good integration with C/C++ Borland too (i haven't legal Delphi to check), few Delphi integrations exist.


问:
Non-synchronized method that calls synchronized methods only
Is it safe to make a non-synchronized method if it only calls synchronized methods?

Say we have:

```<code>public class SomeClass{
    public synchronized void A(){
        //Some code
    }
    public synchronized void B(){
        //Some code
    }
    public synchronized void C(){
        A();
        B();
    }
}
</code>```

Should C() be synchronized or not?

答:
That depends. Could there be problems if something happens between the calls to A and B? If so, then C should be synchronized.

```<code>public class SomeClass{
    private int i;
    public synchronized void A(){
        i += 1;
    }
    public synchronized void B(){
        print i; // uses something modified by A
    }
    public void C(){ // unsynchronized so...
        A();
        // ...i could be changed here by another thread, affecting what B prints
        B();
    }
}
</code>```

If there is no critical section between A and B, then C doesn't need to be synchronized.

```<code>public class SomeClass{
    private int i;
    public synchronized void A(){
        i += 1;
    }
    public synchronized void B(){
        print "B"; // unrelated to what A does
    }
    public void C(){
        A();
        // i could be changed here, but won't affect B
        B();
    }
}
</code>```

Body:
That depends. Could there be problems if something happens between the calls to A and B? If so, then C should be synchronized.

public class SomeClass{
    private int i;
    public synchronized void A(){
        i += 1;
    }
    public synchronized void B(){
        print i; // uses something modified by A
    }
    public void C(){ // unsynchronized so...
        A();
        // ...i could be changed here by another thread, affecting what B prints
        B();
    }
}

If there is no critical section between A and B, then C doesn't need to be synchronized.

public class SomeClass{
    private int i;
    public synchronized void A(){
        i += 1;
    }
    public synchronized void B(){
        print "B"; // unrelated to what A does
    }
    public void C(){
        A();
        // i could be changed here, but won't affect B
        B();
    }
}


问:
How is fundamental mathematics efficiently evaluated by programming languages?
As I get more and more involved with the theory behind programming, I find myself fascinated and dumbfounded by seemingly simple things..
I realize that my understanding of the majority of fundamental processes is justified through circular logic

Q: How does this work?

A: Because it does!

I hate this realization! I love knowledge, and on top of that I love learning, which leads me to my question (albeit it's a broad one).

Question:

How are fundamental mathematical operators assessed with programming languages?

How have current methods been improved?

Example

```<code>var = 5 * 5;
</code>```

My interpretation:

```<code>$num1 = 5; $num2 = 5; $num3 = 0;
while ($num2 > 0) {
    $num3 = $num3 + $num1;
    $num2 = $num2 - 1;
}
echo $num3;
</code>```

This seems to be highly inefficient. With Higher factors, this method is very slow while the standard built in method is instantanious. How would you simulate multiplication without iterating addition?

```<code>var = 5 / 5;
</code>```

How is this even done? I can't think of a way to literally split it 5 into 5 equal parts.

```<code>var = 5 ^ 5;
</code>```

Iterations of iterations of addition?
My interpretation:

```<code>$base = 5;
$mod = 5;
$num1 = $base;
while ($mod > 1) {

    $num2 = 5; $num3 = 0;
    while ($num2 > 0) {
        $num3 = $num3 + $num1;
        $num2 = $num2 - 1;
    }
    $num1 = $num3;
    $mod -=1;
}
echo $num3;
</code>```

Again, this is EXTREMELY inefficient, yet I can't think of another way to do this.
This same question extends to all mathematical related functions that are handled automagically.

答:
Here's how a modern processor might implement multiplication of two 64 bit integers:

You know how to do a long hand multiplication. To multiply two 10 digit numbers, you would multiply one 10 digit number by each of the 10 digits of the other number, write the 11 digits result one below the other and shifted, then add all the number.

A modern processor does this with all the 64 by 64 bits. However, a multiplication of two single bit numbers is very simple: 1 x 1 = 1, all other products are zero. This is implemented with a logical and. And unlike the decimal product, where the result can be two digits, a binary product of single bit numbers is always one bit.

So now you have 64 rows of 64 bits that need to be added. But 64 additions of 64 bit numbers are slooooooow. So the processor uses either a 3/2 adder or a 7/3 adder: If you add 3 single bit numbers, the result can be 0, 1, 2 or 3, which fits into two bits. If you add 7 single bit numbers, the result is a number from 0 to 7, which can be represented by 3 bits. IBM claims they can make a 7/3 adder with just 18 primitive circuits (PowerPC documentation), I bet Intel and ARM can do this as well.

You have 4096 bits, group them into about 600 groups of 7 bits in the same bit positions, and use about 600 7/3 adders to reduce the result from 4096 bits to less than 2,000. Then you do the same again, and again, until you end up with pairs of bits that can be fed into an ordinary full adder.


问:
Should every member of a team use the same IDE?
Do you think it makes sense to enforce that every member of a team must use the same IDE?

For instance all engineers that are already on the team use IDE X. Two new engineers come and want to use IDE Y instead because that's what they have been using for several years now.

Do you have any experience with "mixed IDE" teams? If so what is it?

答:
One downside is that when pairing you can't swap the keyboard between you as fluently. Between mainstream IDEs this is probably not a huge problem, but if one person is used to Eclipse while the other is used to vim, there is going to be a mismatch. The Eclipse user may well be entirely unable to use vim, while the vim user (that's me ;) spends a lot of time cursing under their breath at the horrible slowness of using vanilla Eclipse.

That said, I'd still much rather use vim myself. Provided your pair are happy with just one of you "driving" for extended periods it works OK.

And I know there are plugins to make Eclipse work like vi, but I'm talking about pairing where I go and sit with someone who has Eclipse working as they like it, so they won't be installing that plugin.


问:
Is there such thing as an example driven parser generator or ad-hoc DSL development?
I'm intrested to know if there exists a tool that lets you input examples of valid documents and lets you then generalize from that to a reusable parser.

I can imagine this, but everytime i start learning about parsers it gets to the granularity of something like lex and yacc and it seems more complicated than my instincts say it should be.

So I'm left wondering if

a) it's just fundamentally that complicated and I need to see it or

b) there's a way to build ad-hoc DSLs for relatively simple tasks that I could learn about

Update: a simple example of an "ad hoc" dsl i might like to make quickly.

Instead of the XML

```<code><foo>
  <item>bar</item>
  <item>bat</item>
</foo>
</code>```

I might want something like:

```<code>foo
  bar
  bat
</code>```

lines contain data items

indentation produces parent-child relations

My imaginary tool lets me convey the above information.

Then, in my imaginary tool, I might highlight "foo" above and right click, at which point it would prompt me to restrict the values to a choice list....

Then I might extend the first one to:

```<code>foo
  bar(5)
  bat
</code>```

in a line, '(' and ')' surround a sub item

The above might be qualified with a boolean value that specifies recursion or not, if set to true then bar(lala(4)) might work...

This is the kind of train of thought I generally have that led me to ask the question. It's possible that now I've qualified it, the answer changes - if so I apologize in advance.

答:
DSL can be divided to 2 groups:

a) external like (mostly) write Ira Baxter: build NEW parser etc ... implement semantic

b) internal: use subset / over-set (library extensions) of real language. Then use have no-choice about syntax, must accept general syntax rule of hosting language.

Example of internal DSL in java. Copied from bigger project:

```<code>BackupService.open().setAdminEmail("aaa@yyy.ccc")
.setDatabase("xddasdas;user;pass").pefrorm().zip().transfer("sftp...).finish();
</code>```

Read "evangelism" in Groovy Language community.

http://www.groovy-lang.org/dsls.html

and sample a. Xml Builder, is very near to Your idea

http://www.groovy-lang.org/processing-xml.html#_creating_xml

Body:
DSL can be divided to 2 groups:

a) external like (mostly) write Ira Baxter: build NEW parser etc ... implement semantic

b) internal: use subset / over-set (library extensions) of real language. Then use have no-choice about syntax, must accept general syntax rule of hosting language.

Example of internal DSL in java. Copied from bigger project:

BackupService.open().setAdminEmail("aaa@yyy.ccc")
.setDatabase("xddasdas;user;pass").pefrorm().zip().transfer("sftp...).finish();

Read "evangelism" in Groovy Language community.

http://www.groovy-lang.org/dsls.html

and sample a. Xml Builder, is very near to Your idea

http://www.groovy-lang.org/processing-xml.html#_creating_xml


答: Not in the general case, for the reasons given by Ira Baxter.  However, this is a pretty good description of how docopt works: you give it examples of what valid command-line arguments to your program should look like, and it generates a command-line argument parser from those examples.</p>

Title: Is there such thing as an example driven parser generator or ad-hoc DSL development?

Body:
I'm intrested to know if there exists a tool that lets you input examples of valid documents and lets you then generalize from that to a reusable parser.

I can imagine this, but everytime i start learning about parsers it gets to the granularity of something like lex and yacc and it seems more complicated than my instincts say it should be.

So I'm left wondering if

a) it's just fundamentally that complicated and I need to see it or

b) there's a way to build ad-hoc DSLs for relatively simple tasks that I could learn about

Update: a simple example of an "ad hoc" dsl i might like to make quickly.

Instead of the XML

```<code><foo>
  <item>bar</item>
  <item>bat</item>
</foo>
</code>```

I might want something like:

```<code>foo
  bar
  bat
</code>```

lines contain data items

indentation produces parent-child relations

My imaginary tool lets me convey the above information.

Then, in my imaginary tool, I might highlight "foo" above and right click, at which point it would prompt me to restrict the values to a choice list....

Then I might extend the first one to:

```<code>foo
  bar(5)
  bat
</code>```

in a line, '(' and ')' surround a sub item

The above might be qualified with a boolean value that specifies recursion or not, if set to true then bar(lala(4)) might work...

This is the kind of train of thought I generally have that led me to ask the question. It's possible that now I've qualified it, the answer changes - if so I apologize in advance.


问:
Better to have two variables to designate whether a variable exists, or one
Lets say I have a string variable FirstName. FirstName can be null. I need to know if FirstName exists or not.

Is it better to just use one variable: FirstName and if FirstName is empty assume that it doesn't exists

OR

Create two variables:

Boolean HasFirstName and String FirstName

The benefits of this is I know positively that FirstName doesn't exist but on the down side it creates two variables.

答:
I would argue against both choices and would use an option type instead. An option type either contains no value or, or in this case, a string.

Many languages, especially functional ones, have such types built-in. Even if your chosen language doesn't support it directly, an Option<T> is a simple type to create.


问:
Access container object from within an item
Generally I have 3 classes, a container that holds an array of items and a special object that is another property of the container class. What I need to do is access the special object from an item object within the container. I see 2 ways of achieving this.

```<code>class Container {

    protected $object;
    protected $items = [];

    public function __construct() {
        $this->object = new SpecialObject;
    }

    public function setItem($index, Item $item) {
        $this->items[$index] = $item;
    }

    public function getItem($index) {
        return $this->items[$index];
    }

}

class Item {

    protected $container;

    public function __construct(Container $container) {
        $this->container = $container;
    }

    public function action() {
        $this->container->object;
    }
}
</code>```

Or

```<code>class Container {

    protected $object;
    protected $items = [];

    public function __construct() {
        $this->object = new SpecialObject;

        Registry::set('SpecialObject', $this->object);
    }

    public function setItem($index, Item $item) {
        $this->items[$index] = $item;
    }

    public function getItem($index) {
        return $this->items[$index];
    }

}

class Item {

    public function action() {
        Registry::get('SpecialObject');
    }
}
</code>```

With the first example the problem I'm concerned about is that there will be a reference within each Item object pointing to the container, which is not only redundant but if an item switches containers (for some reason, not intended) it will have a wrong container reference and could lead to trouble. The second one however implies that there will only be one instance of Container, which may not and probably will not be the case. I think there is no fool-proof way to grab the container of an item but what would you suggest is the "best" way to achieve this in terms of performance and avoiding bugs?

答:
A few solutions come to mind:

In stead of calling that action on the Item, call it on the Container. Something like this:

```<code>class Container {
    ...

    public function actionOnItem($index) {
        // do stuff with the item and the special object
        $this->object;
        $this->items[$index];
    }
}
</code>```

In stead of hard coding that dependency into the Item, you could inject it when you Item needs it. Something Along these lines:

```<code>class Item {
    ...
    public function action(SpecialObject $object) {
        // do stuff with the item and the special object
        $object;
        $this;
    }
}
</code>```

And you could use it like this:

```<code>$item->action($container->object);
</code>```

Another option would be to make a dedicated object for that Action, and inject both the Item and SpecialObject when you want it to do it's thing. Something in this order.

```<code>class ItemAction {

    private $object;

    public function __construct(SpecialObject $object) {
        $this->object = $object;
    }

    public function action(Item $item) {
        // do stuff with the item and the special object
        $this->object;
        $item;
    }
}
</code>```

Or perhaps something like this

```<code>class ItemAction {

    public static function action(Item $item, SpecialObject $object) {
        // do stuff with the item and the special object
        $object;
        $item;
    }
}
</code>```

What would be the best option in your case is hard to tell and depends largely on the scope and size of your application, and even the framework you are (not) using. Perhaps you could try to  give a real world example of what you are trying to achieve?...

Anyway, if it where up to me, Dependency Injection would be the way to go! And it has the added benefit of making your code easier to test. Even that SpecialObject would be injected into the Container if it where up to me, in stead of newing it up hardcoded inside your Container constructor.

Body:
A few solutions come to mind:

In stead of calling that action on the Item, call it on the Container. Something like this:

class Container {
    ...

    public function actionOnItem($index) {
        // do stuff with the item and the special object
        $this->object;
        $this->items[$index];
    }
}

In stead of hard coding that dependency into the Item, you could inject it when you Item needs it. Something Along these lines:

class Item {
    ...
    public function action(SpecialObject $object) {
        // do stuff with the item and the special object
        $object;
        $this;
    }
}

And you could use it like this:

$item->action($container->object);

Another option would be to make a dedicated object for that Action, and inject both the Item and SpecialObject when you want it to do it's thing. Something in this order.

class ItemAction {

    private $object;

    public function __construct(SpecialObject $object) {
        $this->object = $object;
    }

    public function action(Item $item) {
        // do stuff with the item and the special object
        $this->object;
        $item;
    }
}

Or perhaps something like this

class ItemAction {

    public static function action(Item $item, SpecialObject $object) {
        // do stuff with the item and the special object
        $object;
        $item;
    }
}

What would be the best option in your case is hard to tell and depends largely on the scope and size of your application, and even the framework you are (not) using. Perhaps you could try to  give a real world example of what you are trying to achieve?...

Anyway, if it where up to me, Dependency Injection would be the way to go! And it has the added benefit of making your code easier to test. Even that SpecialObject would be injected into the Container if it where up to me, in stead of newing it up hardcoded inside your Container constructor.


问:
Estimating in groups - How to extract useful statistics / estimates?
As many other projects we have to estimate our jira tasks up front. This is obviously not fun and I've started hacking on a simple webapp to "gameify" this tedious process.

My idea is that an issue summary and description is presented to all participants and that when everyone has provided an upper plus a lower estimate the results are displayed to everyone. I prefer estimating in intervals instead of fixed points as it communicates uncertainty.

If I ask each participants something in the line of "provide a lower and upper estimate you feel 90% certain will contain the actual number of hours required to complete this task" - is this a 90% confidence interval?

My end goal is to reduce this to a single point estimate that can be fed into Jira + something that communicates the uncertainty related to this estimate.

What would be the best / most "correct" way of reducing the suggested intervals into a single fixed number of hours?

What would be a good indicator of the uncertainty / spread of the estimates?

答:
In the commonly referenced book Software Estimation: Demystifying the Black Art, McConnell speaks specifically to this technique in Chapter 13 (Expert Judgment in Groups).

The answer to "how to reduce this" is "by consensus."

Don’t just average your estimates and accept that. You can compute the average, but you need to discuss the differences among individual results. Do not just take the calculated average automatically.

Arrive at a consensus estimate that the whole group accepts. If you reach an impasse, you can’t vote. You must discuss differences and obtain buy-in from all group members.

The technique itself is a very good and useful one.  It is known as the "Wideband Oracle" or "Wideband Delphi" - and searching for that will find other essays and presentations out there on the net.

One approach (summarized from Software Engineering Economics):

All estimations are given simultaneously / anonymously.

The coordinator then provides a summary of estimates and presents it (this way people can see how their estimations compare to others).

The group then meets to discuss the variations in the estimates.

The group then votes (anonymous) on if they want to accept the average estimates. If any say 'no', repeat.

This approach tends to a single point, though could easily be adapted to high and low single points to give a range.

I have also seen it done in a non-anonymous form where the high and low estimators are then asked to give a short "this is why..." and repeat the process there. This has the possibility of having strong personalities dominating the estimate (or reserved ones going along with the flow rather than raising their concerns).

So yes, this is a very useful technique and can be used to give a convergence. McConnell gives a reduction of estimate error by 40% using multiple iterations compared to the initial average.


答:
There are four classes of comments:-

What the code is supposed to do.

What this piece of data really means.

What this weird looking bit of code is actually doing.

Why we changed this piece of code.

For items 1 and 4 these should really be in separate "stanzas" at the top of the code.

Items 2 and 3 should live with the line of code they are documenting.

If you have lots of type 2 and 3 comments it may be time to look at your naming standards and coding style, as clear code is much easier to understand than alphabet spaghetti plus comments.

Title: Best possible way to comment?


问:
A secondary "type system" for references?
I'm designing a language and was wondering how to incorporate C++-like references with regards to their place in the type system. I think they're useful for operations like indexing and dereferencing (v[i] returns a reference that can be assigned to, *pointer_type returns a reference to an a that behaves like an a).

Nominally in C++, a reference type like int& and its original type int are two distinct types. However, I believe that this is inconsistent with the rest of the type system: an int& can be substituted for int and they sometimes behave as they were the same type, and sometimes they don't, without explicit conversions (which is one of the reasons why references are used in the first place).

My solution would be for bindings and function arguments to essentially have a "secondary type", or rather another qualification with special rules, determining whether they are references or not. There would be two types in this secondary type system: ref and non-ref (default), and these labels would be written in places where other similar labels like const (or mut) would be -- mainly when introducing new bindings or in function types.

Thus, along with classical type mismatch errors, the compiler would report something like mismatched binding mechanism as well. For example this would happen if the programmer attempted to place a function which accepts a single integer by-reference into a list of functions which accept it by-copy (ref a -> b vs. a -> b). Although the functions would have the same type: a -> b, the binding mechanisms are incompatible (because if passed lvalues that are later assigned to, unexpected incompatible behaviour could occur).

Does this solution make sense or is it better to just wrap it in the type system and suffer inconsistencies? Are there some negative side-effects that I'm not anticipating?

To clarify: the touching points between these two type systems would have special rules. For example, there would be implicit conversions from ref to non-ref while keeping the type invariant.

答:
I think here it is fruitful to consider how mutable references work in the ML/Haskell family of languages.  In these languages, there are explicit, generic types whose values are mutable references.  I'll use Haskell because that's what I know better, but ML has similar ideas.

Take for example the STRef type in Haskell:

https://hackage.haskell.org/package/base-4.8.1.0/docs/Data-IORef.html

We can use this (and a few other tools) to, for example, sum the elements of a list in the same manner you'd do in an imperative language:

```<code>import Data.Foldable (Foldable, for_)
import Data.IORef

imperativeSum :: (Foldable t, Num a) => t a -> IO a
imperativeSum numbers = do
    ref <- newIORef 0        -- Allocate mutable cell, initialize with `0`
    for_ numbers $ \i -> do  -- Loop over the numbers, with `i` as loop var
      modifyIORef' ref (+i)  -- Mutate the cell by adding `i` to its content
    readIORef ref            -- Read final value of the cell and return it
</code>```

Here, the type of the ref variable is Num a => IORef a—a mutable reference to a value of type a (which must be a Number). Haskell is completely strict about the fact that the IORef and its content are different values with different types—an IORef Int is not the same type as an Int. So the type system automatically prevents you from using one in a context where the other is expected.

Note the operations available for an IORef are:

Creating a new IORef, with an initial value (obligatory)

Reading the current content of an IORef

Mutating the content of an IORef

Comparing two IORefs for equality ("are these two references to the same memory location").

Also note that IORef is just a generic type with some operations, and the language doesn't privilege it at all.  There are other similar types that provide for different types of references:

STRef: special reference type for use in computations that use mutation internally but don't have externally observable side effects.

TVar: reference type used in software transactional memory computations.  See Simon Peyton Jones' paper on Haskell STM for a demonstration.

Body:
I think here it is fruitful to consider how mutable references work in the ML/Haskell family of languages.  In these languages, there are explicit, generic types whose values are mutable references.  I'll use Haskell because that's what I know better, but ML has similar ideas.

Take for example the STRef type in Haskell:

https://hackage.haskell.org/package/base-4.8.1.0/docs/Data-IORef.html

We can use this (and a few other tools) to, for example, sum the elements of a list in the same manner you'd do in an imperative language:

import Data.Foldable (Foldable, for_)
import Data.IORef

imperativeSum :: (Foldable t, Num a) => t a -> IO a
imperativeSum numbers = do
    ref <- newIORef 0        -- Allocate mutable cell, initialize with `0`
    for_ numbers $ \i -> do  -- Loop over the numbers, with `i` as loop var
      modifyIORef' ref (+i)  -- Mutate the cell by adding `i` to its content
    readIORef ref            -- Read final value of the cell and return it

Here, the type of the ref variable is Num a => IORef a—a mutable reference to a value of type a (which must be a Number). Haskell is completely strict about the fact that the IORef and its content are different values with different types—an IORef Int is not the same type as an Int. So the type system automatically prevents you from using one in a context where the other is expected.

Note the operations available for an IORef are:

Creating a new IORef, with an initial value (obligatory)

Reading the current content of an IORef

Mutating the content of an IORef

Comparing two IORefs for equality ("are these two references to the same memory location").

Also note that IORef is just a generic type with some operations, and the language doesn't privilege it at all.  There are other similar types that provide for different types of references:

STRef: special reference type for use in computations that use mutation internally but don't have externally observable side effects.

TVar: reference type used in software transactional memory computations.  See Simon Peyton Jones' paper on Haskell STM for a demonstration.


问:
Multi-tenant database design
My boss is currently working on a database design for a multi-tenant capable ERP/CRM system, which will have a Sql Server backend.

Some key points of the design:

A server instance will host a "shared" database (unique model), plus one database per company (same model)

The "shared" database have tables like contacts, users, etc. that will be referred to by other company databases.

The "shared" database have triggers that will check if its data can safely be deleted (if it's used by any company, the DELETE operation must fail)

If, for security concerns, a company must NOT use shareable information, it must be set up on its own server instance, with its own "shared" database that will, in fact, be used only by that company.

And here's an implementation example for a system:

SERVER INSTANCE 1:

Shared DB

ACME

WayneEnterprises

KwikEMart

SERVER INSTANCE 2:

Shared DB

Umbrella

My boss stands by this design on the following believed benefits:

Since there's one db per company, smaller companies like KwikEMart won't suffer from the weight of the bigger ones.

User access can be defined on a "per-company" strategy. This way, Apu can be granted the privilege to read KwikEMart's Invoices table, but not ACME's.

Although I understand these benefits, the integrity tradeoffs seems overwhelming to me.

First, there's the obvious integrity cut-off between companies db and the shared db. It's impossible to make foreign keys across db boundaries.

Second, what if the Joker messes up with WayneEnterprises database so bad that Batman will have to restore a day-old backup? If ACME, on that very same day, decided to remove a shared Gotham address that was still in use in the older WayneEnterprises db, then every document which used that address won't be able to display it anymore. Unless of course there's a shared db backup from the exact same time that can be restored. But EVEN if there was one, it could lead to even more problems for both ACME and KwikEMart.

And that's just the two issues that popped right into my mind, there's probably others as well.

So my question here would be: are we getting in the right direction with this? And also, how does this kind of system is normally built?

Any guidance will be much appreciated.

答:
In the multi tennent systems I have worked on as a DBA and Developer we used 1 database per client.  That database was completely self contained and did not rely on any shared database, not even for things like the states in the US.

To make standing up a new client easy a model database was created that had all the things like States prepopulated.

The reason we did not store addresses or other common data in a shared database is that it allowed us to move the databases around several different servers to normalize the load accross the servers we had.  If a database needed a higher SLA due to a client upgrade we could just take a backup and restore the client database on the appropriate server and not need to worry if "the address for Stark Industries" existed on the new server.

The obvious question is what happens when client A updates the phone number or address for a customer?  Should client B see that change?  Wouldn't that lead to "duplicated" data if every thing is stored in seperate databases?

What if "Stark Industries" wants your Client A using a different phone number than your Client B?  Then you will have to have a way to show that and store the different numbers in the Client database or move Client A and Client B to different instances.  I am sure as you look through your shared database you will find additional instances of this problem of different clients wanting to use data differently.

For updates to the common tables a script that loops through each database is rather easy to write, a cursor on sys.databases and some dynamic SQL takes care of that part.

Overall while having a shared database may look good from a normalization standpoint once you start to look at different ways that clients use the different data, a shared database may not make sense any more.  If you are going to go the route of seperate databases per client, just go full bore and go completely seperate with no shared data.

Title: Multi-tenant database design


问:
Difference between admin and super admin?
In our company we use the term admin and super admin.

Admin - refers to the person who will handle the users, this is preferably from the external (maybe a manager of our client)

Superadmin - refers to the person who will handle the admins, preferably this is internal (a personnel that should be working in our company)

But I am looking for the standard definition of those, I've tried searching it on google but all of the results correspond to specific system (like wordpress, google, etc) and they are the one who defines it.

Is there a standard definition of admin and superadmin?

答:
Is there a standard definition of admin and superadmin?

No, there isn't.

SuperAdmin is just a word that was made up when someone needed to create a new role with more powers than ordinary admins.  In a prior job, we created a 'Super Admin' role when we modified a particular piece of software to have multi-tenant capabilities; the super-admin was allowed access to all tenants, while the Admin role was restricted to the tenant to whom they were assigned.


问:
Uncaught TypeError: Cannot read property 'add' of null
I am novice developer.

While development is going on, we come across different error issues. However for the novice of programming, it is always hard to directly understand them & solve them.

I believe, errors are generally related to typing error OR data structure error OR run-time memory error - which is related to hardware OR else.

How to elaborate and solve those errors very fast ?

答:
My thoughts:

I don't think many errors are related to typing errors.  Typos will generally not produce stuff that will compile so rarely produces anything that gets even as far as unit testing, let alone beyond that.  Those few that do are generally very easy to spot.

In 16 years in development the only issues that I've seen which were caused by a hardware fault were so major (i.e. system / sub-system down) that it was instantly obvious and was picked up by the sysadmins.  Once it makes it as far as the programmer I'd suggest that you remove the possibility of hardware error from your mind until you see some very very strong evidence to suggest that that's the case as generally it's so unlikely you shouldn't waste time thinking about it.

Errors fall into three categories:

1) Misunderstandings - that is the system is working correctly but someone has misunderstood what it's meant to do.  The best way to find out if this is the case is to get as much information as possible, ideally by speaking to someone who has actually seen the error and ask what they saw and what they expected to see.

2) Configuration Errors - while there are very few errors which are caused by hardware errors, there are plenty caused by machines being set up differently as far as software configuration goes.  This is particularly likely if you can't reproduce the error on your development set up which is likely to be pretty non-standard because of the assorted tools you've got installed and changes you've made to be productive.  The best thing to do here is to have a development test environment which is a clone of production and try and reproduce the error on there.  Once you have you can start comparing that environment to the ones where it works and see what the differences are.

3) Code Errors - the code is out and out wrong.  There are common problems (not checking return values or badly handled errors, incorrect loops and checks - for instance not checking the final record in an array or collection because the developer got confused about whether it ended at i or i-1) but exactly how common they are varies from project to project and in any case, they're easy enough to spot by walking the code.  The main things I'd say here are make sure you can reproduce the error (this may involved getting details of a specific record where the error occurs from the user) and walk the code line by line.

Broadly speaking I'd suggest the following hints:

1) Own the problem.  It's your problem and you need to fix it regardless of what it is or who originally caused it.  This may involve you looking into things that aren't your area of specialisation but it that's what it takes, that's what you do.

2) Speak to the user.  The thing which slows down problem resolution the most in my experience is bad information so cut that out by going straight to the user and find out what's happening.  Have them walk you through it, what they did, what they saw, what they expected to see.  Ask if it happens all the time or just some of the time.  If it's just some of the time ask them about patterns, get details of specific records where it occurs.  Question everything and assume nothing.  And when I say speak to them, I mean speak to them - you'll find out more than through some e-mail conversation and you'll do so far far faster.

3) Reproduce the problem.  Don't guess at the solution, reproduce it, it's the only way of knowing you've really found what's happening.  Walk the code step by step and see what's actually happening.  This may involve reproducing the environment or getting a copy of the database - if you have to, that's what you do.

4) Be realistic.  It's not a hardware problem and you've not found a problem with the compiler.  Once you've worked out it's a real problem (that is that the user is not mistaken about what it's meant to be doing) and you've reproduced it, by far the most likely issue is that the code is wrong so don't kid yourself otherwise.

5) Fix the root problem, not the symptom.  If they say everything is out by 1, don't just subtract 1 from everything, find out WHY it was out by 1 and fix that.  If you only fix the symptom, you will see the problem again.

ContentLicense: CC BY-SA 4.0


问:
Creating variations of a property heavy class
What kind of pattern or design can prevent the creation of a class packed with properties that aren't always used?

Example

```<code>class Car{
   public string type;
   public string name;
   public DateTime manufactured;
   public int model;
   public Color color;
   public int VIN;
   // ..and on
}

public Car(string name, Color color){
    this.name = name;
    this.color = color;
}
</code>```

Sometimes you want to make a Car with just some info, like the make and model, but you always want it to have a few defaults. How do you avoid 20 children classes or constructor overloads in this case?

答:
You can avoid multiple constructor overloads by using one constructor with named, optional arguments.

```<code>public Car(string name, Color color, string type="sedan", string model = "Taurus")
</code>```

...which you can call thusly:

```<code>var car = new Car("Ford", Color.Red)
</code>```

type and model are optional; it will set type to "sedanandmodel` to "Taurus" automatically, unless you override them in the parameter list.

Further Reading

Named and Optional Arguments

Body:
You can avoid multiple constructor overloads by using one constructor with named, optional arguments.

public Car(string name, Color color, string type="sedan", string model = "Taurus")

...which you can call thusly:

var car = new Car("Ford", Color.Red)

type and model are optional; it will set type to "sedanandmodel` to "Taurus" automatically, unless you override them in the parameter list.

Further Reading

Named and Optional Arguments


问:
I am able to use PUT to act like GET when using my REST API
I wrote a simple REST API (just learning) using Go and I am calling it using python requests. I have two methods, "update_x", which updates the value of the resource, "get_x_times_n" which gets the value of the resource. Logically, I would think that I need (and can only use) put for "update_x" and get for "get_x_times_n". However, I can very easily implement a method, such that I can call "get_x_times_n" using put.

Here is my Go code:

```<code>package main

import (
    "fmt"
    "log"
    "io"
    "io/ioutil"
    "net/http"
    "encoding/json"
    "strconv"
)

func main() {
    my_resource := MyResource{x: 0}

    http.HandleFunc("/update_x", my_resource.update_x)
    http.HandleFunc("/get_x_times_n", my_resource.get_x_times_n)
    http.HandleFunc("/get_x_times_n_wierd", my_resource.get_x_times_n_wierd)
    http.ListenAndServe("localhost:8000", nil)
}

type MyResource struct {
    x int
}

func (mr *MyResource) update_x(w http.ResponseWriter, r *http.Request) {

    body, err := ioutil.ReadAll(io.Reader(r.Body))
    if err != nil {
        panic(err)
    }

    if err := r.Body.Close(); err != nil {
        panic(err)
    }

    var delta int

    err = json.Unmarshal(body, &delta)

    if err != nil {
        panic(err)
    }
    mr.x += delta
}

func (mr *MyResource) get_x_times_n(w http.ResponseWriter, r *http.Request) {

    err := r.ParseForm()
    if err != nil {
        panic(err)
    }

    log.Println(r.Form)

    n_str := r.Form["n"][0]

    n, err := strconv.Atoi(n_str)

    if err != nil {
        panic(err)
    }

    result := mr.x * n

    fmt.Fprint(w, result)
}

func (mr *MyResource) get_x_times_n_wierd(w http.ResponseWriter, r *http.Request) {
    fmt.Println(r.Body)
    body, err := ioutil.ReadAll(io.Reader(r.Body))
    if err != nil {
        panic(err)
    }

    if err := r.Body.Close(); err != nil {
        panic(err)
    }

    var n int

    err = json.Unmarshal(body, &n)

    if err != nil {
        panic(err)
    }

    result := mr.x * n

    fmt.Fprint(w, result)
}
</code>```

And here is my Python session:

```<code>In [51]: import requests

In [52]: r = requests.put("http://localhost:8000/update_x", data='5')
In [53]: r = requests.get("http://localhost:8000/get_x_times_n", params={"n": 5})

In [54]: r.content
Out[54]: '25'

In [55]: r = requests.put("http://localhost:8000/get_x_times_n_wierd", data="5")

In [56]: r.content
Out[56]: '25'
</code>```

I can see why this is happening, since in both methods I have r *http.Request, I can pass whatever data I want. And also in both methods I have access to w http.ResponseWriter, I can write anything I want.

My question is: What am I doing wrong? Am I just abusing requests when using the API? Did I set up my API completely wrong? (If the API was set up properly something like this would not be allowed?). Or both? Or maybe something else?

答:
Nothing builtin into the server will figure out that a request should have been a PUT request. (How could it?) It's up to you to handle that. The default behavior for the go http server is simply to ignore the method. (Some other systems have other default, such as only supporting GET by default). If you want a particular request to only work when used with a particular http method, you have to enforce it. Something like:

```<code>if r.Method != "PUT" {
   sendRejection(w);
}
</code>```

My recommendation is to always enforce that the correct method is being used.

Body:
Nothing builtin into the server will figure out that a request should have been a PUT request. (How could it?) It's up to you to handle that. The default behavior for the go http server is simply to ignore the method. (Some other systems have other default, such as only supporting GET by default). If you want a particular request to only work when used with a particular http method, you have to enforce it. Something like:

if r.Method != "PUT" {
   sendRejection(w);
}

My recommendation is to always enforce that the correct method is being used.


问:
Identity propagation using Azure service bus
We currently have a platform with a SOA architecture in which the user's identity is propagated from the web application via middle tier services (REST and SOAP) until we actually query our data storage layer.

We use the user's identity to apply access control at the entity layer. The user's identity is communicated between services by attaching security tokens to the service invocations (SAML/JWT).

One of our customers wants to use an Event Driven Architecture to build a product on our platform instead of the more traditional request/response pattern. They want to use the Azure Service Bus Queues and Topics to achieve a higher scalability.

I was wondering how in this architecture we could propagate the user's identity to the consumers of the messages/events stored on the service bus.

FOR EXAMPLE:

Suppose the user creates a new task in the front-end web application. Instead of calling the Task service (sending along the user's identity) and waiting for the response, the application stores the task creation event in the queue and delegates the actual creation of the task to a background worker subscribed to this type of message.

However, in order to determine if the user who initiated the task creation is allowed to create a task, the task service (a background worker) needs to call the entity layer in the context of the user.

I could store the security token together with the task creation payload, but given the temporal decoupling of the producer and consumer, this token may have expired by the time it is used to call into the entity layer.

Are there any well-established patterns to solve this problem? I realize that I can move the access control into the web-application, but as we've built a platform for others to build applications on, I do not necessarily want to trust those application to enforce the security requirements. That is the key reason why we've build the access control into the entity layer.

Are all consumers of service bus events always part of a trusted subsystem, or are there ways of solving this elegantly?

答:
There are commonly two identity roles in play when you use middleware for routing messages. One identity role is about the relationship between senders/receivers and the middleware, the other is about the end-to-end relationship between the producer of the message and the ultimate consumer of the message.

The identity used in these two roles can be the same, but it also can be different and often is.

For Service Bus, we chose a token-based model for access control that allows a trusted subsystem approach and concrete identities to be used for the sender/receiver to middlware relationship with the same model. The shared access token can be directly generated by the client when in possesion of the shared key. That's how our token providers work with connection strings. You can also generate those tokens externally in a simple STS (using the token provider or https://brentdacodemonkey.wordpress.com/2015/02/21/sas-its-just-another-token/) and trade them against some end-user identity proof, and pass the token on to the shared access token provider.

For the end-to-end relationship between producer and consumer, we leave the door open for whatever is appropriate for the use-case. We stay out of and don't interpret the payload body and thus allow that to be signed and encrypted. You can flow tokens and key-hints in the message properties. You can flow long-lived tokens (including JWTs from Azure Active Directory) in properties or payload, or you can use X.509 certs to authenticate and protect the end-to-end payload. JWE is a fresh standard for payload-level security https://www.rfc-editor.org/rfc/rfc7516


答:
Another option is to just make them public properties. Since they are optional, the caller should be able to assign a value to them, or set them to null if they already have a value. That would make it easier for callers to assign values as needed. Sometimes the callers have certain code flows which allows assigning properties at that point much more convenient. Without making them properties, that cannot be supported.

If you go with that pattern, you could make them auto-properties, and each method can validate the properties it requires and throw appropriate exceptions. This gets away with doing a lot of validations with different combinations in the constructor (regardless of whether you take them as optional parameters in the constructor or not).

As for the callers, they can call the constructor with required properties and use initializers for assigning values to auto-properties, e.g.

```<code>public class Car
{
    public string Name { get; set; }
    public DateTime Manufactured { get; set; }
    public int Model { get; set; }
    public Color Color { get; set; }
    public int Vin { get; set; }
    public Car (string name, DateTime manufactured)
    { ... } // required properties

    public Register()
    {
        if (Vin == 0) { throw new SomeException(); }
        // Code to register here
    }
}
</code>```

And consuming code:

```<code>public void Method()
{
    Car myCar = new Car("myCar", DateTime.Now())
    {
        Model = 5 // Every caller may not need to assign it.
    };

    if (someCondition) { myCar.Color = Color.Red; }
    MethodA(car);
    car.Register();
}

private void MethodA(Car car)
{
    if (someCheck || methodCall())
    { car.Vin = 888; }
}
</code>```

Note that this saves the latter code from having to use other variables to return some value from a child method, which can directly operate on car and set the property. Keeping design discussion aside, in more involved code, I have had to change my classes to support this pattern (i.e. auto-properties) as opposed to hard checks in constructors.

There can definitely be some exceptions to this pattern, but this seems to be a widely used pattern and you can find many .NET framework class libraries that support this. I use this by default unless there is a reason not to.

Title: Creating variations of a property heavy class

Body:
What kind of pattern or design can prevent the creation of a class packed with properties that aren't always used?

Example

```<code>class Car{
   public string type;
   public string name;
   public DateTime manufactured;
   public int model;
   public Color color;
   public int VIN;
   // ..and on
}

public Car(string name, Color color){
    this.name = name;
    this.color = color;
}
</code>```

Sometimes you want to make a Car with just some info, like the make and model, but you always want it to have a few defaults. How do you avoid 20 children classes or constructor overloads in this case?

Body:
Another option is to just make them public properties. Since they are optional, the caller should be able to assign a value to them, or set them to null if they already have a value. That would make it easier for callers to assign values as needed. Sometimes the callers have certain code flows which allows assigning properties at that point much more convenient. Without making them properties, that cannot be supported.

If you go with that pattern, you could make them auto-properties, and each method can validate the properties it requires and throw appropriate exceptions. This gets away with doing a lot of validations with different combinations in the constructor (regardless of whether you take them as optional parameters in the constructor or not).

As for the callers, they can call the constructor with required properties and use initializers for assigning values to auto-properties, e.g.

public class Car
{
    public string Name { get; set; }
    public DateTime Manufactured { get; set; }
    public int Model { get; set; }
    public Color Color { get; set; }
    public int Vin { get; set; }
    public Car (string name, DateTime manufactured)
    { ... } // required properties

    public Register()
    {
        if (Vin == 0) { throw new SomeException(); }
        // Code to register here
    }
}

And consuming code:

public void Method()
{
    Car myCar = new Car("myCar", DateTime.Now())
    {
        Model = 5 // Every caller may not need to assign it.
    };

    if (someCondition) { myCar.Color = Color.Red; }
    MethodA(car);
    car.Register();
}

private void MethodA(Car car)
{
    if (someCheck || methodCall())
    { car.Vin = 888; }
}

Note that this saves the latter code from having to use other variables to return some value from a child method, which can directly operate on car and set the property. Keeping design discussion aside, in more involved code, I have had to change my classes to support this pattern (i.e. auto-properties) as opposed to hard checks in constructors.

There can definitely be some exceptions to this pattern, but this seems to be a widely used pattern and you can find many .NET framework class libraries that support this. I use this by default unless there is a reason not to.


答:
There is a reason for which this can be forced. Simply consider visual studio and emacs/vim. As on windows visual studio will add an extra \r at the end of the line. This mess up with the display in emacs/vim. Also the tabs create problem. The problem with us is that we developers work in Linux but our software architect is comfortable in visual studio. He once cursed us saying that we do not format the file properly. But then when he found that this is because of the default setting issue, we all agreed to the same format.

If anyone force me to use particular IDE, I will not feel bad. Whatever is good for the team I will respect that and will compromise accordingly.

Title: Should every member of a team use the same IDE?

Body:
Do you think it makes sense to enforce that every member of a team must use the same IDE?

For instance all engineers that are already on the team use IDE X. Two new engineers come and want to use IDE Y instead because that's what they have been using for several years now.

Do you have any experience with "mixed IDE" teams? If so what is it?


答:
An approach I have seen is to ask for 2 numbers.  The first number is the "expected" time, which you want to be an unbiased estimator of how long the task will take.  The second is the 90% confidence time, you want 90% of your tasks to fall below this estimated line.  These numbers are then rephrased in terms of the "expectation" and an "uncertainty" term which is the difference between the two.

The idea behind this is that if I have 10 tasks, each of which will take 1 week "on average" and 2 weeks "90% worst case," then I don't really need to budget for 10-20 weeks.  The probability of getting a 90% worst case on every single task is very low.  We get to use the central limit theorem to cut down on the final task uncertainty.

The final numbers are found by adding the "expectation" terms and doing a root-sum-squared of the "uncertainty" terms.  In my pathological case where I have 10 tasks, each of which is 1-2 weeks, I add the 10 expectations to get 10 weeks.  Then I RSS 10 1-week uncertainties together to get 3.16 weeks of uncertainty.  Thus my final estimate, instead of a scary looking 10 to 20 weeks, is presented as 10 weeks to 13 weeks 1 day.

Title: Estimating in groups - How to extract useful statistics / estimates?

Body:
As many other projects we have to estimate our jira tasks up front. This is obviously not fun and I've started hacking on a simple webapp to "gameify" this tedious process.

My idea is that an issue summary and description is presented to all participants and that when everyone has provided an upper plus a lower estimate the results are displayed to everyone. I prefer estimating in intervals instead of fixed points as it communicates uncertainty.

If I ask each participants something in the line of "provide a lower and upper estimate you feel 90% certain will contain the actual number of hours required to complete this task" - is this a 90% confidence interval?

My end goal is to reduce this to a single point estimate that can be fed into Jira + something that communicates the uncertainty related to this estimate.

What would be the best / most "correct" way of reducing the suggested intervals into a single fixed number of hours?

What would be a good indicator of the uncertainty / spread of the estimates?


问:
OAuth2 ROPC vs Basic Auth for public REST APIs?
The specific use case I'm interested in here is authenticating REST clients against publicly-available server endpoints (such as a public REST API).

The simplest solution here is Basic Auth. But I often hear OAuth2 touted as a superior auth solution in almost all circumstances.

The thing is, the only OAuth2 grant type that is feasible for a REST client authenticating against a REST server is Resource Owner Password Credentials (ROPC), because Code Grants and Implicit Grants require a UI/webpage (hosted by the Auth Server) for the user to login to and manually authorize the client app.

The way ROPC works is, by sending the resource owner's username/password, and the client ID as query string params?!? This is even less secure (IMHO) then Basic Auth, which at least base-64 encodes the credentials and sends them inside a header which can be encrypted by TLS!

So I ask: in the context of public REST APIs, is OAuth2 ROPC really any better than Basic Auth? What is more secure than OAuth2 ROPC?

Update

I just read this excellent article which explains Amazon's non-OAuth2 based REST security for AWS. It is essentially a private key-based solution where hashes of each REST request are generated and sent as sidecars along-side the normal (un-encrypted) request. Only the client and the server know the private key, so when the server receives the request (again, containing the normal request + the hashed request), the server looks up the client's private key, applies the same hash to the normal request, and then compares the two hashes.

This sounds way more complicated, complex and secure than OAuth2's ROPC! Unless I'm missing something major here, OAuth2 ROPC is just sending client_id, username and password as query string params...totally and utterly unsecure! This HMAC/hashed-based solution seems to be much more impressive and secure.

The thing is, even the author of that article goes on to say:

You [will] also slowly realize and accept that at some point you will have to implement OAuth...

Ba-ba-bwhat?!?! If OAuth2 is less secure than this clever HMAC/hash-based solution, why does the author of this article feel OAuth needs to be embraced at some point. I'm so confused.

答:
Basic authentication is not a good way to secure your REST API. I explained the reasons why in this answer.

When you build a REST API, you are implementing the resource server in OAuth2 terms. All your API needs to do is validate that the token passed along with the request in the Authorization HTTP header is valid and from a trusted issuer. See this link for steps how to implement validation if there's no library available.

How your client acquires the token from the authorization server depends on what kind of client it is. Remember, you need to specify the type of client your going to use when you register the client with the authorization server.

In case of a web application talking to your server, it could use the authorization code grant. If it's an untrusted client like a mobile application or a JavaScript app, it should use the implicit grant.

For backend services which can't interact with a resource owner, you can use client credentials grant. For command line tools, you could use either client credentials or the resource owner password grant.

It all depends on what kind of client you are using.

Finally, validating a JWT token happens on the resource server without the need to talk to the authorization server. This leads to a better scalable architecture then solutions that need to look up private data for each client.


答:
An often overlooked option in this case is seperating the interface from the implementation. Of course if you can live with them being public properties, by all means. If that is not an option consider making Car a private class of the class that would do the instantiation and then make an interface for the getters only like this.

```<code>interface ICar
{
    int Foo{get;}
    string Bar{get;}
}

class SomeService
{
    private class MyCar : ICar
    {
        int Foo{get;set;}
        string Bar{get;set;}
    }
    public ICar MakeCar()
    {
        return new MyCar{/*todo*/}
    }
}
</code>```

Now the caller have complete control while you still provide encapsulation to the consumers.

Body:
An often overlooked option in this case is seperating the interface from the implementation. Of course if you can live with them being public properties, by all means. If that is not an option consider making Car a private class of the class that would do the instantiation and then make an interface for the getters only like this.

interface ICar
{
    int Foo{get;}
    string Bar{get;}
}

class SomeService
{
    private class MyCar : ICar
    {
        int Foo{get;set;}
        string Bar{get;set;}
    }
    public ICar MakeCar()
    {
        return new MyCar{/*todo*/}
    }
}

Now the caller have complete control while you still provide encapsulation to the consumers.


问:
Why are the sizes of programs so large?
If we look at the vintage program Netscape Navigator or an early version of Microsoft Word, those programs were less than 50 MB in size. Now when I install google chrome it is 200 MB and desktop version of Slack is 300 MB. I read about some rule that programs will take all available memory no matter how much it is but why?

Why are the current sizes of programs so large compared to 10 or 15 years ago? The programs are not doing significantly more functions and do not look very different. What is it that is the resource hog now?

答:
"Looking very different" is a matter of perception. Today's graphics have to look good at totally different screen resolutions than they used to, with the result that a 100x100 image that used to be more than good enough for a logo would now look horribly tacky. It has had to be replaced with a 1000x1000 image of the same thing, which is a factor of 100 right there. (I know you can use vector graphics instead, but that just emphasizes the point - vector graphics rendering code has had to be added to systems that didn't need it before, so this is just a trade-off from one kind of size increase to another.)

"Working differently" is likewise a matter of perception. Today's browser does massively more things than one from 1995. (Try surfing the internet with a historic laptop one rainy day - you'll find it's almost unusable.) Not many of them are used very much, and uses may be completely unaware of 90% of them, but they're there.

On top of that, of course, is the general tendency to spend less time on optimizing things for space and more on introducing new features. This is a natural side-effect of larger, faster, cheaper computers for everyone. Yes, it would be possible to write programs that are as resource-efficient as they were in 1990, and the result would be stunningly fast and slick. But it wouldn't be cost-effective anymore; your browser would take ten years to complete, by which time the requirements would have completely changed. People used to program with extreme attention to efficiency because yesteryear's slow, small machines forced them to, and everyone else was doing it as well. As soon as this changed, the bottleneck for program success shifted from being able to run at all to running more and more shiny things, and that's where we are now.

Title: Why are the sizes of programs so large?


答:
If you compare Netscape Navigator to a modern browser, there is a massive difference in functionality. Just compare the HTML 3.2 Spec (51 pages when I do a print preview) with the current HTML Spec (PDF version is 1155 pages). That's a 20x increase in size.

Netscape Navigator did not have a DOM and did not have CSS! There were no dynamic changes of the document, no JavaScript modifying the DOM or style-sheets. No tabs. No audio or video. A modern browser is a vastly more complex program.

Title: Why are the sizes of programs so large?

Body:
If we look at the vintage program Netscape Navigator or an early version of Microsoft Word, those programs were less than 50 MB in size. Now when I install google chrome it is 200 MB and desktop version of Slack is 300 MB. I read about some rule that programs will take all available memory no matter how much it is but why?

Why are the current sizes of programs so large compared to 10 or 15 years ago? The programs are not doing significantly more functions and do not look very different. What is it that is the resource hog now?


答:
By time, user's needs are evolving and more and more demanding, so vendor/authors of different softwares are forced to satisfy those needs in the name of competition.

But satisfying a new need means often adding new code. New code means new vulnerabilities to fix. Fixing new vulnerabilities may add code or open doors to new vulnerabilities.

Each added feature to satisfy a user's need may need more processor power for speed (we all complain about the speed of this or that browser), new graphical resources for better visual effects...etc.

All this means adding new layers of applications (code), security and sometimes hardware.

Title: Why are the sizes of programs so large?


答: In additional to the other ansers, 10 years ago there typically would have been separate versions for localised / internationalised versions. Now it's generally the case that programs will bundle full localisation support into every released version which pads the program size.</p>

Title: Why are the sizes of programs so large?


问:
Best practice for parameters in asynchronous APIs in Java
Is there a best practice for using Guava's ListenableFuture in parameters in API calls? Compare these two versions of an interface that internally does a compare-and-set (I'm using Guava's ListenableFuture):

```<code>interface MyDao {
    ListenableFuture<Data> getData(String id);
    ListenableFuture<Boolean> updateData(ListenableFuture<Data> data, int newFieldValue);
}
</code>```

```<code>interface MyDao {
    ListenableFuture<Data> getData(String id);
    ListenableFuture<Boolean> updateData(Data data, int newFieldValue);
}
</code>```

The first looks a bit messy, and the implementation will likely involve a Futures.transform of its own, but you could also argue that it's an asynchronous API, so taking futures as parameters might make sense. Where it gets nice is that it tidies up the business logic when using the interface so it reads like synchronous code:

```<code>ListenableFuture<Data> data = dao.getData("123");
ListenableFuture<Boolean> success = dao.updateData(data, 10);
</code>```

Compare that to

```<code>ListenableFuture<Data> data = dao.getData("123");
ListenableFuture<Boolean> success = Futures.transform(data, (Data d) -> dao.updateData(d, 10));
</code>```

And that's with a lambda. It's hideous in Java 7.

The obvious drawback is the interface looks inconsistent. Why is data a future, but newFieldValue isn't? Should id be a future, too? Along those lines, it makes a trivial call incredibly complicated—almost like Java wrapper objects before autoboxing.

It also doesn't do anything to clean up hideous stack traces when futures fail; they still cascade through every transform.

答:
I think having a ListenableFuture in an API signature method doesn't make it inconsistent.

It's only there to declare explicity to the user an asynchronous computation while hiding the boilerplate thread logic. Like an Optional would declare explicity to the user a possibility of missing data while hiding the boilerplate "if not null" logic.

These 2 links explain a bit more my thoughts: Monadic Java and Use of optional

However, if you think any user of your API potentially want to call updateData but have only an instance of Data you could consider adding the corresponding method to your API.

```<code>public interface MyDao {
    ListenableFuture<Boolean> updateData(ListenableFuture<Data> data, int newFieldValue);
    ListenableFuture<Data> getData(String id);
    default ListenableFuture<Boolean> updateData(Data data, int newFieldValue) {
        //TODO: wrap data in a ListenableFuture and call updateData
    }
}
</code>```

Body:
I think having a ListenableFuture in an API signature method doesn't make it inconsistent.

It's only there to declare explicity to the user an asynchronous computation while hiding the boilerplate thread logic. Like an Optional would declare explicity to the user a possibility of missing data while hiding the boilerplate "if not null" logic.

These 2 links explain a bit more my thoughts: Monadic Java and Use of optional

However, if you think any user of your API potentially want to call updateData but have only an instance of Data you could consider adding the corresponding method to your API.

public interface MyDao {
    ListenableFuture<Boolean> updateData(ListenableFuture<Data> data, int newFieldValue);
    ListenableFuture<Data> getData(String id);
    default ListenableFuture<Boolean> updateData(Data data, int newFieldValue) {
        //TODO: wrap data in a ListenableFuture and call updateData
    }
}


问:
Hide authentication information on Github
When your creating a project that has some sort of information that needs to be private (authentication details, etc), but you want to use some public repo like Github, are there anything that can be done to keep these things private?

All I can really think of is ignore the file that has this data in it, but then if you need to change anything, it needs changing everywhere that it's checked out, making the VCS pointless. Same issue with reverts etc.

Or is this something that cannot really be avoided easily when using a public repo?

答:
There are a couple of different ways to deal with this problem. It all depends on your personal preference.

Don't commit any configuration files

This is probably the easiest, although you have to make sure you never accidentally commit anything with configuration information in it. With git, once it has been committed and pushed out or forked it's practically impossible to remove it. If you ever leaked anything in a configuration file that was pushed, consider that information compromised.

Major disadvantage here is that you have to maintain some kind of documentation on the structure and entries you need in the configuration file. Deploying the application means creating a configuration file for your environment. A new version that adds a configuration option will need some kind of documentation on the deployment process for the new version to make sure this option is set.

Commit a sandbox-file

A lot of projects favor an approach where you can check out, build and run an application without the need to do any configuration. You can achieve this by providing a default configuration file. For your database, this file could just point to a localhost database-server with 'myproject_user' as username and 'myproject_password' as password for the 'myproject_db'. This has the advantage of providing a default configuration file with all options present AND is part of the code because it runs with the application, unlike your documentation.

Downside is that in this case people checking out your application have to set up their environment to match this, or still change the configuration settings. Does not fix the issue with having to remember to set configuration values on deployment either.

Provide a parameters.dist-file that is checked at deploy-time

Frameworks such as Symfony actually version configuration files by having a parameters.yml.dist-file. (see http://symfony.com/doc/current/best_practices/configuration.html). This is a template file that simply contains the structure of the config file, without any values, and during deployment compares the existing parameters.yml-file to the parameters.yml.dist-file that is deployed. Obsolete entries are dropped and new entries that need a value prompt to the person deploying the app for a value.

This is a solid approach for big applications and frameworks that will be used in other applications or by external parties, but might be overkill for smaller applications where deployment is often a simple copy/past or FTP upload and you can follow a deployment-document that outlines what entries you need to change.


答:
One reason is that the data packaged within applications are larger because they are of higher resolution and quality. An icon back in the days of Netscape was at most 32x32 pixels, with at most 8 bit depth, (possibly only 4,) while now it is probably something like 64x64 and it is in true color with transparency, meaning 32 bit depth.  That's 16 times larger.  And space is so cheap that people often do not even bother checking the "compressed" option when generating a PNG.

Another reason is that applications nowadays carry a mind-boggling amount of data with them, which older applications did not.  There exist applications today that get shipped together with a "getting started" presentation in video.

Another reason is that programming languages today tend to go together with rich run-time environments, which are fairly large, to the tune of 100MB each.  Even if you do not use all of the features of your run-time environment, you still have to package the whole thing with your app.

But the main reason is that today there exist tons and tons of libraries out there that we can use in our applications, and we have developed a culture of using libraries as to avoid the constant re-invention of the wheel. Of course, once you start using libraries, several questions pop up, and we have developed the habit of giving the most liberal answers to them:

Is it worth to include yet another library if it is going to be used by only one of my functions? --yes.

Is it worth to include yet another library if I only need a tiny subset of the entire wealth of functionality offered by that library? --yes.

Is it worth to include yet another library if its inclusion will only save me from 2 days of work?  --yes.

Is it worth to include multiple libraries that serve more or less the same purpose just because different programmers on my payroll happen to already be familiar with different libraries? --yes.

(Please note that I am just observing these tendencies, I am making no statement whatsoever as to whether I agree or disagree with them.)

Another reason worth mentioning is that when trying to decide which application to use among several choices, some users think that the one which occupies more space will be more feature-packed, will have fancier graphics, etc.  (Which is complete nonsense, of course.)

So, to conclude, does software behave like gas?  Does it tend to occupy all of the space available to it?  In a certain sense yes, but not to any alarming extent. If we look at what takes up most space on our drives, for most of us the answer is that it is not applications, but media such as movies and music by far.  Software has not been bloating at the same rate that storage capacity has been expanding, and it is unlikely that it ever will, so in the future applications are likely to represent a negligible fraction of the storage space available to users.

Title: Why are the sizes of programs so large?


答:
Since this is a question asked in general terms, I will try to make my answer as broad as possible.

Solving an error involves answering two questions assuming you are familiar with the development language/platform/technology

What does the code do ?

The answer to this can be found both from the top first by code comprehension (either manually or using tools) and from the bottom by good old debugging. What is more important is to religiously document any  incrementally knowledge thus gained in a easy to understand format and gradually construct a model in your mind.

What should the code do ?

The answer to this can be found from the existing documentation of the product as well that of technology, platform and language , discussion with colleagues and the end users, and from the knowledge gained and model constructed in the first step.

Solving error is a matter of aligning 1. with 2.

Title: Uncaught TypeError: Cannot read property 'add' of null

Body:
I am novice developer.

While development is going on, we come across different error issues. However for the novice of programming, it is always hard to directly understand them & solve them.

I believe, errors are generally related to typing error OR data structure error OR run-time memory error - which is related to hardware OR else.

How to elaborate and solve those errors very fast ?


问:
How should an HTTP server respond to a GET of an absolute URI of a different server?
I'm implementing a custom HTTP 1.1 server. According to Page 35 of RFC 2616, an HTTP Request URI may take one of four forms. One of these forms is "absolute-URI", which is exactly what it sounds like.

Let's say I have a server at http://www.example.com. My server is sent the following request:

```<code>GET http://www.google.com.au HTTP/1.1
Host: www.example.com
</code>```

What response should I send for a request like this? I want to say maybe 406 Not Acceptable or 409 Conflict. Is there a standard way to respond to this?

答:
First, RFC 2616 is obsolete; you should be referring to RFC 7230 and RFC 7231 instead.

(RFC 7230 § 5.5) HTTP servers which receive the absolute form of a URI in the request-line ignore the Host: header and use only that absolute URI for any further processing. The server then has to decide what to do with it.

Existing general purpose HTTP servers use virtual hosts to provide service for several different hostnames, and if the given hostname does not match an existing virtual host, they will attempt to serve it with the default virtual host. Unless the server has been explicitly configured to proxy such requests, but this isn't in your scenario.

While the RFC does note that this situation can occur, it does not mandate a particular response. If you are implementing a server capable of serving virtual hosts, you can do what other servers do and serve it with the default virtual host. Or you can decide to refuse such requests and explicitly serve a 403 Forbidden. (RFC 7231 § 6.5.3)

The 403 (Forbidden) status code indicates that the server understood the request but refuses to authorize it.  A server that wishes to make public why the request has been forbidden can describe that reason in the response payload (if any).

The 406 and 409 errors you mention aren't intended for this scenario.

(RFC 7231 § 6.5.6) 406 is intended for the situation when the server found one or more documents matching the URL, but none of them have a MIME type matching any type given in the request's Accept header.

(RFC 7231 § 6.5.8) 409 is intended for situations in which the data being uploaded can't be processed due to a conflict with existing data, such as a version control merge conflict.

OwnerDisplayName: Ephemera


答:
If you want to reject the request, I'd go with

400 Bad Request

The 400 (Bad Request) status code indicates that the server cannot or
     will not process the request due to something that is perceived to be
     a client error (e.g., malformed request syntax, invalid request
     message framing, or deceptive request routing).

400 is the catch-all error for cases where the client made a mistake and no specific error is applicable.

If you want to accept the request and show some of your content, I would not silently serve the contents of your "default" domain. I'd rather use a 3xx redirect to your default domain.

What I would not use:

HTTP 404 because it gives the client the impression that it talked to the correct server where the file is missing.

HTTP 403 for similar reasons as 404 and because it fits even less.
406 Not Acceptable

HTTP 406 Not Acceptable

The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request.

Your denial is unrelated to accept headers.

HTTP 409 Conflict

Indicates that the request could not be processed because of conflict in the request, such as an edit conflict in the case of multiple updates.

No conflicting changes here. A client receiving this code might refetch the data and apply its changes to the new version. This clearly doesn't fit your situation.

Title: How should an HTTP server respond to a GET of an absolute URI of a different server?

Body:
I'm implementing a custom HTTP 1.1 server. According to Page 35 of RFC 2616, an HTTP Request URI may take one of four forms. One of these forms is "absolute-URI", which is exactly what it sounds like.

Let's say I have a server at http://www.example.com. My server is sent the following request:

```<code>GET http://www.google.com.au HTTP/1.1
Host: www.example.com
</code>```

What response should I send for a request like this? I want to say maybe 406 Not Acceptable or 409 Conflict. Is there a standard way to respond to this?


问:
What are the standards for dealing with pluralia tantum in your code?
When using variables of which their plural and singular are both the same, how do you name them? Are there any standards out there?

For example:

```<code>Series[] series  // Plural
Series series    // Singular
</code>```

Indepth:

To be specific, my collection of series needs to be called series (due to JSON formatting), would you consider naming the singular form of Series that gets added to the collection Series s?

As in:

```<code>List<Series> series = new List<Series>();
Series s;

while (someBool)
{
    s = new Series();
    s.Name = "Name";
    while (anotherBool)
    {
        s.AddValue(someValue);
    }
    series.Add(s);
}
</code>```

答:
I do not think there is a standard for this. The majority of english nouns does not come with this problem. So if you do not want to add a term like "list" or "collection" to the variable name, a possible solution is to circumvent that problem by simply choosing a different term.

In your example, one could use "sequence" instead of "series" (if that is the meaning of "series" you had in mind).

Of course, for some words like "spectacles" or "trousers" finding an appropriate synonym which fits to your context might not be easy. For those it is probably the best solution to follow @DavidPacker's suggestion to use a word like "spectaclesCollection" or "trousersList".


答: One reason is dependencies. A program with rich functionality and good looks needs a lot of things done - encryption, spell checking, working with XML and JSON, text editing and lots of other things. Where would they come from? Maybe you roll your own and keep them as small as possible. Most likely you use third party components (MIT licensed open source perhaps) which have a lot of functionality you never actually need but once you need a single function from a third party component you often have to carry the whole component around. So you add more and more dependencies and as they themselves evolve and grow your program that depends on them grows too.</p>

Title: Why are the sizes of programs so large?


答:
It's trivially true that software has to be built to fit two things: The users and the available hardware. A program is fit for its purpose if it does what the user wants in a timely manner with the hardware at the user's disposal. Well duh. But as hardware improves in basically all measurable dimensions the number of discrete programs which move from unfit to fit increases - the design space gets bigger:

Higher level languages make it possible to express ideas in less code & time than before. This lowered complexity, conversely, makes it possible to express increasingly complex ideas.

Bundling more data with the application can make it instantly more usable. For example, it probably won't be long before spell checking applications come bundled with every language known to humanity - it's only a few gigabytes, after all.

Hardware trade-offs allow developers and users more choice in which resource they care about. See for example FLAC/OGG vs WAV, SVG vs PNG, database indexes.

Humane interfaces often trade off what would previously amount to huge amounts of hardware for usability. Anti-aliasing, high resolutions, fast refreshing, and swiping between what amounts to discrete panels all make for a more realistic, and therefore intuitive and relatable, experience.

Title: Why are the sizes of programs so large?


问:
Wrapping third party library is best practice
I came across with following statements while reading the Clean Code book of Robert C. Martin.

Chapter : 7 :  Error Handling
 Page No : 109

  ..In fact, wrapping third-party APIs is a best practice. When you wrap
  a third-party API, you minimize your dependencies upon it: You can
  choose to move to a different library in the future without much
  penalty. Wrapping also makes it easier to mock out third-party calls
  when you are testing your own code.

 One ﬁnal advantage of wrapping is
  that you aren’t tied to a particular vendor’s API design choices. You
  can deﬁne an API that you feel comfortable with.

I am quite confused about the bold part.

I am totally clueless how can we move to different library so easily if we wrap the third party library and how testing becomes easy with it ?

答:
Imagine you have a complicated library that you depend on. Say the library exposes four different calls to its functionality, and your code base uses each of them three times.

If you use the raw vendor API in your code, then if the vendor library changes or you have to replace it, you'll have to change twelve API calls in your code base. If you had an abstraction layer between your code and their code, you'd have to change four places in the abstraction layer and none at all in your code base. You can see that this saves effort - the more effort the more calls the API offers. And most real-world APIs offer more than four entry points.


答:
You are right to be suspicious. I haven't read this book, but I personally strongly disagree with this advice.

This approach adds both additional code and additional abtraction.

Code can add bugs and overhead.

Abstractions have their limit, and the poor maintainer now has to understand both the library and the abstraction on top to do its job.

Abtraction is hard: either you mimic the underlying library API almost 1:1, and at this point this "abstraction" is not one anymore. Or you create your own API that will certainly mismatch with the design of the library you are using, or with the future library you will want to use in the future. In the codebase I am working on right now, there is such an abstraction over the XML parser we are using. We have a known performance issue, where the abstraction needs to keep a list of all nodes and iterate over it over and over, to satisfy the abstraction's API. It's been more than 10 years that we depend on this specific 3rd party lib, and we never had the need to change it. Removing this awful abstration is on my todo list...

Also, third party libraries being replaced are an exception and not the rule. This advice is asking you to do some work upfront, with all the disadvantages I outlined above, for a case that is unlikely to happen.

About the "mocking calls to 3rd party lib" part, I am unable to think of a case where I needed to mock a library. I may be a bit shortsighted, here.

Title: Wrapping third party library is best practice

Body:
I came across with following statements while reading the Clean Code book of Robert C. Martin.

Chapter : 7 :  Error Handling
 Page No : 109

  ..In fact, wrapping third-party APIs is a best practice. When you wrap
  a third-party API, you minimize your dependencies upon it: You can
  choose to move to a different library in the future without much
  penalty. Wrapping also makes it easier to mock out third-party calls
  when you are testing your own code.

 One ﬁnal advantage of wrapping is
  that you aren’t tied to a particular vendor’s API design choices. You
  can deﬁne an API that you feel comfortable with.

I am quite confused about the bold part.

I am totally clueless how can we move to different library so easily if we wrap the third party library and how testing becomes easy with it ?


答:
In addition to Killian Foth's very good answer, consider some issues with testing code that uses APIs:

Testing is difficult because the API does something "real".  Imagine you want to test your code that uses an API making a credit card payment.  If each time you run your code it results in a real transaction, that is going to be a big limit on your testing.

Testing is difficult because you can't control the information the API returns.

Your code is supposed to do something special on Christmas, but the API only returns the current date.  Wait until Christmas to test that feature?

You want to test handling a million email addresses, but these come from an external platform that only has a few test users.  Add a million test users manually to that platform?

Your code uses a phone GPS API to get the current location and then set the language accordingly.  Do you have to actually go to different countries to see if this works?

Many more examples could be created, but you get the idea.  All of these issues are solved by wrapping the API.  Then you can replace the actual API with a test one that returns anything you want for testing purposes.