答:
If you're asking how to manage your own keys then there are 2 places to store them:

For dev/test - you might as well put them in the SCM repo. Unless your repo is publicly accessible.

For production, you want to store them with a single point of authority, either somebody (with a deputy) who keeps the originals on a CD or USB drive in a firesafe or similar.

Copies of these can then be given to the relevant people who need to deploy them. So (eg) a DBA who creates the DB and sets up the user accounts associated with it will be given the passwords and accounts to use. This can be emailed to him, assuming you trust your email provider, or handed on a scrap of paper that is eaten immediately afterwards if you are really paranoid.

In many cases you don't need to be quite so secure - the DBA may create the passwords and user accounts to use himself, but he must them tell someone (preferably the contact who keeps this information) what they were in case of accident.

Otherwise, you use the OSs features to secure the details - either creating accounts using LDAP or AD, or putting certificate files into protected directories and ensuring they are secured so only the correct user accounts can access them.

Title: Where should you store/how should you control access to application secrets?

Body:
There are these relevant questions questions:

Strategy for keeping secret info such as API keys out of source control?

How do you deal with configuration files in source control?

How to version control config files pragmatically?

But as far as I can tell, they deal with the opposite side of the problem. So yes, we've designed a good application that has no secrets stored in it or its repository. They either pull them from the environment variables or from files stored on the system. Great, awesome, secure, right?

But what about our secrets? Where do they come from? Do we store these in another vcs repository? Do they only exist in an encrypted database?

Obviously we want developers to have their own credential sets - but we're going to need to have credentials for our test/preprod/prod servers.

How do we keep those secure? Of course we want them accessible to the systems that need them...


问:
What are functional programmers using in place of UML?
I'm CS student. I am currently attending lectures, where we're taught Objective Analysis and Design. It consists mostly of writing use cases, analysing the problem that we can face when writing some application for the client, and how to design the project so that it's both extensible, clear to developers, and doesn't spawn problems when client argues about some features. Since it's 'objective', we're learning it from OOP point of view(classes and such).

Now we're using UML as a helper tool. I believe I have a good grasp on OOP, but I have also learned functional paradigm and used it successfully in some of my smaller projects.

Our teacher, when confronted with "what about functional paradigm?" question, answered that he wasn't programming any larger project in functional languages, and he doesn't know what tool may functional programs be using.

So, what would they use? Is there some methodology for this? Or maybe there's no need for such thing?

答:
I can't speak for all functional programmers, but those I know all start out by writing the type signatures of the top-level functions, then as they need more detail, they write the type signatures of the helper functions, and so forth.

This works because of the lack of side effects in functional programming, so functions are all specified in terms of only their inputs and outputs.  This makes their type signatures much more useful as a design tool than in imperative programming.  That's one reason you see them used even when the compiler could infer them.

As far as diagramming tools go, with all due respect to your professor, I haven't used those to any significant degree in any paradigm since I left school.

ContentLicense: CC BY-SA 3.0


问:
How are head first books?
I have never read any of them but I find their style interesting and unique.  I am not sure if they are worth giving money/time?</p>

答:
There are two extreme opinions about Head First: The first is that they're awful, and the other is that they're excellent.

I personally think they're awful because their explanations are way too long and very off topic most of the time. They're big books with not so much content. They feel like books for kids (or childish adults).

Some people (most people I think) love those books because they're very easy to read and it's almost impossible not to understand their explanations.

Head First books are good only if you're a beginner. They cannot be used as reference books. They're written for people who know absolutely nothing about the topic.

Note that there are many Head First books and many Head First authors. The most famous ones are "Head First Design Patterns" and "Head First Java". And they also have books which aren't related to programming (about physics and statistics). So you cannot really say anything about the whole "Head First" series. The only "Head First" books I'v tried reading are "Head First Design Patterns", "Head First iPhone Development" and "Head First Servlets & JSPs". I didn't like them (found their explanations, metaphors and jokes annoying) but I know about people who did like them.

Here's a list of all their books: http://oreilly.com/store/series/headfirst.html

Here are some opinions about "Head First Design Patterns": https://stackoverflow.com/questions/386087/head-first-design-patterns-opinions-wanted

Title: How are head first books?

ContentLicense: CC BY-SA 2.5


问:
Temporary Variables or Not: Choose CPU Time or RAM?
In a case where multiple variables are set equal to an operation using the result of an other operation, is it best to create a temporary variable for the result of the second operation (this would save memory) or is it best to create a temporary variable for the result of the second operation (this would save time)?

For example:

```<code>// Option 1 (memory)
totalRevenue += numSold * price;
totalProfit += numSold * price - numSold * cost;
return numSold * price;

// Option 2 (time)
saleRevenue = numSold * price;
totalRevenue += saleRevenue;
totalProfit += saleRevenue - numSold * cost;
return saleRevenue;
</code>```

I understand that this choice, especially in the example above, is rather trivial. My suspicion is that it makes most sense to create the temporary variable, but I can't help feeling that it is a waste. No, memory isn't very scarce these days, but I feel like Option 1 wastes less time than Option 2 does memory. Am I right?

Why choose one way over the other?

答:
You need to put one more thing in consideration: readability. Option 2 seems much more readable than option 1.

Apart of readability, in this example, I would go to Option 2 for a reason that I'll explain below.

Here is a representation of your code in Java and the bytecode produced:

```<code>public class Main {

    public static int totalRevenue;
    public static int totalProfit;

    public static int option1(int numSold, int price, int cost) {
        // Option 1 (memory)
        totalRevenue += numSold * price;
        totalProfit += numSold * price - numSold * cost;
        return numSold * price;
    }

    public static int option2(int numSold, int price, int cost) {
        // Option 2 (time)
        int saleRevenue = numSold * price;
        totalRevenue += saleRevenue;
        totalProfit += saleRevenue - numSold * cost;
        return saleRevenue;
    }
}
</code>```

Bytecode:

```<code>public class Main {
  public static int totalRevenue;

  public static int totalProfit;

  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static int option1(int, int, int);
    Code:
       0: getstatic     #2                  // Field totalRevenue:I
       3: iload_0
       4: iload_1
       5: imul
       6: iadd
       7: putstatic     #2                  // Field totalRevenue:I
      10: getstatic     #3                  // Field totalProfit:I
      13: iload_0
      14: iload_1
      15: imul
      16: iload_0
      17: iload_2
      18: imul
      19: isub
      20: iadd
      21: putstatic     #3                  // Field totalProfit:I
      24: iload_0
      25: iload_1
      26: imul
      27: ireturn

  public static int option2(int, int, int);
    Code:
       0: iload_0
       1: iload_1
       2: imul
       3: istore_3
       4: getstatic     #2                  // Field totalRevenue:I
       7: iload_3
       8: iadd
       9: putstatic     #2                  // Field totalRevenue:I
      12: getstatic     #3                  // Field totalProfit:I
      15: iload_3
      16: iload_0
      17: iload_2
      18: imul
      19: isub
      20: iadd
      21: putstatic     #3                  // Field totalProfit:I
      24: iload_3
      25: ireturn
}
</code>```

For the sake of understandability, iload_* load data from stack and istore_* store data into stack.

So you can notice that you really saved one memory allocation, but you spend precious CPU cycles.

But here is the reason: Memory allocations work in blocks, not at byte level. Each time a thread runs, it will allocate a certain amount of memory to use in stack operations. So unless you are lucky enough to have these 4 bytes overflow memory allocation for this block (and requiring you to setup a larger stack size), you will be ending up spending the same memory amount to run both examples. But in the second one, you will spend more cycles doing math calculations.

Body:
You need to put one more thing in consideration: readability. Option 2 seems much more readable than option 1.

Apart of readability, in this example, I would go to Option 2 for a reason that I'll explain below.

Here is a representation of your code in Java and the bytecode produced:

public class Main {

    public static int totalRevenue;
    public static int totalProfit;

    public static int option1(int numSold, int price, int cost) {
        // Option 1 (memory)
        totalRevenue += numSold * price;
        totalProfit += numSold * price - numSold * cost;
        return numSold * price;
    }

    public static int option2(int numSold, int price, int cost) {
        // Option 2 (time)
        int saleRevenue = numSold * price;
        totalRevenue += saleRevenue;
        totalProfit += saleRevenue - numSold * cost;
        return saleRevenue;
    }
}

Bytecode:

public class Main {
  public static int totalRevenue;

  public static int totalProfit;

  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static int option1(int, int, int);
    Code:
       0: getstatic     #2                  // Field totalRevenue:I
       3: iload_0
       4: iload_1
       5: imul
       6: iadd
       7: putstatic     #2                  // Field totalRevenue:I
      10: getstatic     #3                  // Field totalProfit:I
      13: iload_0
      14: iload_1
      15: imul
      16: iload_0
      17: iload_2
      18: imul
      19: isub
      20: iadd
      21: putstatic     #3                  // Field totalProfit:I
      24: iload_0
      25: iload_1
      26: imul
      27: ireturn

  public static int option2(int, int, int);
    Code:
       0: iload_0
       1: iload_1
       2: imul
       3: istore_3
       4: getstatic     #2                  // Field totalRevenue:I
       7: iload_3
       8: iadd
       9: putstatic     #2                  // Field totalRevenue:I
      12: getstatic     #3                  // Field totalProfit:I
      15: iload_3
      16: iload_0
      17: iload_2
      18: imul
      19: isub
      20: iadd
      21: putstatic     #3                  // Field totalProfit:I
      24: iload_3
      25: ireturn
}

For the sake of understandability, iload_* load data from stack and istore_* store data into stack.

So you can notice that you really saved one memory allocation, but you spend precious CPU cycles.

But here is the reason: Memory allocations work in blocks, not at byte level. Each time a thread runs, it will allocate a certain amount of memory to use in stack operations. So unless you are lucky enough to have these 4 bytes overflow memory allocation for this block (and requiring you to setup a larger stack size), you will be ending up spending the same memory amount to run both examples. But in the second one, you will spend more cycles doing math calculations.

ContentLicense: CC BY-SA 4.0


问:
When are enums NOT a code smell?
Dilemma

I've been reading a lot of best practice books about object oriented practices, and almost every book I've read had a part where they say that enums are a code smell. I think they've missed the part where they explain when enums are valid.

As such, I am looking for guidelines and/or use-cases where enums are NOT a code smell and in fact a valid construct.

Sources:

"WARNING As a rule of thumb, enums are code smells and should be refactored
to polymorphic classes. [8]"
Seemann, Mark, Dependency Injection in .Net, 2011, p. 342

[8] Martin Fowler et al., Refactoring: Improving the Design of Existing Code (New York: Addison-Wesley, 1999), 82.

Context

The cause of my dilemma is a trading API. They give me a stream of Tick data by sending thru this method:

```<code>void TickPrice(TickType tickType, double value)
</code>```

where enum TickType { BuyPrice, BuyQuantity, LastPrice, LastQuantity, ... }

I've tried making a wrapper around this API because breaking changes is the way of life for this API. I wanted to keep track of the value of each last received tick type on my wrapper and I've done that by using a Dictionary of ticktypes:

```<code>Dictionary<TickType,double> LastValues
</code>```

To me, this seemed like a proper use of an enum if they are used as keys. But I am having second thoughts because I do have a place where I make a decision based on this collection and I can't think of a way how I could eliminate the switch statement, I could use a factory but that factory will still have a switch statement somewhere. It seemed to me that I'm just moving things around but it still smells.

It's easy to find the DON'Ts of enums, but the DOs, not that easy, and I'd appreciate it if people can share their expertise, the pros and cons.

Second thoughts

Some decisions and actions are based on these TickType and I can't seem to think of a way to eliminate enum/switch statements. The cleanest solution I can think of is using a factory and return an implementation based on TickType. Even then I will still have a switch statement that returns an implementation of an interface.

Listed below is one of the sample classes where I'm having doubts that I might be using an enum wrong:

```<code>public class ExecutionSimulator
{
  Dictionary<TickType, double> LastReceived;
  void ProcessTick(TickType tickType, double value)
  {
    //Store Last Received TickType value
    LastReceived[tickType] = value;

    //Perform Order matching only on specific TickTypes
    switch(tickType)
    {
      case BidPrice:
      case BidSize:
        MatchSellOrders();
        break;
      case AskPrice:
      case AskSize:
        MatchBuyOrders();
        break;
    }
  }
}
</code>```

答:
Whether using an enum is a code smell or not depends on the context.
I think you can get some ideas for answering your question if you consider the expression problem. So, you have a collection of different types and a collection of operations on them, and you need to organize your code. There are two simple options:

Organize the code according to the operations. In this case you can use an enumeration to tag different types, and have a switch statement in each procedure that uses the tagged data.

Organize the code according to the data types. In this case you can replace the enumeration by an interface and use a class for each element of the enumeration. You then implement each operation as a method in each class.

Which solution is better?

If, as Karl Bielefeldt pointed out, your types are fixed and you expect the system to grow mainly by adding new operations on these types, then using an enum and having a switch statement is a better solution: each time you need a new operation you just implement a new procedure whereas by using classes you would have to add a method to each class.

On the other hand, if you expect to have a rather stable set of operation but you think you will have to add more data types over time, using an object-oriented solution is more convenient: as new data types must be implemented, you just keep adding new classes implementing the same interface whereas if you were using an enum you would have to update all switch statements in all procedures using the enum.

If you cannot classify your problem in either of the two options above, you can look at more sophisticated solutions (see e.g. again  the Wikipedia page cited above for a short discussion and some reference for further reading).

So, you should try to understand in which direction your application may evolve, and then pick a suitable solution.

Since the books you refer to deal with the object-oriented paradigm, it is not surprising that they are biased against using enums. However, an object-orientation solution is not always the best option.

Bottomline: enums are not necessarily a code smell.

Title: When are enums NOT a code smell?


答:
The UML standard defines over a dozen different diagram types, as shown in this handy chart:

Source: https://en.wikipedia.org/wiki/File:UML_diagrams_overview.svg

See also Figure A.5 The taxonomy of structure and behavior diagrams in the UML 2.5 spec.

Note that this is an example of a class diagram, with is-a subtyping relationships between diagram types, and abstract diagram types in italics.
  While these diagram types actually are classes within the UML metamodel, this class diagram is still useful to illustrate a hierarchy, without any connection to OOP.

There are a couple of types that clearly only apply to OOP, for example the class diagram or the object diagram. But the rest is more widely applicable than just for object-oriented systems.

State Machine Diagrams – FP does not avoid states, it merely makes them explicit. A State Machine Diagram can be useful to explain the control flow, or the various state transitions in the program.

Activity Diagrams – are useful in similar cases as for the State Machine Diagram, but on a higher level. They can be used to explain the flow of data between various subsystems, or to model external business processes.

Interaction Diagrams – model the interactions between multiple stateful processes. Clearly, this is not useful for modeling the internals of a pure functional program. However, UML is not only about modelling the structure of code, but primarily about providing an universal modelling language. With an interaction diagram, I could e.g. use interaction diagrams to model the external behaviour between systems, e.g. between a browser and a web server – even when those are written using FP techniques.

Use Case Diagrams – Use cases and requirements are independent of the technology used to satisfy them. OOP or FP is absolutely irrelevant here.

Deployment Diagrams – This diagram type is used to describe the relation between runnable software and hardware resources. Whether that software was written in an FP language does not matter.

Component Diagrams – Most functional languages have explicit support for modular programming these days. A Component Diagram describes components/modules, and their offered and required interfaces. This reminds me a lot of OCaml's Functor modules.

Profile Diagrams – describe extensions to UML itself and are as such never actually used.

Composite Structure Diagrams – describe the structure of composites. It can be used to describe data structures, or even the interaction points of a function. Wikipedia shows a diagram for the Fibonacci function as an example:

Source: https://commons.wikimedia.org/wiki/File:Composite_Structure_Diagram.png

In a sense, this would be the functional programmers choice rather than a class diagram, but this seems horribly overengineered….

Package Diagrams – Packages are the UML equivalent of namespaces. This diagram type is more part of the UML language infrastructure than a separate diagram type. For example, you could use packages to categorize a large Use Case Diagram.

So as we have seen, various UML diagram types can still be useful when doing functional programming.

I have rarely felt the desire to use UML when designing a system, and primarily use UML to do my assigned homework, or to communicate the outline of an architecture with a quick sketch. Even for an OOP system, UML does not provide enough value to use it all the time – actual code says more than a thousand diagrams. I could imagine using UML-like diagrams to explain the dependencies between various functions and data structures in an FP program, but have yet to do so – my personal style prefers a blend of OOP and FP where FP techniques are used at a local scale, but do not influence the overall architecture.

Title: What are functional programmers using in place of UML?

Body:
I'm CS student. I am currently attending lectures, where we're taught Objective Analysis and Design. It consists mostly of writing use cases, analysing the problem that we can face when writing some application for the client, and how to design the project so that it's both extensible, clear to developers, and doesn't spawn problems when client argues about some features. Since it's 'objective', we're learning it from OOP point of view(classes and such).

Now we're using UML as a helper tool. I believe I have a good grasp on OOP, but I have also learned functional paradigm and used it successfully in some of my smaller projects.

Our teacher, when confronted with "what about functional paradigm?" question, answered that he wasn't programming any larger project in functional languages, and he doesn't know what tool may functional programs be using.

So, what would they use? Is there some methodology for this? Or maybe there's no need for such thing?


问:
Is measuring the binary size of a c++ program a good indication of code complexity? Or something else?
In my company we have this obligatory practice before a review to be send the binary size impact of the code change to be measured and provided.

We must use -Os for this metric to avoid unpredictable inlining. There is no customer or product driven arguments for it. It is a big server that is installed as singleton of a dedicated machine, where the executable size is completely ignorable in comparison to all the other resources involved in the system.

The main argument for this practice is that -Os binary size correlates with code complexity.

Is measuring the binary size a reliable metric to use when evaluating code complexity? Or for evaluating anything else?

答:
As noted in the comments, size of the binary could be very important for some embedded systems - especially old ones.

However, as you've noted in the update to the question

There is no customer or product driven arguments for it. It is a big server that is installed as singleton of a dedicated machine, where the executable size is completely ignorable in comparison to all the other resources involved in the system.

This is one of the most pointy-haired schemes I've heard in a long time.  You'll be penalized for including a library that's well tested and solves a lot of problems, but they'll let a Bubble sort get past?

Seriously, it would be useful to see some justification for their main argument that the binary size correlates with other qualities of the code.  It's entirely possible that I'm dead wrong and there is such a correlation, but I kind of doubt it.


问:
Does it matter to you that a software is "available source" but not "open source"
You probably know the list of open source licenses officially approved by the OSI. Most notably I guess would be the GPL, MIT, [insert your favorite license here].

I recently ran into a project which although was open source (the creator made all source code available), was not officially open source under one of those official licenses.

It released the source, but made no promise to release the source in the future.

It allowed modification suggestions, but made no promises to accept patches and disallowed external distribution of externally-patched versions.

It allowed the use of the software in commercial or paid projects, but disallowed the sale of the software itself.

I suppose it could be called "available source" not open source as we like to think of it.

I can see why the management team of a company wouldn't want to do business with this software. They can't fork it, they can't sell it, they can't create their own version of the software and distribute it or sell it.

But would it matter to you as part of a software engineering team who's just using this software? I can still get my work done with it, I can use it in a project for which I'm paid (but I can't sell the software itself, which I'm not in the business of doing anyway), and I can make changes to the code to make it behave differently for my needs (but I can't make those modifications public), and if I do want those modifications officially made available to others, the approval is up to the project itself and they choose whether to incorporate them in an official release or not.

So we know that a company that wants to base its business on this "available source" software can't do that, but as someone from the software engineering team, would those differences matter to you or do they seem less relevant?

Curious what others think of this.

答:
This is why the Free Software Foundation uses the terms 'free' or 'non-free' to describe software. They are not referring to price, but restrictions that are placed on use or distribution of the software.

It looks like you have hit one of the rare corner cases where you have full access to the source code of something, but the software is not "Open Source" by the OSI definition.

Either term has the capacity to become a misnomer. I paid $50 for my first copy of emacs (on QIC tape), but emacs is free software. I have the source code to some proprietary applications that my company uses internally, but they are not open source.

The thing that raises the biggest red flag (at least to me) is no guarantee to access to the source code of future versions. If you heavily depend on being able to modify this tool, I'd be careful. Even if you have  verbal agreement with the vendor that you'll always have code, unless it's in contract form .. that agreement never happened.

As CTO, I try my best to ensure that we do not depend on non-free software. I've been on the bad end of vendor lock in several times in the past, a mistake that I like to avoid. While we do use some proprietary stuff, our business would not suffer undue hardship if all of a sudden we could not use it any longer.

It sounds to me like you are building stuff around having this software and access to the code, so I'd recommend getting something in writing that says you'll always have access. What happens if the vendor is purchased?


问:
Which pattern can I use for doing computations involving similar yet different object subtypes?
How do I design code that has two qualities:

uses similar but different subtypes of an object

uses similar but different types of computation on the above objects

Example

I am refactoring this from a legacy code that had if/then/else statements for different object types in one file, and if/then/else statements for doing various computing tasks with the objects in another file.

Using OOP I can rewrite it somewhat like this:

```<code>class Pricing {
    public $base;
}

class PumpPricing extends Pricing {
    public $pumpCost;
    public $pumpOption1;
};
class MotorPricing extends Pricing {
    public $motorCost;
    public $motorOption1;
};
class PartPricing extends Pricing {
    public $partCost;
};
</code>```

Later . . .

```<code>//I can put proper object creation into Factory:
$pricing = (new PriceFactory())->getPriceObject("motor");

//but how do I compartmentalize computations?
//i.e. this:

if  (get_class($pricing) == "PumpPricing") {
    $json = array( //future json
        'total' => $pricing->pumpCost + $pricing->base + $pricing->pumpOption1,
        'pump_option_1' => $pricing->pumpOption1
    );
}
else if (get_class($pricing) == "MotorPricing") {
    $json = array(
        'total' => $pricing->motorCost + $pricing->base + $pricing->motorOption1,
        'motor_option_1' => $pricing->motorOption1
    );
}
</code>```

Question

Considering my goal to get rid of if/then/else statements in the mainstream code and to encapsulate the computations, where and how do I do that?

For one, I can group the above formulas into a single computational getter, and put it into the Pricing object.  i.e. to mimic line from above:

```<code>'total' => $pricing->getTotal(),
'motor_option_1' => $pricing->getOption1()
</code>```

But, I am still dealing with different options that I want to group into an array, i.e. names and quantity of the options are different.

答:
1) You can just add a serialize method to each class. So your base class Pricing would define an abstract method like:

```<code>abstract function getPriceObject();
</code>```

Then each class would define a unique getPriceObject.

http://php.net/manual/en/language.oop5.abstract.php

2) That said this also looks like a problem suited for the visitor pattern. If someone else wants to write a verbose explanation of this it might be useful, but searching online gives a lot of PHP examples.

Body:
1) You can just add a serialize method to each class. So your base class Pricing would define an abstract method like:

abstract function getPriceObject();

Then each class would define a unique getPriceObject.

http://php.net/manual/en/language.oop5.abstract.php

2) That said this also looks like a problem suited for the visitor pattern. If someone else wants to write a verbose explanation of this it might be useful, but searching online gives a lot of PHP examples.


答:
As a first step, you can put that behaviour into methods of your Price hierarchy objects. Then:

```<code>class PumpPricing extends Pricing {
  ...
  function serializableRepresentation() {
    return array(
      'total' => $this->pumpCost + $this->base + $this->pumpOption1,
      'pump_option_1' => $this->pumpOption1
    );
  }
}
</code>```

This simplifies your main code to:

```<code>$json = $pricing->serializationRepresentation();
</code>```

Unfortunately, this likely violates the Single Responsibility Principle for more complex behaviours. In this case, we can use the Visitor Pattern to allow us to define extension methods on your types. The only thing that has to be modified is adding an acceptVisitor method to each Pricing type:

```<code>class PumpPricing extends Pricing {
  ...
  function acceptVisitor($v) {
    return $v->visitPumpPricing($this);
  }
}
</code>```

We can now define operations in external classes:

```<code>class SerializationRepresentationVisitor {
  ...
  function visitPumpPricing($pricing) {
    return array(
      'total' => $pricing->pumpCost + $pricing->base + $pricing->pumpOption1,
      'pump_option_1' => $pricing->pumpOption1
    );
  }
}

function serializationRepresentation($pricing) {
  $visitor = new SerializationRepresentationVisitor();
  return $pricing->acceptVisitor($visitor);
}
</code>```

This changes your main code to:

```<code>$json = serializationRepresentation($pricing);
</code>```

I believe using a visitor like this to enable the easy addition of new functionality strikes the best balance between separating responsibilities, and making for readable code. This is particularly advisable when operating on a hierarchy of dumb types that do not have much behaviour of their own, but a lot of operations that act on the whole hierarchy. Your Pricing hierarchy is one example, as would be abstract syntax trees in a compiler.

Title: Which pattern can I use for doing computations involving similar yet different object subtypes?

Body:
How do I design code that has two qualities:

uses similar but different subtypes of an object

uses similar but different types of computation on the above objects

Example

I am refactoring this from a legacy code that had if/then/else statements for different object types in one file, and if/then/else statements for doing various computing tasks with the objects in another file.

Using OOP I can rewrite it somewhat like this:

```<code>class Pricing {
    public $base;
}

class PumpPricing extends Pricing {
    public $pumpCost;
    public $pumpOption1;
};
class MotorPricing extends Pricing {
    public $motorCost;
    public $motorOption1;
};
class PartPricing extends Pricing {
    public $partCost;
};
</code>```

Later . . .

```<code>//I can put proper object creation into Factory:
$pricing = (new PriceFactory())->getPriceObject("motor");

//but how do I compartmentalize computations?
//i.e. this:

if  (get_class($pricing) == "PumpPricing") {
    $json = array( //future json
        'total' => $pricing->pumpCost + $pricing->base + $pricing->pumpOption1,
        'pump_option_1' => $pricing->pumpOption1
    );
}
else if (get_class($pricing) == "MotorPricing") {
    $json = array(
        'total' => $pricing->motorCost + $pricing->base + $pricing->motorOption1,
        'motor_option_1' => $pricing->motorOption1
    );
}
</code>```

Question

Considering my goal to get rid of if/then/else statements in the mainstream code and to encapsulate the computations, where and how do I do that?

For one, I can group the above formulas into a single computational getter, and put it into the Pricing object.  i.e. to mimic line from above:

```<code>'total' => $pricing->getTotal(),
'motor_option_1' => $pricing->getOption1()
</code>```

But, I am still dealing with different options that I want to group into an array, i.e. names and quantity of the options are different.

Body:
As a first step, you can put that behaviour into methods of your Price hierarchy objects. Then:

class PumpPricing extends Pricing {
  ...
  function serializableRepresentation() {
    return array(
      'total' => $this->pumpCost + $this->base + $this->pumpOption1,
      'pump_option_1' => $this->pumpOption1
    );
  }
}

This simplifies your main code to:

$json = $pricing->serializationRepresentation();

Unfortunately, this likely violates the Single Responsibility Principle for more complex behaviours. In this case, we can use the Visitor Pattern to allow us to define extension methods on your types. The only thing that has to be modified is adding an acceptVisitor method to each Pricing type:

class PumpPricing extends Pricing {
  ...
  function acceptVisitor($v) {
    return $v->visitPumpPricing($this);
  }
}

We can now define operations in external classes:

class SerializationRepresentationVisitor {
  ...
  function visitPumpPricing($pricing) {
    return array(
      'total' => $pricing->pumpCost + $pricing->base + $pricing->pumpOption1,
      'pump_option_1' => $pricing->pumpOption1
    );
  }
}

function serializationRepresentation($pricing) {
  $visitor = new SerializationRepresentationVisitor();
  return $pricing->acceptVisitor($visitor);
}

This changes your main code to:

$json = serializationRepresentation($pricing);

I believe using a visitor like this to enable the easy addition of new functionality strikes the best balance between separating responsibilities, and making for readable code. This is particularly advisable when operating on a hierarchy of dumb types that do not have much behaviour of their own, but a lot of operations that act on the whole hierarchy. Your Pricing hierarchy is one example, as would be abstract syntax trees in a compiler.


问:
Is micro-optimisation important when coding?
I recently asked a question on Stack Overflow to find out why isset() was faster than strlen() in PHP. This raised questions around the importance of readable code and whether performance improvements of micro-seconds in code were worth even considering.

My father is a retired programmer, and I showed him the responses. He was absolutely certain that if a coder does not consider performance in their code even at the micro level, they are not good programmers.

I'm not so sure - perhaps the increase in computing power means we no longer have to consider these kind of micro-performance improvements? Perhaps this kind of considering is up to the people who write the actual language code? (of PHP in the above case).

The environmental factors could be important - the Internet consumes 10% of the world's energy. I wonder how wasteful a few micro-seconds of code is when replicated trillions of times on millions of websites?

I'd like to know answers preferably based on facts about programming.

Is micro-optimisation important when coding?

My personal summary of 25 answers, thanks to all.

Sometimes we need to really worry about micro-optimisations, but only in very rare circumstances. Reliability and readability are far more important in the majority of cases. However, considering micro-optimisation from time to time doesn't hurt. A basic understanding can help us not to make obvious bad choices when coding such as

```<code>if (expensiveFunction() || counter < X)
</code>```

Should be

```<code>if (counter < X || expensiveFunction())
</code>```

(Example from @zidarsk8) This could be an inexpensive function and therefore changing the code would be micro-optimisation. But, with a basic understanding, you would not have to, because you would write it correctly in the first place.

答:
I started programming nearly 31 years ago, where memory and CPU are scarce. Maybe this is why I agree with your father.

I do believe a good coder needs to worry about optimisation in every line of code. But I would add to this sentence: as much as it worths and always trying to favor readability over optimisation in places where computations are not critical.

For example, in another thread, a guy asked about the code below, which solution he would choose: CPU or Memory.

```<code>public class Main {

    public static int totalRevenue;
    public static int totalProfit;

    public static int option1(int numSold, int price, int cost) {
        // Option 1 (memory)
        totalRevenue += numSold * price;
        totalProfit += numSold * price - numSold * cost;
        return numSold * price;
    }

    public static int option2(int numSold, int price, int cost) {
        // Option 2 (time)
        int saleRevenue = numSold * price;
        totalRevenue += saleRevenue;
        totalProfit += saleRevenue - numSold * cost;
        return saleRevenue;
    }
}
</code>```

This code generates the following bytecode:

```<code>public class Main {
  public static int totalRevenue;

  public static int totalProfit;

  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static int option1(int, int, int);
    Code:
       0: getstatic     #2                  // Field totalRevenue:I
       3: iload_0
       4: iload_1
       5: imul
       6: iadd
       7: putstatic     #2                  // Field totalRevenue:I
      10: getstatic     #3                  // Field totalProfit:I
      13: iload_0
      14: iload_1
      15: imul
      16: iload_0
      17: iload_2
      18: imul
      19: isub
      20: iadd
      21: putstatic     #3                  // Field totalProfit:I
      24: iload_0
      25: iload_1
      26: imul
      27: ireturn

  public static int option2(int, int, int);
    Code:
       0: iload_0
       1: iload_1
       2: imul
       3: istore_3
       4: getstatic     #2                  // Field totalRevenue:I
       7: iload_3
       8: iadd
       9: putstatic     #2                  // Field totalRevenue:I
      12: getstatic     #3                  // Field totalProfit:I
      15: iload_3
      16: iload_0
      17: iload_2
      18: imul
      19: isub
      20: iadd
      21: putstatic     #3                  // Field totalProfit:I
      24: iload_3
      25: ireturn
}
</code>```

For the sake of understandability, 'iload_' load data from stack and 'istore_' save data into stack.

It's easy to notice that you really saved one memory allocation in one solution spending more CPU cycles. That kind of question may arise even for experienced programmers.

But there is a catch in this example: stack memory is pre-allocated in blocks, not at byte level. Each time a thread runs, it will allocate a certain amount of memory to use in stack operations. So unless you are lucky enough to have these 4 bytes overflow your stack (and requiring you to setup a larger stack size), you will be ending up spending the same memory amount to run both examples. But in the second one, you are spending more cycles doing math calculations and your code is much less readable.

I brought it here to give a sample that discussing about optimisations in small portions of code is not evil. Some guy closed that question pointing to this thread. But this thread don't answer that specific question. It only discuss about "don't worry about optimisation". And due to this stupid mantra, people feel that is right not go to deep understanding.

There is a reasonable answer to that question, and maybe one can even give a better answer about the internals. Once learned, a good programmer will be able to repeat that pattern instinctively, and will become a better programmer. Programmers must have critical thinking about their code and must try to understand, as much as possible, how machine will process it.

I'm not advocating here that we all need to optimize little things. Remember that I recommended to favor readability over micro-optimisations.

I just believe that repeating the mantra "don't worry about optimisation" don't make things better. It only make programers lazy. Programmers must be instigated to know how things work behind the scenes. This way people can pursue to write better code, and wisely choose when not to optimise.

Body:
I started programming nearly 31 years ago, where memory and CPU are scarce. Maybe this is why I agree with your father.

I do believe a good coder needs to worry about optimisation in every line of code. But I would add to this sentence: as much as it worths and always trying to favor readability over optimisation in places where computations are not critical.

For example, in another thread, a guy asked about the code below, which solution he would choose: CPU or Memory.

public class Main {

    public static int totalRevenue;
    public static int totalProfit;

    public static int option1(int numSold, int price, int cost) {
        // Option 1 (memory)
        totalRevenue += numSold * price;
        totalProfit += numSold * price - numSold * cost;
        return numSold * price;
    }

    public static int option2(int numSold, int price, int cost) {
        // Option 2 (time)
        int saleRevenue = numSold * price;
        totalRevenue += saleRevenue;
        totalProfit += saleRevenue - numSold * cost;
        return saleRevenue;
    }
}

This code generates the following bytecode:

public class Main {
  public static int totalRevenue;

  public static int totalProfit;

  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static int option1(int, int, int);
    Code:
       0: getstatic     #2                  // Field totalRevenue:I
       3: iload_0
       4: iload_1
       5: imul
       6: iadd
       7: putstatic     #2                  // Field totalRevenue:I
      10: getstatic     #3                  // Field totalProfit:I
      13: iload_0
      14: iload_1
      15: imul
      16: iload_0
      17: iload_2
      18: imul
      19: isub
      20: iadd
      21: putstatic     #3                  // Field totalProfit:I
      24: iload_0
      25: iload_1
      26: imul
      27: ireturn

  public static int option2(int, int, int);
    Code:
       0: iload_0
       1: iload_1
       2: imul
       3: istore_3
       4: getstatic     #2                  // Field totalRevenue:I
       7: iload_3
       8: iadd
       9: putstatic     #2                  // Field totalRevenue:I
      12: getstatic     #3                  // Field totalProfit:I
      15: iload_3
      16: iload_0
      17: iload_2
      18: imul
      19: isub
      20: iadd
      21: putstatic     #3                  // Field totalProfit:I
      24: iload_3
      25: ireturn
}

For the sake of understandability, 'iload_' load data from stack and 'istore_' save data into stack.

It's easy to notice that you really saved one memory allocation in one solution spending more CPU cycles. That kind of question may arise even for experienced programmers.

But there is a catch in this example: stack memory is pre-allocated in blocks, not at byte level. Each time a thread runs, it will allocate a certain amount of memory to use in stack operations. So unless you are lucky enough to have these 4 bytes overflow your stack (and requiring you to setup a larger stack size), you will be ending up spending the same memory amount to run both examples. But in the second one, you are spending more cycles doing math calculations and your code is much less readable.

I brought it here to give a sample that discussing about optimisations in small portions of code is not evil. Some guy closed that question pointing to this thread. But this thread don't answer that specific question. It only discuss about "don't worry about optimisation". And due to this stupid mantra, people feel that is right not go to deep understanding.

There is a reasonable answer to that question, and maybe one can even give a better answer about the internals. Once learned, a good programmer will be able to repeat that pattern instinctively, and will become a better programmer. Programmers must have critical thinking about their code and must try to understand, as much as possible, how machine will process it.

I'm not advocating here that we all need to optimize little things. Remember that I recommended to favor readability over micro-optimisations.

I just believe that repeating the mantra "don't worry about optimisation" don't make things better. It only make programers lazy. Programmers must be instigated to know how things work behind the scenes. This way people can pursue to write better code, and wisely choose when not to optimise.


问:
Almost every reported bug is a high-priority bug
I have noticed a pattern while working on several software projects: the big majority of the bugs reported had a high/very-high priority. I asked some colleagues about why this may be happening, and they mentioned that if a bug doesn't haven't that level of priority it is very rare that the Bug gets developer attention, which indeed makes sense.

So, I wanted to know if this problem is common or if I just had bad luck. I did a quick Google search, and I found that some teams implement Bug Reporting guidelines or have a separate "Bug Triage" team. If you have faced and solved this issue, what was the approach that worked for you?

This question is specifically about the "Priority Inflation" problem: If you face the scenario and what meassures result effective against this problem.

答:
Most has already been said, but I'd distill the "bug zoo" list down to something a bit less granular:

A:  The bug stops the user dead in her tracks, gives wrong output, generally renders the system/feature/function unusable. That's a "high priority" bug.

B:   Everything else.  These are "negotiable" bugs.

NEGOTIABLE bugs fall under a variety of concerns (which you'd put in your own particular order):

1:  Bugs that impact security;

2:  Bugs that impact usability (fitness for intended purpose);

3:  Bugs that impact aesthetics;

4:  Bugs that impact performance (a subset of usability perhaps?);

5:  Bugs that offend your sensibilities as a professional programmer;

6:  Bugs that diminish USER TRUST;

So that's the utopian world that none of us actually live in.  sigh  To complete my answer to the OP's stated question, across the entire software industry, it is utterly common for development efforts to be in a status where every single bug is a priority-one-super-banger-special.  And you know what they say about "special":  when everyone is special, nobody is special.


问:
Unit testing Eloquent outside of Laravel
How can I unit test my Eloquent models when I'm using the ORM outside of Laravel? What I'm hoping to do it run tests on each model but somehow mock the database connection/query/builder(?) object.

Below is something along the lines of what I'm trying to do:

```<code>$capsule = new Capsule;

$capsule->addConnection(array(
    'driver'    => 'mysql',
    'host'      => 'localhost',
    'database'  => 'mydb',
    'username'  => 'dbuser',
    'password'  => 'badpass',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => ''
));

$capsule->bootEloquent();
</code>```

Below is my model:

```<code><?php

use Illuminate\Database\Eloquent\Model as Eloquent;

class Users extends Eloquent
{
    public function myCustomFind($id)
    {
        // .. lots of various checks before find() ...

        return $this->find($id);
    }
}
</code>```

Then, in my unit tests I can do the following (not a working version, but I hope you can see what I'm hoping to do):

```<code>$mockSomething->expects($this->once)
    ->method('find')
    ->with(1);

$users = new Users();
$users->setSomething($mockSomething);

$user = $users->myCustomFind(1);
</code>```

...I just have no idea how to do this without full integration (data being written to the database). I just want to test my models, not the ORM, also so my tests are fast and only checking the correct params are passed to the query builder, and that my method handles the resulting data correctly. Will Eloquent allow this? I notice that Laravel has it's own TestCase class but from what I see this caters for all aspects of testing in Laravel (controllers, etc)

If Eloquent is not a good choice for unit testing outside of Laravel, are there any popular ORMs that can? I haven't spent much time with others like Doctrine or Propel to know what they are capable of in that respect. Would appreciate any recommendations.

答:
You probably want to test a class that is using an eloquent model rather than the model itself.

To create an in memory database for eloquent to query against in your test you want to do create a data base and then create your tables in it with some data to test against.

```<code>use MyNamespace\ClassToTest;
use MyNamespace\Models\MyModel;
use Illuminate\Database\Capsule\Manager as DB;

class ExampleTest extends PHPUnit_Framework_TestCase
{

    public function setUp()
    {
        $this->configureDatabase();
        $this->migrateIdentitiesTable();
    }
    protected function configureDatabase()
    {
        $db = new DB;
        $db->addConnection(array(
            'driver'    => 'sqlite',
            'database'  => ':memory:',
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ));
        $db->bootEloquent();
        $db->setAsGlobal();
    }

    public function migrateIdentitiesTable()
    {
        DB::schema()->create('my_table', function($table) {
            $table->increments('id');
            $table->integer('page_id');
            $table->timestamps();
        });
        MyModel::create(array('page_id' => 1));
        MyModel::create(array('page_id' => 2));

    }

    public function testExtract()
    {
        $extractor = new ClassToTest();
        $result = $extractor->someFunctionThatUsesAnEloquentModel(1);
        $expected = array(
            'id' => '1',
            'page_id' => '1'
        );
        $this->assertEquals($expected['page_id'], $result['page_id']);
    }

}
</code>```

Body:
You probably want to test a class that is using an eloquent model rather than the model itself.

To create an in memory database for eloquent to query against in your test you want to do create a data base and then create your tables in it with some data to test against.

use MyNamespace\ClassToTest;
use MyNamespace\Models\MyModel;
use Illuminate\Database\Capsule\Manager as DB;

class ExampleTest extends PHPUnit_Framework_TestCase
{

    public function setUp()
    {
        $this->configureDatabase();
        $this->migrateIdentitiesTable();
    }
    protected function configureDatabase()
    {
        $db = new DB;
        $db->addConnection(array(
            'driver'    => 'sqlite',
            'database'  => ':memory:',
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ));
        $db->bootEloquent();
        $db->setAsGlobal();
    }

    public function migrateIdentitiesTable()
    {
        DB::schema()->create('my_table', function($table) {
            $table->increments('id');
            $table->integer('page_id');
            $table->timestamps();
        });
        MyModel::create(array('page_id' => 1));
        MyModel::create(array('page_id' => 2));

    }

    public function testExtract()
    {
        $extractor = new ClassToTest();
        $result = $extractor->someFunctionThatUsesAnEloquentModel(1);
        $expected = array(
            'id' => '1',
            'page_id' => '1'
        );
        $this->assertEquals($expected['page_id'], $result['page_id']);
    }

}


答:
Basically this issue is rooted in the problem of decentralizing prioritization. There should always be an odd number of people with ability to prioritize a team's workload, and 3 is too many. So that 1 person is responsible for effectively -triage. And it should be a manager/analyst, in consultation with a dev lead/architect. And the process is quite simple, and can be applied to feature requests too. What's the cost of doing the development? What's the value of the expected result to the business. Output of that function is the priority assigned.

Of COURSE every user wants their issue fixed first. And as soon as you allow that, chaos. You have no valid prioritization. You need this done by a SINGLE person with authority (consulting with others where necessary), who has VISIBILITY across ALL the issues and business needs, and competent enough to gather the required business and IT expert advice and thereby generate reasonably accurate estimates of the metrics above.

Title: Almost every reported bug is a high-priority bug

Body:
I have noticed a pattern while working on several software projects: the big majority of the bugs reported had a high/very-high priority. I asked some colleagues about why this may be happening, and they mentioned that if a bug doesn't haven't that level of priority it is very rare that the Bug gets developer attention, which indeed makes sense.

So, I wanted to know if this problem is common or if I just had bad luck. I did a quick Google search, and I found that some teams implement Bug Reporting guidelines or have a separate "Bug Triage" team. If you have faced and solved this issue, what was the approach that worked for you?

This question is specifically about the "Priority Inflation" problem: If you face the scenario and what meassures result effective against this problem.


问:
Why exactly can't PHP have full unicode support?
Everybody knows, that PHP has problems with Unicode. Version 6 is effectively abandoned, because of Unicode implementation difficulties. But I wonder if anyone knows what are the exact reasons? Architecture/design problems, performance concerns, community problems (I bet not), something other?

答:
PHP as a language definitely can have it, but I think the problem is with compatibility with existing programs. Unicode support can break them in subtle ways, which is the most annoying kind of bug to have.

Currently most string-processing functions in PHP are "binary-safe", which means you can use them to process any file in any encoding as well as binary formats like image data, etc.

With addition of Unicode strings you'd have to be very careful not to mix Unicode strings with binary strings (pretty hard when your strings come from different sources and you never had to worry about it before). And you couldn't be ignorant about encodings any more (and lots of scripts are ignorant about this!)

Another hard, but solvable problem is random access in Unicode strings. Implementation of $string[$offset] changes from trivial to either very slow or little slow and very complex.

Also I think it was a mistake to choose UTF-16 as internal encoding for PHP. It has same problems as UTF-8 (variable width because of surrogate pairs) and inefficiency of UCS-2. Maybe they should scrap that and start again with UTF-8?

</speculation>


问:
How to model heuristic uncertainty when sorting data?
Sorting algorithms assume you have a defined comparator. For example, if sorting integers A and B, the A > B operation allows you to determine if A should be after or before B.

Imagine you want to implement a sort, but rather than a defined and consistent comparator, the comparison uses a heuristic of some sense - so it's not a guarantee it will be correct. An example might be analogous to how eye doctors identify your prescription. They show two prescriptions and ask which is better. In some cases, as a patient you might not answer correctly for two close values. For values that are far apart, you will be more accurate.

If for example, you want to compare numeric values, you might model this as a custom comparator like:

```<code>public class HeuristicComparator implements Comparator {

    @Override
    public int compare(double val1, double val2) {
        double adjustedVal1 = val1 + Math.random();
        double adjustedVal2 = val2 + Math.random();

        return Double.compare(adjustedVal1, adjustedVal2);
    }

}
</code>```

In this basic example, I arbitrarily assigning some random variation to the comparison operation, effectively saying that any double values less than 1.000 apart might be sorted incorrectly. 1.5 might be less than 1.3, but only some of the time.

What other strategies are there for modeling heuristic behavior like this rather than a comparator? It seems you could modify the sort logic too (perhaps skip random points, modify a sort to not "finish" all adjacent sorts)?   What sorting algorithms that can be easily modified to match this behavior?

Or would it always be preferable to modify the comparator?

答:
For your example, you could view each item in the array as an interval from the minimum possible value to the maximum possible value.  Then you could randomly pick an interval, iterative reduce it to the intersection of what's left of it and any of the original intervals it still intersects, then quick sort using that interval as the pivot and considering intersection to be equality. (Effectively you are using quick-sort, slightly modified because you need to reduce the interval via intersection to ensure correctness).  </p>

<p>In the general case, you would need to specify what you want and how the heuristic works.  Are you interested in fault tolerance for a not always accurate non-deterministic heuristic (if so, fault tolerant sorting networks might be relevant)?   If you want fault tolerance for a faulty deterministic heuristic there really is nothing to be done.  Are there varying degrees of success in the sort that you want to trade of for time?  The general case of your question is too broad to answer.  </p>

Body:
For your example, you could view each item in the array as an interval from the minimum possible value to the maximum possible value.  Then you could randomly pick an interval, iterative reduce it to the intersection of what's left of it and any of the original intervals it still intersects, then quick sort using that interval as the pivot and considering intersection to be equality. (Effectively you are using quick-sort, slightly modified because you need to reduce the interval via intersection to ensure correctness).

In the general case, you would need to specify what you want and how the heuristic works.  Are you interested in fault tolerance for a not always accurate non-deterministic heuristic (if so, fault tolerant sorting networks might be relevant)?   If you want fault tolerance for a faulty deterministic heuristic there really is nothing to be done.  Are there varying degrees of success in the sort that you want to trade of for time?  The general case of your question is too broad to answer.


问:
eradicating the array = loop mindset
I have noticed a common issue in code reviews, that takes this form:

```<code>// "arr" is an array
for (i = 0; i < arr.length; ++i) {
    if (i == 3) {
        // do something with arr[i]
    }
    if (i == 8) {
        // do something else with arr[i]
    }
}
</code>```

I call this the "array = loop" mindset.  Somehow they have in their heads that if you want to work with an array, you have to use a loop.  I'm wondering what the root of this mindset is... does it have to do with education? What concept are they missing? How can this be untaught?

答:
Your question title and the code in the question don't match.

The answer to your question in the title is: how else would you find a value? Unless you have some extra knowledge about the structure of the array, iterating it is the only way to find a value. If you do know something extra, e.g. that the array is sorted, then you can do something more efficient, e.g. binary search. But in the worst-case, you need to iterate over the entire array, in the average case, over half the array.

Now, about the code you posted: this code isn't trying to find a value. It's not trying to find anything, really. It already knows the indices it wants to work on, there is no need at all to iterate.

Sometimes, there are legitimate reasons to do extra work, though. For example, in security-sensitive applications, the time it takes to do some work may leak information about the data. (This is called a timing attack, which is a special case of the more general class of side-channel attacks.) For example, a string comparison will usually abort and return false as soon as it finds the first difference between strings. However, this means that an attacker can, e.g. determine how many characters at the beginning of the password he guessed correctly, thus reducing the complexity of brute-forcing the password from  **  (i.e. exponential complexity) to  *  (i.e. polynomial complexity).

So, this would be an example, where you always need to loop through the entire array and cannot abort early, because you need to spend the same time regardless of where the difference occurs.

This doesn't appear to be the case here, though.

Title: eradicating the array = loop mindset


答:
There have been a few changes and updates, so I'm going with rev4 of your question.

The main argument for this practice is that -Os binary size correlates
  with code complexity.

You're asking size-optimized binary size to act as a proxy for code complexity; from version to version that number can go up or down. If you said that observed "up" measurements generally correlate to increases in code complexity I'd say that's ... reasonable.

But that alone is hardly actionable.

You haven't said why your bosses are asking you to do it, or how they use the information. If they are rejecting a change solely because the -Os version of the binary went up 3K, that sounds mighty foolish. If they are just interested in seeing/charting/graphing changes to the code over time, that sounds okay, especially because it should/could/might be easy to compute this number during an automated build process. If nothing else, metrics can start conversations and/or act as sanity checks.

Scenario 1

Boss: I see the size is down, how'd that happen?

Coder: Marketing finally gave us permission to completely remove that set of deprecated features.

Boss: Oh, nice.

Scenario 2

Boss: A 30% increase in size? I thought the new feature involved a minor tweak!

Coder: That's what we thought too, but once we understood what the client was asking for, we had to blah blah blah....

Final note, in case someone thinks otherwise, I'll state explicitly: complexity != maintainability != quality

Title: Is measuring the binary size of a c++ program a good indication of code complexity? Or something else?

Body:
In my company we have this obligatory practice before a review to be send the binary size impact of the code change to be measured and provided.

We must use -Os for this metric to avoid unpredictable inlining. There is no customer or product driven arguments for it. It is a big server that is installed as singleton of a dedicated machine, where the executable size is completely ignorable in comparison to all the other resources involved in the system.

The main argument for this practice is that -Os binary size correlates with code complexity.

Is measuring the binary size a reliable metric to use when evaluating code complexity? Or for evaluating anything else?


答:
You can't just have a priority and expect everything to magically work out. Sometimes people figure it out on their own, but not always.

To correctly assign priorities, there must be a definition of exactly what constitutes each priority. These criteria must be objective, to avoid bug favoritism and political prioritization. If the objective criteria are not followed, you need to make the team follow it.

There's really no way around this - if you can't have objective criteria for what bug goes where, and if people willfully refuse to honor these criteria, then you might as well not have submitter-assigned priorities - either do without priorities, or have a third party assign priority as others suggested. Crowdsourced data only works if the submitters are cooperative, and don't actively sabotage the data collection.

If the difficulty arises from not being able to create objective criteria, you can use relative criteria:

Have a simple queue of all bugs. Users are able to insert bugs anywhere in the queue. They should only insert at a given position if they feel their bug is more important than everything below it. Bug fixers start from the top of the queue.

Assuming you already have a set of well-classified bugs, tell everyone that the condition for putting a bug in priority X is that it must be more important than all bugs in priority X-1.

Tell submitters that at no time can the number of bugs with priority X exceed the number of bugs with priority X-1.

But it sounds like your problem is not the definition, but the belief amongst submitters that low-priority bugs do not get fixed. Presumably, you cannot persuade them otherwise, since (from what you say) their belief is grounded in fact. Then, why do you make them submit these bugs? It ends up being nothing but busywork. You could, for instance, after a certain number of active bugs has been reached, tell everyone to not bother making reports unless they feel they found something more important than most outstanding bugs. Granted, this is just the queue solution with an upper limit on queue length.


问:
Load testing HTTP server with large number of concurrent connections
I'm trying to load test/benchmark a http server with a very large number of simultaneous connections (10-100k). What is a good procedure for doing this? On linux I've seen that both the client and host likely need to have the number of permitted threads to be explicitly increased.

Also, does anyone have a good feel for how many client machines are needed for testing 10k and up connections? Is one machine enough, or does there tend to be a cap on the number of sockets a machine can handle?

I'm currently using nperf to generate loads. I've been successful up to around 1-2k concurrent requests, after which some of the requests come back failed. I'm not sure if the failures are of the server, or the client and I'm reluctant (lazy) to provision more machines for use as clients if the issue can be resolved with the one I have.

答:
Without any more details about your set-up, I'm tempted to say that you need to try it out.

The best way to benchmark your load generators is to try an easy load on a very light test page on your server (something that is going to cause the least amount of load on the http server). This will test your set-up's ability to generate the load so you can decide how many generators you need. You'll need to monitor your generators particularly for CPU, network, and the timeliness of each request (i.e. are they all sent out to schedule or do they build-up and lag behind?). Check the error logs on your generators, check for dropped requests.

Then you can move on to your real test. Now for the real test you may need to adjust your load generators set-up, depending on how complex your test case is, but the benchmark above will give you a good starting point.


问:
Parsing conditional statements
I've written a small utility in Python3 to help me copy my music collection from my NAS to a mobile device. The usefulness of this is that it will auto-convert flac files to ogg-vorbis (to save space) and also exclude some files based on their audio tags (i.e. artist, album, date, etc).

I'm not happy with the limited nature of the exclude feature and I want to improve it but I've hit a mental block and I'm looking for advice on how to proceed.

I would like the user to write an exclude file which will look something like this:

```<code>exclude {
    artist is "U2"

    artist is "Uriah Heep" {
        album is "Spellbinder"
        album is "Innocent Victim"
    }
}
</code>```

This would translate to:

```<code>exclude if
(artist = "U2") OR
(artist = "Uriah Heep" AND (album = "Spellbinder" OR album = "Innocent Victim"))
</code>```

There will be more conditionals such as sub-string matching and date ranges.

I've been checking out PLY but I'm struggling with the concepts of how to parse this type of nested structure and also how to represent the resulting conditional so that I can execute it in code when applying the exclude filter during the copy operation.

答:
Language agnostic answer (I don't know python):

Since your structure is a tree, you need to store it as a tree.
You need to know whether your tree is going to be only two levels or more, this may affect the way to handle it (recursively or brute force).

If you don't need to optimise for speed you can start with a naive algorithm.

Match your tree with a handling algorithm.

Start from the top level.

1/ Loop for each branch until you find a match (exclusion), if there is no match return to caller with no exclusion.

2/ If the node has no branch at the next level return to caller with an exclusion.

3/ If the node has branches or leaves at the next level, go down one level and start from action 1.

HTH

Title: Parsing conditional statements


问:
Functional Programming - Does Knowing It Help Job Prospects?
The main language that I use at the moment is C# and I am the most comfortable with it. However, I have started dabbling in F# and Haskell and really enjoy those langauges. I would love to improve my skills in either of those languages over time since it truly is fun for me to use them (as opposed to Ruby, which is hyped as "fun", I just don't get where the fun is, but I digress...). My question is directed at those who have hired/interviewed for programming positions (junior/mid-level): if you see a functional programming language on a resume, does it affect your opinion (whether positive or negatively) of that candidate?

My rationale for knowledge of functional programming affecting the view of a candidate is because it can show that the candidate can adapt to different methodologies and take a mulit-dimensional approach to problems rather than the "same old OO approach". (This may be off-base, please let me know if this assumption is as well!)

答: Absolutely. Industry are now crying out for F# programmers and are willing to pay top-dollar. Note that this is no different from other upcoming technologies like LINQ, TPL, Silverlight etc.</p>


问:
Do I need a parent class if I'm using an interface?
I'm starting work a new personal project to send out emails using different email services (like mailchimp, for example). I just started coding and I have a base class called Email:

```<code>public class Email
{
    private string _to;
    private string _from;
    private string _body;
    private string _templateName;

    public Email(string to, string from, string body, string templateName)
    {
        this._to = to;
        this._from = from;
        this._body = body;
        this._templateName = templateName;
    }
}
</code>```

an interface called IEmail:

```<code>public interface IEmail
{
    string Send();
}
</code>```

and a class called MailChimpEmail that will send out emails using MailChimps API and that inherits from Email and implements the IEmail interface

```<code>public class MailChimpEmail : Email, IEmail
{
    private string _body;
    private string _to;
    private string _from;
    private string _templateName;

    public MailChimpEmail (string to, string from, string body, string templateName) : base(to, from, body, templateName)
    {
        this._to = to;
        this._from = from;
        this._body = body;
        this._templateName = templateName;
    }

    public string Send()
    {
        throw new NotImplementedException();
    }
}
</code>```

I plan on being able to use another 3rd party email sender so I'm not tied to one and will create a new class and implement the IEmail interface and inherit Email. But, my question is: do I really need to inherit Email? Say the classes don't gain any new functionality and stay as such (so I can just Send an email, that's it), what am I gaining by inheriting the base class if I'm implementing the interface? The Send method will have a different implementation for each class, so what would the point be?

答: You are correct, you are not gaining anything by inheriting Email. In fact, the class Email right now is completely useless. Using only the interface is just fine. Optionally, you could use an abstract class instead of an interface but either will do.


答:
The binary size is the most fundamental metric of any build because it will hit the bottom line of the deliverable, for better or worse.

For large programs, as a general rule, binary size will reflect complexity. This seems counter intuitive because redundant or duplicated code would seem to be a path to greater size. In practice, however, for non-trivial programs redundant code tends to be hard to maintain so it is self limiting. In other words, the larger a program gets, the more essential it becomes to abstract it to support further growth. For this reason, binary size tends to approximate complexity.

Note that it is only a very rough metric, however. In some cases you can find bloatware by large organizations, like IBM, where they have succeeded in creating large binaries using very large teams of developers which are somewhat redundant. However, even in these case the law of maintainability applies and even IBM is not immune to it; eventually even the most massive manhour efforts will succumb to inertia if they are not abstracted.

Thus, as rule, especially for a given corporate context binary size will provide a very rough generalization of complexity.


答:
We should inherit if there is a 'is a relation'. We should use aggregation if there is a 'has a relation'.

There is no need to inherit 'Email' class in every email sending implementation classes. Your 'Email' class is a model class. Email sending logic implementation classes should only implement the 'IEmail' interface and use 'Email' type private variable inside them.

```<code>public class Email
{
    private string _to;
    private string _from;
    private string _body;
    private string _templateName;

    public Email(string to, string from, string body, string templateName)
    {
        this._to = to;
        this._from = from;
        this._body = body;
        this._templateName = templateName;
    }
}

public interface IEmail
{
    string Send();
}

public class MailChimpEmail : IEmail
{
    private Email _email;

    public MailChimpEmail(Email email)
    {
        this._email = email;
    }

    public string Send()
    {
        // implementation goes here...
    }
}

public class ThirdPartyEmail : IEmail
{
    private Email _email;

    public ThirdPartyEmail(Email email)
    {
        this._email = email;
    }

    public string Send()
    {
        // Third party implementation goes here...
    }
}
</code>```

'MailChimpEmail' and 'ThirdPartyEmail' implement 'IEmail' interface and give its own logic to the 'send()' method.  'MailChimpEmail' and 'ThirdPartyEmail' is in 'has a relation' with 'Email' class, so it should not inherit rather it should use 'Email' type variable inside them to work with (this is called aggregation).

Title: Do I need a parent class if I'm using an interface?

Body:
I'm starting work a new personal project to send out emails using different email services (like mailchimp, for example). I just started coding and I have a base class called Email:

```<code>public class Email
{
    private string _to;
    private string _from;
    private string _body;
    private string _templateName;

    public Email(string to, string from, string body, string templateName)
    {
        this._to = to;
        this._from = from;
        this._body = body;
        this._templateName = templateName;
    }
}
</code>```

an interface called IEmail:

```<code>public interface IEmail
{
    string Send();
}
</code>```

and a class called MailChimpEmail that will send out emails using MailChimps API and that inherits from Email and implements the IEmail interface

```<code>public class MailChimpEmail : Email, IEmail
{
    private string _body;
    private string _to;
    private string _from;
    private string _templateName;

    public MailChimpEmail (string to, string from, string body, string templateName) : base(to, from, body, templateName)
    {
        this._to = to;
        this._from = from;
        this._body = body;
        this._templateName = templateName;
    }

    public string Send()
    {
        throw new NotImplementedException();
    }
}
</code>```

I plan on being able to use another 3rd party email sender so I'm not tied to one and will create a new class and implement the IEmail interface and inherit Email. But, my question is: do I really need to inherit Email? Say the classes don't gain any new functionality and stay as such (so I can just Send an email, that's it), what am I gaining by inheriting the base class if I'm implementing the interface? The Send method will have a different implementation for each class, so what would the point be?

Body:
We should inherit if there is a 'is a relation'. We should use aggregation if there is a 'has a relation'.

There is no need to inherit 'Email' class in every email sending implementation classes. Your 'Email' class is a model class. Email sending logic implementation classes should only implement the 'IEmail' interface and use 'Email' type private variable inside them.

public class Email
{
    private string _to;
    private string _from;
    private string _body;
    private string _templateName;

    public Email(string to, string from, string body, string templateName)
    {
        this._to = to;
        this._from = from;
        this._body = body;
        this._templateName = templateName;
    }
}

public interface IEmail
{
    string Send();
}

public class MailChimpEmail : IEmail
{
    private Email _email;

    public MailChimpEmail(Email email)
    {
        this._email = email;
    }

    public string Send()
    {
        // implementation goes here...
    }
}

public class ThirdPartyEmail : IEmail
{
    private Email _email;

    public ThirdPartyEmail(Email email)
    {
        this._email = email;
    }

    public string Send()
    {
        // Third party implementation goes here...
    }
}

'MailChimpEmail' and 'ThirdPartyEmail' implement 'IEmail' interface and give its own logic to the 'send()' method.  'MailChimpEmail' and 'ThirdPartyEmail' is in 'has a relation' with 'Email' class, so it should not inherit rather it should use 'Email' type variable inside them to work with (this is called aggregation).


答:
It is quite possible that all the bugs mentioned are high priority.  I've been on projects that were both underfunded and underspecified, and when testing began QA and users just gave up reporting low priority items, because they knew that spelling errors or glitches in usability were a waste of time if the core functionality of the project was completely hosed.  If your automated baggage system is crashing carts together and destroying luggage, who cares if the font on the tags is 2pt too small?

In a situation like this, the project is failing.  If you suspect that this is even a possibility, you need a heart to heart with the people reporting defects to find out. If people are inflating bug reports, then the other answers will help. If the bugs are as bad as reported, then you need to take extreme action.


问:
Why Garbage Collection if smart pointers are there
These days, so many languages are garbage collected. It is even available for C++ by third parties. But C++ has RAII and smart pointers. So what's the point of using garbage collection? Is it doing something extra?

And in other languages like C#, if all the references are treated as smart pointers(keeping RAII aside), by specification and by implementation, will there still be any need of garbage collectors? If no, then why is this not so?

答:
It's about performance. Unallocating memory requires lot of administration. If the unallocation runs in the background, the performance of foreground process increases. Unfortunatelly, memory allocation can't be lazy (the objects allocated will be used at the holy next moment), but releasing objects can.

Try in C++ (w/o any GC) to allocate a big bunch of objects, print "hello", then delete them. You'll be surprised how long does it take to free objects.

Also, GNU libc provides more effective tools for unallocating memory, see obstacks. Must notice, I have no experience with obstacks, I never used them.


答:
An interface and a parent (or base) class solve different problems, so it depends on the problem you're trying to solve.

An interface defines a contract. This is handy when you want to manipulate a variety of concrete implementations in a consistent, well-defined manner. They're great for hiding the gory details that probably don't matter in the consumer. They're also good at forcing us to think about useful abstractions.

A base class also offers a contract of sorts (any number of extended classes can be handled as if they are the base class), but its most useful feature is its shared, concrete implementation. If you have implementation that's identical in a family of related classes, you can DRY up your code with a base class.

At first glance, it looks like your example only requires the interface. There's no obvious shared implementation. Looking closer, though, I wonder. Both Email and MailChimpEmail define a body, addresses, and a template. It might be worth defining those once and only once, especially if there's any tricky state management. If each email type must define its own Send(), an abstract base class might better convey the intent (the base class isn't instantiate-able). You get a little contract and a little concrete implementation.

```<code>public abstract class BaseEmail
{
    public string Body { get; set; }
    public string From { get; set; }
    public string To { get; set; }
    public string Template {get; set; }

    protected BaseEmail (string body, string from, string to, string template)
    {
        this.Body = body;
        this.From = from;
        this.To = to;
        this.Template = template;
    }

    public abstract string Send();
}

public class VanillaEmail : BaseEmail
{
    public VanillaEmail (string body, string from, string to, string template)
        : base (body, from, to, template)
    {
    }

    public override string Send()
    {
        // do some vanilla work
    }
}

public class MailChimpEmail : BaseEmail
{
    public MailChimpEmail (string body, string from, string to, string template)
        : base (body, from, to, template)
    {
    }

    public override string Send()
    {
        // do some mailchimp work
    }
}
</code>```

Keep in mind that this is only one way to model the problem. Some would argue that an email shouldn't be able to send itself. In this case, you can separate the concern of sending an email message from the message itself.

```<code>public class Email
{
    public string Body { get; set; }
    public string From { get; set; }
    public string To { get; set; }
    public string Template {get; set; }
}

public interface IMailer
{
    string Send(Email email);
}

public class VanillaMailer : IMailer
{
    public string Send(Email email)
    {
        // do some vanilla work
    }
}

public class MailChimpMailer : IMailer
{
    public string Send(Email email)
    {
        // do some mailchimp work
    }
}
</code>```

Body:
An interface and a parent (or base) class solve different problems, so it depends on the problem you're trying to solve.

An interface defines a contract. This is handy when you want to manipulate a variety of concrete implementations in a consistent, well-defined manner. They're great for hiding the gory details that probably don't matter in the consumer. They're also good at forcing us to think about useful abstractions.

A base class also offers a contract of sorts (any number of extended classes can be handled as if they are the base class), but its most useful feature is its shared, concrete implementation. If you have implementation that's identical in a family of related classes, you can DRY up your code with a base class.

At first glance, it looks like your example only requires the interface. There's no obvious shared implementation. Looking closer, though, I wonder. Both Email and MailChimpEmail define a body, addresses, and a template. It might be worth defining those once and only once, especially if there's any tricky state management. If each email type must define its own Send(), an abstract base class might better convey the intent (the base class isn't instantiate-able). You get a little contract and a little concrete implementation.

public abstract class BaseEmail
{
    public string Body { get; set; }
    public string From { get; set; }
    public string To { get; set; }
    public string Template {get; set; }

    protected BaseEmail (string body, string from, string to, string template)
    {
        this.Body = body;
        this.From = from;
        this.To = to;
        this.Template = template;
    }

    public abstract string Send();
}

public class VanillaEmail : BaseEmail
{
    public VanillaEmail (string body, string from, string to, string template)
        : base (body, from, to, template)
    {
    }

    public override string Send()
    {
        // do some vanilla work
    }
}

public class MailChimpEmail : BaseEmail
{
    public MailChimpEmail (string body, string from, string to, string template)
        : base (body, from, to, template)
    {
    }

    public override string Send()
    {
        // do some mailchimp work
    }
}

Keep in mind that this is only one way to model the problem. Some would argue that an email shouldn't be able to send itself. In this case, you can separate the concern of sending an email message from the message itself.

public class Email
{
    public string Body { get; set; }
    public string From { get; set; }
    public string To { get; set; }
    public string Template {get; set; }
}

public interface IMailer
{
    string Send(Email email);
}

public class VanillaMailer : IMailer
{
    public string Send(Email email)
    {
        // do some vanilla work
    }
}

public class MailChimpMailer : IMailer
{
    public string Send(Email email)
    {
        // do some mailchimp work
    }
}


问:
Why do we need a context class in strategy pattern?
For the strategy pattern, why do we need a context class to call the appropriate algorithm? Why can't we just do Strategy s = new OperationAdd()? This way, we still use polymorphism.

答:
In some languages, notably C# and Java, you can strategize, not the sorting algorithm, but the way the objects being sorted are compared for ordering purposes.

For example, in C#, you could say something like

```<code>var sort = new MergeSort(new ImaginaryNumberComparator());
</code>```

and the MergeSort will treat the objects being sorted like imaginary numbers for ordering purposes.

Changing the sorting algorithm, however, requires knowledge of the entire collection, not just two of its members.

Body:
In some languages, notably C# and Java, you can strategize, not the sorting algorithm, but the way the objects being sorted are compared for ordering purposes.

For example, in C#, you could say something like

var sort = new MergeSort(new ImaginaryNumberComparator());

and the MergeSort will treat the objects being sorted like imaginary numbers for ordering purposes.

Changing the sorting algorithm, however, requires knowledge of the entire collection, not just two of its members.


答:
UML class diagram at wikipedia article shows Context to include strategy by composition. So, the class, you use Strategy inside, IS a context.

```<code>class MyClass() {
  public function sort() {
    SortStrategy s=new MergeSort();
  }
}
</code>```

Here MyClass is a context for the strategy.

Title: Why do we need a context class in strategy pattern?

Body: For the strategy pattern, why do we need a context class to call the appropriate algorithm? Why can't we just do Strategy s = new OperationAdd()? This way, we still use polymorphism.

Body:
UML class diagram at wikipedia article shows Context to include strategy by composition. So, the class, you use Strategy inside, IS a context.

class MyClass() {
  public function sort() {
    SortStrategy s=new MergeSort();
  }
}

Here MyClass is a context for the strategy.


问:
Design patter for a dynamic filter builder
Say that I have an abstract base class Shape and its derived classes Triangle, Square, etc.

Currently I have the following (simplified) structure to fetch a list of Shapes and filter them (mostly using Fluent):

public abstract class BaseSearch<T> where T : Shape
{
    protected readonly IRepository<T> repository;

    public IQueryable<T> Search(Filter filter)
    {
        var shapes = repository.GetAll();
        // applies the common filtering to shapes

        return CustomSearch(filter, shapes);
    }

    public abstract IQueryable<T> CustomSearch(Filter filter, IQueryable<T> shapes);
}

public class TriangleSearch : BaseSearch<Triangle>
{
    public IQueryable<Triangle> CustomSearch(Filter filter, IQueryable<Triangle> shapes)
    {
        var filteredTriangles = shapes;
        // applies filters specific to Triangles
        return filteredTriangles;
    }
}
```

<p>The same goes for the rest of the derived class. They just need to implement the <code>CustomSearch</code> method.</p>

<p>The problem is that now different places require different filters, with different conditions, properties, etc. Augmenting the <code>Filter</code> class to handle those extra requirements would make it too cubersome.</p>

<p>To solve this problem, I though about having many filter classes, each of them would apply its simple filter algorithm to a list of <code>Square</code>s. Then, using composition I could nest them all and have the whole filter I need.</p>

<p>The problem with this approach is that some properties lie in different places on each entity. For example, to filter by height, I need to compare the <code>MiddleHeight</code> property from <code>Triangle</code> and the <code>Height</code> property from <code>Square</code>. Also, neither of those properties are present in the <code>Square</code> class.</p>

<p>I also thought about using the Predicate Builder approach, but I would fall into the same problem.</p>

<p>What could be used to implement a more general or dynamic filter that could be used to filter instances of classes derived from <code>Shape</code> and still return an <code>IQueryable</code> of shapes?</p>

<p><strong>Edit:</strong> explaining further the filter class and how its used.
</p>

```public class Filter {
    public string Color { get; set; }
}

public class AnotherFilter {
    public Filter MainFilter { get; set; }
    public long? Height { get; set; }
}
```

The main search uses the Filter class. It checks if the Color property is set and if so, applies a condition to the collection of shapes. This condition is not always a simple "where the color of the shape matches the color set in the filter"; sometimes the property requires a more complex check (e.g. "where the color of the shape matches that of the filter and the shape has the opacity set to 0%").

The AnotherFilter class represents a different filter. Currently it has a Filter property which is used to call the main Search and fetch some results. Then, using the properties of AnotherFilter, the collection is filtered further. There is also a problem here mentioned before: the Height property is to be used to filter data by height. But Height is not a property of Shape, only of, say, Triangle and Square (a Circle, which also inherits from Shape, doesn't have a height).

The search fetches data from a remote database and uses NHibernate.

答:
Use Dynamic Linq.

Dynamic linq will allow you to write "stringly-typed" queries with conditional statements that can be created and resolved at run time, rather than at compile time.

Further Reading

Getting Started with Dynamic Linq


问:
Single Class to Serve as View Model as well as Container for Submitted Form
I see the following design in the code which is part of the default web application project in visual studio:

A single data model class in constructed and decorated with various data validation annotations. For Example, there's a RegisterViewModel class that looks like this:

```<code>public class RegisterViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 8)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}
</code>```

This class then serves two purposes:

It is the 'view model' or the type for the view which consists of the html form with which the user registers. The html details as well as the jquery validation metadata can be automatically extracted from the class's data annotations.

When the user posts his/her form back to the server, the form data is stored in an object of the same type; e.g. in this case the Register action signature looks like this:

public async Task<ActionResult> Register(RegisterViewModel model)

Among other things, this allows for server-side validation to happen using the same data annotations.

Is this a common, acceptable pattern? Is it a design to strive for when building my own forms?

答: Well, I don't see anything unusual here. ViewModel validation is a common thing. Although I would say, that domain entity should also be validated. Here is a good article on the subject.


问:
Is client-side validation really all that important, always?
Through the years I've worked in web development it's been ingrained in me that client-side validation is absolutely and completely necessary in all web applications. Seems to me like all the people in the profession are very adamant on using it every single time. The most commonly mentioned benefits are:

Instantaneous showing of form errors

Less unnecessary requests to the server

But as we're moving towards the modern web, more and more applications are AJAX based. The simple task of submitting forms takes a lot less time now than it did before and validating on the server and returning errors barely impacts the user experience.

Could it be justifiable to completely avoid client-side validation (for example) on an application that only contains small and simple forms?

EDIT: I would argue that the linked duplicate question doesn't really capture the same example I'm giving here. A lot has changed since 2011. All of the answers on the related question are arguing for user experience whereas in my question I'm describing a scenario where the user experience would be unaffected.

When client-side validation no longer improves the user experience does it continue to rank in the same level of importance as before?

答:
Server side validation is absolutely necessary. Client side validation is purely a user experience improvement since the same validation should always happen on the server anyway. After all, you can always disable JavaScript or simply post arbitrary data directly via HTTP.

If you can provide server side validation which gives just as smooth a user experience as client side validation, you don't need client side validation.