问:
Should all functions be fully self-contained (is it bad practice to share a variable between functions)?
There are two ways to do the same thing (pseudo code)

Define databaseHandle in the parent function, and use it as a global in this scope:

```<code>function API() {

  function openDatabase() {
      return databaseHandle;
  }
  databaseHandle = openDatabase()

  function getItem(i) {
      databaseHandle.get(i)
  }

  function addItem(name) {
      databaseHandle.add(name)
  }

}
</code>```

Define a function for getting this handle, and then get it when we need it:

```<code>function API() {

  function openDatabase() {
      return databaseHandle;
  }

  function getItem(i) {
      databaseHandle = openDatabase()
      databaseHandle.get(i)
  }

  function addItem(name) {
      databaseHandle = openDatabase()
      databaseHandle.add(name)
  }

}
</code>```

The first option seems simpler, and I see it in many examples. But the second one seems to me more reliable and obvious in what it does (and a bit redundant).

What is the best practice here? If there's another, better way, I'd like to hear about it. Thanks.

答:
I'd go with the second approach, with a change which releases the handle when done. If each method takes care of getting, operating and releasing its own handle, then your application should be better suited to scale up (assuming you have some sort of pooling underneath).

With the first approach, it is hard to say what will happen should two different threads call each method separately at the same time.


问:
Java: why do collections accept a Comparator but not (a hypothetical) Hasher and Equator?
This issue is most apparent when you have different implementations of an interface, and for the purposes of a particular collection you only care about the interface-level view of the objects. For example, suppose you had an interface like this:

```<code>public interface Person {
    int getId();
}
</code>```

The usual way to implement hashcode() and equals() in implementing classes would have code like this in the equals method:

```<code>if (getClass() != other.getClass()) {
    return false;
}
</code>```

This causes problems when you mix implementations of Person in a HashMap. If the HashMap only cares about the interface-level view of Person, then it could end up with duplicates that differ only in their implementing classes.

You could make this case work by using the same liberal equals() method for all the implementations, but then you run the risk of equals() doing the wrong thing in a different context (such as comparing two Persons that are backed by database records with version numbers).

My intuition tells me that equality should be defined per collection instead of per class. When using collections that rely on ordering, you can use a custom Comparator to pick the right ordering in each context. There is no analogue for hash-based collections. Why is this?

Just to clarify, this question is distinct from "Why is .compareTo() in an interface while .equals() is in a class in Java?" because it deals with the implementation of collections. compareTo() and equals()/hashcode() both suffer from the problem of universality when using collections: you can't pick different comparison functions for different collections. So for the purposes of this question, the inheritance hierarchy of an object doesn't matter at all; all that matters is whether the comparison function is defined per-object or per-collection.

答:
The real answer to

why is there a Comparator interface but no Hasher and Equator?

is, quote courtesy of Josh Bloch:

The original Java APIs were done very quickly under a tight deadline to meet a closing market window. The original Java team did an incredible job, but not all of the APIs are perfect.

The problem lies solely in Java's history, as with other similar matters, e.g. .clone() vs Cloneable.

tl;dr

it's for historical reasons mainly; current behaviour/abstraction was introduced in JDK 1.0 and wasn't fixed later on because it was virtually impossible to do so with maintaining backward code compatibility.

First, let's sum up a couple of well-known Java facts:

Java, from the very beginning to the present day, was proudly backwards-compatible, requiring legacy APIs to be still supported in newer versions,

as such, almost each and every language construct introduced with JDK 1.0 lived to present day,

Hashtable, .hashCode() & .equals() were implemented in JDK 1.0, (Hashtable)

Comparable/Comparator was introduced in JDK 1.2 (Comparable),

Now, it follows:

it was virtually impossible & senseless to retrofit .hashCode() & .equals() to distinct interfaces while still maintaining backwards compatibility after the people realized there are better abstractions than putting them in superobject, because e.g. each and every one Java programmer by 1.2 knew that every Object has them, and they had to stay there physically to provide compiled code (JVM) compatibility also - and adding an explicit interface to every Object subclass that really implemented them would make this mess equal (sic!) to Clonable one (Bloch discusses why Cloneable sucks, also discussed in e.g. EJ 2nd and many other places, including SO),

they just left them there for the future generation to have a constant source of WTFs.

Now, you may ask "what does Hashtable have with all this"?

The answer is: hashCode() / equals() contract and not-so-good language design skills of core Java developers in 1995/1996.

Quote from Java 1.0 Language Spec, dated 1996 - 4.3.2 The Class Object, p.41:

The methods equals and hashCode are declared for the benefit of hashtables
  such as java.util.Hashtable (§21.7). The method equals defines a notion
  of object equality, which is based on value, not reference, comparison.

(note this exact statement has been changed in later versions, to say, quote: The method hashCode is very useful, together with the method equals, in hashtables such as java.util.HashMap., making it impossible to make the direct Hashtable-hashCode-equals connection without reading historical JLS!)

Java team decided they wanted a good dictionary-style collection, and they created Hashtable (good idea so far), but they wanted the programmer to be able to use it with as little code/learning curve as possible (oops! trouble incoming!) - and, since there was no generics yet [it's JDK 1.0 after all], that would mean that either every Object put into Hashtable would have to explicitly implement some interface (and interfaces were still just in their inception back then... no Comparable yet even!), making this a deterrent to use it for many - or Object would have to implicitly implement some hashing method.

Obviously, they went with solution 2, for the reasons outlined above. Yup, now we know they were wrong. ... it's easy to be smart in hindsight. chuckle

Now, hashCode() requires that every object having it has to have a distinct equals() method - so it was quite obvious that equals() had to be put in Object as well.

Since the default implementations of those methods on valid a&b Objects are essentially useless by being redundant (making a.equals(b) equal to a==b and a.hashCode() == b.hashCode() roughly equal to a==b also, unless hashCode and/or equals is overriden, or you GC hundreds of thousands of Objects during the lifecycle of your application1), it's safe to say they were provided mainly as a backup measure and for usage convenience. This is exactly how we get to the well-known fact that always override both .equals() & .hashCode() if you intend on actually comparing the objects or hash-storing them. Overriding only one of them without the other is a good way to screw your code (by wicked compare results or insanely high bucket collision values) - and getting your head around it is a source of constant confusion & errors for beginners (search SO to see it for yourself) and constant nuisance to more seasoned ones.

Also, note that although C# deals with equals & hashcode in a bit better way, Eric Lippert himself states that they did almost the same mistake with C# that Sun did with Java years before C#'s inception:

But why should it be the case that every object should be able to hash itself for insertion into a hash table? Seems like an odd thing to require every object to be able to do. I think if we were redesigning the type system from scratch today, hashing might be done differently, perhaps with an IHashable interface. But when the CLR type system was designed there were no generic types and therefore a general-purpose hash table needed to be able to store any object.

1of course, Object#hashCode can still collide, but it takes a bit of effort to do that, see: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6809470 and linked bug reports for details; https://stackoverflow.com/questions/1381060/hashcode-uniqueness/1381114#1381114 covers this subject more in-depth.

ContentLicense: CC BY-SA 3.0


问:
Ternary operator considered harmful?
For example, would you prefer this one-liner

```<code>int median(int a, int b, int c) {
    return (a<b) ? (b<c) ? b : (a<c) ? c : a : (a<c) ? a : (b<c) ? c : b;
}
</code>```

or an if/else solution involving multiple return statements?

When is ?: appropriate, and when is it not? Should it be taught to or hidden from beginners?

答:
If ... then ... else tends to emphasize the condition and therfore de-emphasize the operations being conditionally done.

the ternary operator is the opposite, it tends to hide the condition and is therfore useful when the operation being done is more important than the condition itself.

There is the minor technical niggle, in some languages, that they aren't quite interchangeble due to one being a statement and one an expression e.g. conditionally initialising consts in C++

Title: Ternary operator considered harmful?

ContentLicense: CC BY-SA 2.5


问:
Virtualized Development Environments in Enterprise Networks
We are attempting to implement a development environment using virtualization for a small team of 4 developers within an enterprise organization.  This would allow us to set up separate development, testing, and staging environments - as well as allowing access to new operating systems that are requirements for systems or tools we are evaluating.   We re-purposed an existing workstation-class machine, threw in 24GB RAM and RAID-10, and were doing fine until we attempted to get the machine added to the domain.

Now we are beginning the war that all enterprise developers since the beginning of time have had to fight - the fight for local control of a development and testing environment.  The network and IT admins' have raised concerns ranging from "ESX Server is the enterprise standard" to "servers are not allowed on client VLANs" to "[fill-in-the-blank] is not a skill set currently possessed in the local or enterprise IT organization".

We could justify production-class hardware and formal IT support if we had to, but it would take time and involve a whole lot of headache.  Even then it might take months to formally get IT resources assigned by treating this as a production system - and even if we did, we would likely lose the local control we need.

I imagine that many of you have had similar struggles over developer control of non-production environments - and virtualization in particular - so my questions are as follows:

What strategies and arguments have helped you win over the infrastructure (IT & Network) folks to allow these types of silos to exist within enterprises which have standard network and security policies in place that would generally (and understandably) preclude this type of non-(centrally)-managed infrastructure?

Have you found this to be a matter of technical justification - or more of a political struggle for control and ownership?

If you ended up with a IT-managed development environment, how much of a roadblock has it been for day-to-day development and testing?

Has anyone ended up moving their development environment to a disconnected VLAN or entirely separate network to avoid these network access struggles?

Also, this is not a Hyper-V vs. ESX holy war (we would be fine with either - but Hyper-V was selected since it is "free" with MSDN for these purposes [yes, VMWare has free tools too - but the good management tools generally aren't], and would be easier to manage by the local developers in a "Microsoft Shop") - so arguments for or against either are outside the scope of this question.

This is also less of a virtualization vs. physical hardware - I suppose the same question could be asked without the virtualization component to the equation.

Also assume that the dev team has already made assurances to either manage patch management and antivirus, or integrate with the existing enterprise systems if they will support it.
This scenario, with different questions, is also posted on SF to hopefully elicit the opposing viewpoint.

答:
As much as I am an amateur in such situations as these, it seems that an appropriate and well constructed argument is required to justify to the heads of departments a need for the extra expense (and expanse) of the IT resources. You probably want a good speaker who is able to intermediate the issues and relate the potential value of the proposal to those who wind up paying for it.

The problem is actually one that deserves real consideration: One group want the Dev environment, but that puts some pressure on the other group who feel responsible, indeed are responsible for the security of the overall system, networking especially being something that IT depts are justifiably precious about.

It strikes me that the ability to off-site certain resources for a prospectively lucrative project or even just a free environment for developers has now been superceded by a market rationalisation for Virtualization as a cost cutting and resource control measure.

Now don't get me wrong, I'm not against virtualisation, far from it. But it occurs to me that there are often very good and explainable resons for permitting a development group to be entitled to a seperate realm which would be more productive an environment, and potentially safer than merely virtualizing everything.

Sure a business can save money by using the cloud for regular inter-office departental stuff, it's very useful there. (it's a form of virtualisation, but different, I know)

But suppose a developer raises an unidentifiable error that can't be debugged because there is a question about whether the application/program has broken due to an implementation of virtualisation (ie that it wouldn't occur in a stand-alone computer) then it becomes counter productive to waste time trying to track down the bug that isn't actually in the programming, but in the VM implementation.

I hope I am being clear. I don't have the answer for your specific case, but I think these are hopefully useful considerations in terms of the problem, and I would strongly recommend that such issues be discussed openly and fully with both departments involved, and perhaps a representative of the enterprise management who would ultimately have to make the case for purchasing. Hence my suggestion of a good speaker or intermediary!

Presumably if it requires more employees, then that might be a positive thing (there are plenty of unemployed people out there) but there might be enough IT smarts in the developer section to add a role like server admin for their own group themselves?

I know it's actually quite important, so I don't wish to be flippant, but there are times when I think the consolidation and addition of roles to existing workers lays far too much load on their personal time, which they tend to wind up resenting, especially when they could be being part of something radically new and successful software engineering.

I don't envy your problem, however I do envy the workplace that is fully engaged with bringing about new designs, new software, and new ideas. I sincerely wish you the best of luck, and hope my contributions are of some assistance.

Mihaly

OwnerDisplayName: ScottBai


问:
Can I release a git patch (diff) file of closed source/copyright code?
I've patched a bug in some code that is no longer being supported by it's owner but I would like to provide this to other members of the community.

A git.patch file technically contains copyright source code (in order to show what is removed/changed), does this make it illegal if I don't have permission from the owner?

Would this be considered "fair use"?

答:
This is a very hard question, and only a specialised lawyer will be able to give you an answer. I will just address the technical aspect of your question.

Technical solution of your problem

The easiest technical solution to your problem is to use another patch format.  The patch and diff utilities support several formats, and an especially interesting one for you is the format generated by diff -e:

```<code>   -e  --ed
          Output an ed script.
</code>```

An ed script is a small programm deleting lines in a file and inserting some other lines, much like what the nowadays usual unified patch format describes. However unlike the latter, ed scripts do not contain contextual information.  Technically the ed script contains only your work, so you may see it as an adequate way to distribute your patches. It seems that git-diff does not support the production of patches as ed scripts, so you will need to manually produce them, the easiest way to do so is probably to diff two directories containing the original and the modified version of the source code.

As a side note, I am asking why not bring the original code owner in the discussion?  Has the original code owner any good reasons to refuse you to distribute patches?  There is chances that you can reach an agreement on how to distribute patches on this code, as it seems to me that you add value to the existing software at no cost for the product owner and without eating their bread.

Body:
This is a very hard question, and only a specialised lawyer will be able to give you an answer. I will just address the technical aspect of your question.

Technical solution of your problem

The easiest technical solution to your problem is to use another patch format.  The patch and diff utilities support several formats, and an especially interesting one for you is the format generated by diff -e:

   -e  --ed
          Output an ed script.

An ed script is a small programm deleting lines in a file and inserting some other lines, much like what the nowadays usual unified patch format describes. However unlike the latter, ed scripts do not contain contextual information.  Technically the ed script contains only your work, so you may see it as an adequate way to distribute your patches. It seems that git-diff does not support the production of patches as ed scripts, so you will need to manually produce them, the easiest way to do so is probably to diff two directories containing the original and the modified version of the source code.

As a side note, I am asking why not bring the original code owner in the discussion?  Has the original code owner any good reasons to refuse you to distribute patches?  There is chances that you can reach an agreement on how to distribute patches on this code, as it seems to me that you add value to the existing software at no cost for the product owner and without eating their bread.


答:
This is not going to be something that can easily be answered. Typically, I would recommend "staying clear" of the issue (don't publicly distribute the patch).

You have (as far as I can tell) two real questions that need answering. First, are the little snippits of code in a diff in violation of copyright laws if publicly distributed. I would tend to lean towards "no" as long as the code isn't giving away any core functionality. For example if diff shows entire classes and functions then it probably would cause a problem. If it shows a line or two here and there then it probably isn't a problem.

The second question is do you have the rite to modify and distribute those modifications. The answer to that is usually "no way". Closed source usually means exactly that. Only a "select" group of people have the rite to modify and/or distribute those modifications. The only exceptions that I can think of to this would be some license that was closed source but allowed you to distribute modifications to other licence holders. There are a few software titles that have a license like this.

So basically the answer is that you "probably" do not have the legal rite to distribute your modifications rather they infringe on copyright rules or not. So it becomes a moot point. Even if you could distribute, the question of rather your patches violate copyright is one that would probably have to be answered via trial as it would be unclear, and highly dependent on the overall content of the patches.

Title: Can I release a git patch (diff) file of closed source/copyright code?

Body:
I've patched a bug in some code that is no longer being supported by it's owner but I would like to provide this to other members of the community.

A git.patch file technically contains copyright source code (in order to show what is removed/changed), does this make it illegal if I don't have permission from the owner?

Would this be considered "fair use"?


问:
Objective-c anonymous property coding style
If I have an interface defined like

```<code>@interface MyClass

@property (nonatomic, copy, readonly) NSString *myString;

@end
</code>```

so that myString is externally visible but can't be written, what would be the preferred coding style for redeclaring the property in the implementation? Would it be (a)

```<code>@property (nonatomic, copy) NSString *myString;
</code>```

or (b)

```<code>@property (nonatomic, copy, readwrite) NSString *myString;
</code>```

(I know that these two are exactly the same, this is a question purely about coding style!)

答: The preferred coding style would be (b) according to all style guides that I've seen (e.g. https://github.com/objc-zen/objc-zen-book#property-declaration). They recommend explicitly specify readwrite attribute (for the sake of clarity, I guess).


问:
Can I commerically use GPL licensed software on my server if I am only distributing the client software?
I understand the rules of the GPL stating that if I distribute any software using GPL code, then that code must be licensed under the GPL.

However, I'm wondering what the rules are in this case: I am creating a service where I will be selling and distributing client side software.

The client side software has absolutely no GPL code in it. It is 100% my own code.

However, the client software will be connecting to my server, which internally uses GPL code.

I am not distributing my server side software; the server side software will live on a dedicated server that I alone control, but the client side software will not work without connecting to said server.

Does this count as one software? If I were to do this, would I be required to license my client side source code as GPL? Or, can I sell the client side software without releasing its source code?

答:
This is not a clear-cut issue. Consider two extreme ends of the spectrum:

Your proprietary client software is an HTTP client and it renders HTML responses. It can work with any HTTP server. The HTTP server that you use for your service happens to use GPL components.

You have a program that uses GPL-licensed components. You pick an arbitrary point in that program's operation and break the program into two programs. The two programs communicate over a totally superfluous network hop. You put all the GPL-licensed components in the first program and license under the GPL, and you license the other program under a GPL-incompatible license.

The first case is clearly okay. The second case is clearly not okay. You haven't given much information about your particular case, and even if you did, only a court ruling could decide definitively whether you're in the right.

The GPL FAQ has this to say on interoperable, separately-licensed programs:

However, in many cases you can distribute the GPL-covered software alongside your proprietary system. To do this validly, you must make sure that the free and non-free programs communicate at arms length, that they are not combined in a way that would make them effectively a single program.

The difference between this and “incorporating” the GPL-covered software is partly a matter of substance and partly form. The substantive part is this: if the two programs are combined so that they become effectively two parts of one program, then you can't treat them as two separate programs. So the GPL has to cover the whole thing.

You must decide whether you think your client are server meet the standard of "two parts of the same program" (and therefore must each be licensed under the GPL) or not. The GPL FAQ gives some further explanation on this topic on another question:

Where's the line between two separate programs, and one program with two parts? This is a legal question, which ultimately judges will decide. We believe that a proper criterion depends both on the mechanism of communication (exec, pipes, rpc, function calls within a shared address space, etc.) and the semantics of the communication (what kinds of information are interchanged).

...

By contrast, pipes, sockets and command-line arguments are communication mechanisms normally used between two separate programs. So when they are used for communication, the modules normally are separate programs. But if the semantics of the communication are intimate enough, exchanging complex internal data structures, that too could be a basis to consider the two parts as combined into a larger program.

So, network communication certainly passes the "mechanism of communication" test but it is unclear where your client/server pair falls on the "semantics of communication" test.


问:
What aspects of Haskell led to its rise in popularity among experts?
20 years ago, the Functional Programming world was all about Lisp and Scheme. When I went to college in 2001, my Fall Semester Freshman CS 101 course was taught in OCaml.

However, these days the people that talk about FP always seem to be talking about Haskell.

What is it about Haskell that has led to it's rise in popularity among experts in the FP world? What does it have that gives it an advantage?

Related but not duplicates:

Scheme vs Haskell for an Introduction to Functional Programming?

Haskell AND Lisp vs. Haskell OR Lisp

Functional Programming on the rise?

Choosing a functional programming language

Haskell or Standard ML for beginners? (StackOverflow)

答:
What is it about Haskell that has led to it's rise in popularity among experts in the FP world?

There's a few of different things I've seen:

It's novel. As much as FP enthusiasts poo-poo all of the fads in imperative and OO programming, they're still human. Lisp has been around since the 60's. ML since the 70's. A lot of people have spent a lot of time playing with them, extending them, exploring them. Haskell provides new opportunities for research and exploration.

It's pure. I don't think it's controversial to say that FP enthusiasts are by-and-large not the most practical of sorts. They value elegance and abhor the sort of compromises  (side effects, type system limitations) made by other functional languages in the name of practicality. By being pure and usable, Haskell has affirmed all of their arguments over the years that FP could be awesome if done right.

It's deep. Haskell's main feature is its type system. Since much of its target audience are more academic sorts looking to implement weird academic things in the language, that type system is vital since it provides a playground for those users. It's the key differentiator for the language for those sorts of users.

It works. Haskell has a solid compiler. It has decent library support for a functional language. Once you get to the fringes of popularity, having good compiler support isn't a given. Having a compiler that produces fairly performant code is a luxury, and GHC is pretty good.


问:
What's the idea behind naming classes with "Info" suffix, for example: "SomeClass" and "SomeClassInfo"?
I'm working in a project which deals with physical devices, and I've been confused as how to properly name some classes in this project.

Considering the actual devices (sensors and receivers) are one thing, and their representation in software is another, I am thinking about naming some classes with the "Info" suffix name pattern.

For example, while a Sensor would be a class to represent the actual sensor (when it is actually connected to some working device), SensorInfo would be used to represent only the characteristics of such sensor. For example, upon file save, I would serialize a SensorInfo to the file header, instead of serializing a Sensor, which sort of wouldn't even make sense.

But now I am confused, because there is a middleground on objects' lifecycle where I cannot decide if I should use one or another, or how to get one from another, or even whether both variants should actually be collapsed to only one class.

Also, the all too common example Employee class obviously is just a representation of the real person, but nobody would suggest to name the class EmployeeInfo instead, as far as I know.

The language I am working with is .NET, and this naming pattern seems to be common throughout the framework, for exemple with these classes:

Directory and DirectoryInfo classes;

File and FileInfo classes;

ConnectionInfoclass (with no correspondent Connection class);

DeviceInfo class (with no correspondent Device class);

So my question is: is there a common rationale about using this naming pattern? Are there cases where it makes sense to have pairs of names (Thing and ThingInfo) and other cases where there should only exist the ThingInfo class, or the Thing class, without its counterpart?

答:
It may be a little difficult to find a single unifying convention here because these classes are spread out over a number of namespaces, (ConnectionInfoseems to be in CrystalDecisions, and DeviceInfo in System.Reporting.WebForms).

Looking at these examples, though, there seem to be two distinct uses of the suffix:

Distinguishing a class providing static methods with a class providing instance methods. This is the case for the System.IO classes, as underlined by their descriptions:

Directory:

Exposes static methods for creating, moving, and enumerating through directories and subdirectories. This class cannot be inherited.

DirectoryInfo:

Exposes instance methods for creating, moving, and enumerating through directories and subdirectories. This class cannot be inherited.

Info seems like a slightly odd choice here, but it does make the difference relatively clear: a Directory class could reasonably either represent a particular directory or provide general directory-related helper methods without holding any state, whereas DirectoryInfo could only really be the former.

Emphasising that the class only holds information and does not provide behaviour that might reasonably be expected from the un-suffixed name.

I think that the last part of that sentence might be the piece of the puzzle that distinguishes, say, ConnectionInfo from EmployeeInfo. If I had a class called Connection, I'd reasonably expect it to actually provide me with the functionality that a connection has- I'd be looking for methods like void Open(), etc. However, nobody in their right mind would expect that an Employee class could actually do what a real Employee does, or look for methods like void DoPaperwork() or bool TryDiscreetlyBrowseFacebook().


答:
I think "info" is a misnomer. Objects have state and actions: "info" is just another name for "state" which is already baked into OOP.

What are you really trying to model here? You need an object that represents the hardware in software so other code can use it.

That is easy to say but as you found out, there is more to it than that. "Representing hardware" is surprisingly broad. An object that does that has several concerns:

Low-level device communication, whether it be talking to the USB interface, a serial port, TCP/IP, or proprietary connection.

Managing state. Is the device turned on? Ready to talk to software? Busy?

Handling events. The device produced data: now we need to generate events to pass to other classes that are interested.

Certain devices such as sensors will have fewer concerns than say a printer/scanner/fax multifunction device. A sensor likely just produces a bit stream, while a complex device may have complex protocols and interactions.

Anyway, back to your specific question, there are several ways to do this depending on your specific requirements as well as the complexity of the hardware interaction.

Here is an example of how I would design the class hierarchy for a temperature sensor:

ITemperatureSource: interface that represents anything that can produce temperature data: a sensor, could even be a file wrapper or hard-coded data (think: mock testing).

Acme4680Sensor: ACME model 4680 sensor (great for detecting when the Roadrunner is nearby). This may implement multiple interfaces: perhaps this sensor detects both temperature and humidity. This object contains program-level state such as "is the sensor connected?" and "what was the last reading?"

Acme4680SensorComm: used solely for communicating with the physical device. It does not maintain much state. It is used for sending and receiving messages. It has a C# method for each of the messages the hardware understands.

HardwareManager: used for getting devices. This is essentially a factory that caches instances: there should only be one instance of a device object for each hardware device. It has to be smart enough to know that if thread A requests the ACME temperature sensor and thread B requests the ACME humidity sensor, these are actually the same object and should be returned to both threads.

At the top level you will have interfaces for each hardware type. They describe actions your C# code would take on the devices, using C# data types (not e.g. byte arrays which the raw device driver might use).

At the same level you have an enumeration class with one instance for each hardware type. Temperature sensor might be one type, humidity sensor another.

One level below this are the actual classes that implement those interfaces: they represent one device similar the Acme4680Sensor I described above. Any particular class may implement multiple interfaces if the device can perform multiple functions.

Each device class has its own private Comm (communication) class that handles the low-level task of talking to the hardware.

Outside of the hardware module, the only layer that is visible is the interfaces/enum plus the HardwareManager. The HardwareManager class is the factory abstraction that handles the instantiation of device classes, caching instances (you really do not want two device classes talking to the same hardware device), etc. A class that needs a particular type of sensor asks the HardwareManager to get the device for the particular enum, which it then figures out if it is already instantiated, if not how to create it and initialize it, etc.

The goal here is to decouple business logic from low-level hardware logic. When you are writing code that prints sensor data to the screen, that code should not care what type of sensor you have if and only if this decoupling is in place which centers on those hardware interfaces.

Note: there are associations between the HardwareManager and each device class that I did not draw because the diagram would have turned into arrow soup.

Title: What's the idea behind naming classes with "Info" suffix, for example: "SomeClass" and "SomeClassInfo"?

Body:
I'm working in a project which deals with physical devices, and I've been confused as how to properly name some classes in this project.

Considering the actual devices (sensors and receivers) are one thing, and their representation in software is another, I am thinking about naming some classes with the "Info" suffix name pattern.

For example, while a Sensor would be a class to represent the actual sensor (when it is actually connected to some working device), SensorInfo would be used to represent only the characteristics of such sensor. For example, upon file save, I would serialize a SensorInfo to the file header, instead of serializing a Sensor, which sort of wouldn't even make sense.

But now I am confused, because there is a middleground on objects' lifecycle where I cannot decide if I should use one or another, or how to get one from another, or even whether both variants should actually be collapsed to only one class.

Also, the all too common example Employee class obviously is just a representation of the real person, but nobody would suggest to name the class EmployeeInfo instead, as far as I know.

The language I am working with is .NET, and this naming pattern seems to be common throughout the framework, for exemple with these classes:

Directory and DirectoryInfo classes;

File and FileInfo classes;

ConnectionInfoclass (with no correspondent Connection class);

DeviceInfo class (with no correspondent Device class);

So my question is: is there a common rationale about using this naming pattern? Are there cases where it makes sense to have pairs of names (Thing and ThingInfo) and other cases where there should only exist the ThingInfo class, or the Thing class, without its counterpart?


问:
Avoiding the Grid of Doom™ in Git-Flow
My project follows the Git Flow branching model. Development happens on develop, which is merged into master and tagged there for releases. Hotfixes happen in branches branched off the current master.

However, current development also needs the hotfixes, so each hotfix branch is merged into develop as well.

This creates very ugly revision graphs, especially develop/hotfixes are merged often in a short timeframe:

Is this a problem people usually have with Git-Flow, and is there an easy fix for it?

答:
so your problem is that you're merging every hot fix two or three times? (First to master, then to develop, lastly from develop to master again)?

yeah, that's it! Can't avoid that though, hotfixes have to be merged into develop

Sure, but why merge from develop to master if nothing actually changed?

Take a look at one of those master<-develop<-hotfix merges: there should be no actual change in there (the hotfix was already merged directly to master, after all). If there's no change, just don't do it.

In any case, according to your linked doc, the only merges from develop to master should be going via a release branch. Instead you're keeping master in sync with your (unstable) development branch - don't.

Title: Avoiding the Grid of Doom™ in Git-Flow


问:
Cons of using unconstrained frameworks for unit testing
It's very easy to write unit tests for legacy code using unconstrained frameworks, such as TypeMock Isolator.

But what about writing unit tests for newly written code? Is it a good practice to use an unconstrained framework in such scenario? Or would a constrained framework (such as NSubstitute) enforce better software design?

Update:
An unconstrained framework is a framework that can fake almost anything, including static classes, static constructors, and static methods.
They make it possible for example to fake the result of DateTime.Now.

答:
Whether or not you need to use a unit testing framework is up to you.  Any dependency will need to be faked so that logic can be tested in isolation.  With legacy code where the dependencies are not visible a mocking or faking framework can help expose those dependencies for you and replace them so you can test that code easily without major refactoring.

In new/greenfield development, one can certainly not use a mocking framework if all the dependencies are exposed.  This means that the developer is responsible for writing all the mocks instead of the framework generating them for you.  You may decide its easier to let the framework inline those dependencies instead of the team writing the mocks/fakes manually.

If you don't want to use a framework, as an example consider calculating an age.  This may also answer @Greg B question as well, why you would want to mock DateTime.Now.  It needs the current time to calculate the age which will be difficult to produce consistent tests results since the current time changes.

Interface

```<code>public interface IClock
{
    DateTime Now { get; }
}
</code>```

Real Implementation

```<code>public class SystemClock : IClock
{
    public DateTime Now { get { return DateTime.Now; } }
}
</code>```

Class

```<code>public class DateLogic
{
    private readonly IClock _clock;

    public DateLogic(IClock clock)
    {
        _clock = clock;
    }
    public int CalculateAge(DateTime dateOfBirth)
    {
        DateTime now = _clock.Now;

        int age = now.Year - dateOfBirth.Year;
        if (now < dateOfBirth.AddYears(age)) age--;

        return age;
    }
}
</code>```

Mock/Fake Clock

```<code> public class MockClock200011 : IClock
    {
        public DateTime Now {get {return new DateTime(2000,1,1); } }
    }
</code>```

Test

```<code>[TestMethod]
    public void TestCalculateAge()
    {
        var expected = 30;
        DateTime birthday = new DateTime(1969, 9, 11);
        IClock clock = new MockClock200011();
        var dateLogic = new DateLogic(clock);

        var actual = dateLogic.CalculateAge(birthday);

        Assert.AreEqual(expected, actual);
    }
</code>```

So, in this case we wrote our own mock instead of having the framework do it and have put our age calculation in isolation.  Doesn't matter what year/time, the test will produce the same results.  I don't see any cons of using a framework besides cost and a dependency on that software.  As one can see, you can get by without it provided the dependencies are exposed for mock/fake implementations.

OwnerDisplayName: Ilya Suzdalnitski

Body:
Whether or not you need to use a unit testing framework is up to you.  Any dependency will need to be faked so that logic can be tested in isolation.  With legacy code where the dependencies are not visible a mocking or faking framework can help expose those dependencies for you and replace them so you can test that code easily without major refactoring.

In new/greenfield development, one can certainly not use a mocking framework if all the dependencies are exposed.  This means that the developer is responsible for writing all the mocks instead of the framework generating them for you.  You may decide its easier to let the framework inline those dependencies instead of the team writing the mocks/fakes manually.

If you don't want to use a framework, as an example consider calculating an age.  This may also answer @Greg B question as well, why you would want to mock DateTime.Now.  It needs the current time to calculate the age which will be difficult to produce consistent tests results since the current time changes.

Interface

public interface IClock
{
    DateTime Now { get; }
}

Real Implementation

public class SystemClock : IClock
{
    public DateTime Now { get { return DateTime.Now; } }
}

Class

public class DateLogic
{
    private readonly IClock _clock;

    public DateLogic(IClock clock)
    {
        _clock = clock;
    }
    public int CalculateAge(DateTime dateOfBirth)
    {
        DateTime now = _clock.Now;

        int age = now.Year - dateOfBirth.Year;
        if (now < dateOfBirth.AddYears(age)) age--;

        return age;
    }
}

Mock/Fake Clock

 public class MockClock200011 : IClock
    {
        public DateTime Now {get {return new DateTime(2000,1,1); } }
    }

Test

[TestMethod]
    public void TestCalculateAge()
    {
        var expected = 30;
        DateTime birthday = new DateTime(1969, 9, 11);
        IClock clock = new MockClock200011();
        var dateLogic = new DateLogic(clock);

        var actual = dateLogic.CalculateAge(birthday);

        Assert.AreEqual(expected, actual);
    }

So, in this case we wrote our own mock instead of having the framework do it and have put our age calculation in isolation.  Doesn't matter what year/time, the test will produce the same results.  I don't see any cons of using a framework besides cost and a dependency on that software.  As one can see, you can get by without it provided the dependencies are exposed for mock/fake implementations.


问:
SQL - Designing a Threshold value table
I need to design an SQL table to be used for "threshold" or special values, which in general would have the following properties:
- key
- value
- comparer (less than and greater than as a start, preferably with the ability to add additional types of comparers or rules in the future)

As a basic use case example, these threshold values would be used to raise an event if some parameter in the system exceeds a threshold.

With that in mind, I would appreciate any feedback or input in how precicely to go about this. In the past I have seen such a task done by either using a lookup table containing the types of the comparers, or storing some type of formula in a column and afterwards parsing it using NCalc (.NET) or something similar. Both approaches have drawbacks- the lookup table doesn't seem very practical, and parsing stuff seems very unstable.

Any suggestions on what would be sensible in this scenario would be greatly appreciated. I am not an expert in DB design, so any input will be valuable.

答:
For a database design, all one needs is the left, operator, and right.

Something like this:

X > 10

A table like this:

```<code>RuleSetID   PropertyName    Operand TargetValue
1            Weight          LessThan   200
</code>```

Then one can use System.Linq.Expressions namespace to dynamically create expressions for evaluation.

For more information on this .Net framework feature, please visit this link:

https://msdn.microsoft.com/en-us/library/system.linq.expressions(v=vs.110).aspx

All kinds of operators are supported, greater than, less than etc.

Now, some code to compile the expressions:

```<code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using RulesEngine.Model;
using System.Diagnostics;

namespace RulesEngine.Engine
{
    public class ExpressionBuilder
    {
        public Func<T, bool> Compile<T>(Rule rule, Type type)
        {
            try
            {
                var param = Expression.Parameter(type);
                Expression expression = BuildExpression<T>(rule, param);
                return Expression.Lambda<Func<T, bool>>(expression, param).Compile();
            }
            catch (Exception exception)
            {
                //We would want to log this failure so the rule can be corrected.
                Debug.WriteLine(exception.ToString());
                //Return an expresssion that would always return false
                Expression<Func<T, bool>> defaultLambda = x => false;
                return defaultLambda.Compile();
            }

        }

        private Expression BuildExpression<T>(Rule rule, ParameterExpression param)
        {
            var left = MemberExpression.Property(param, rule.PropertyName);
            var propertyType = typeof(T).GetProperty(rule.PropertyName).PropertyType;
            ExpressionType binaryExpressionType;

            if (ExpressionType.TryParse(rule.Operand, out binaryExpressionType))
            {
                var right = Expression.Constant(Convert.ChangeType(rule.TargetValue, propertyType));
                return Expression.MakeBinary(binaryExpressionType, left, right);
            }
            else
            {
                var methodName = propertyType.GetMethod(rule.Operand);
                var parameterType = methodName.GetParameters()[0].ParameterType;
                var right = Expression.Constant(Convert.ChangeType(rule.TargetValue, parameterType));
                return Expression.Call(left, methodName, right);
            }
        }
    }
}
</code>```

A Rule would be a class to hold the definition from the database.

```<code>using System;
using System.Collections.Generic;
using System.Linq;

namespace RulesEngine.Model
{
    public class Rule
    {
        public string PropertyName { get; private set; }
        public string Operand { get; private set; }
        public string TargetValue { get; private set; }

        public Rule(string propertyName, string operand, string targetValue)
        {
            PropertyName = propertyName;
            Operand = operand;
            TargetValue = targetValue;
        }
    }
}
</code>```

Now we create an object to hold the instance data.  (Replace foo with your threshold instance data).

```<code>public class Foo
{
    public string Name { get; private set; }
    public int Weight { get; private set; }
    public int Size { get; private set; }

    public Foo(string name, int weight, int size)
    {
        Name = name;
        Weight = weight;
        Size = size;
    }
}
</code>```

And finally putting it all together...comparing instance data with the rule.

```<code>private static void RunExample()
        {
            var rule = new Rule("Weight","Equal", "100");
            var foo = new Foo("FooName", 100, 200);

            var expressionBuilder = new ExpressionBuilder();
            Func<Foo, bool> fooRule = expressionBuilder.Compile<Foo>(rule, foo.GetType());

            Console.WriteLine("Is weight equal to 100 for foo?" + fooRule(foo)); //true
        }
</code>```

Since it's generic you can use it as a mini rules engine that can take any instance data and compare it against a set of rules to return true/false.

Title: SQL - Designing a Threshold value table

Body:
For a database design, all one needs is the left, operator, and right.

Something like this:

X > 10

A table like this:

RuleSetID   PropertyName    Operand TargetValue
1            Weight          LessThan   200

Then one can use System.Linq.Expressions namespace to dynamically create expressions for evaluation.

For more information on this .Net framework feature, please visit this link:

https://msdn.microsoft.com/en-us/library/system.linq.expressions(v=vs.110).aspx

All kinds of operators are supported, greater than, less than etc.

Now, some code to compile the expressions:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using RulesEngine.Model;
using System.Diagnostics;

namespace RulesEngine.Engine
{
    public class ExpressionBuilder
    {
        public Func<T, bool> Compile<T>(Rule rule, Type type)
        {
            try
            {
                var param = Expression.Parameter(type);
                Expression expression = BuildExpression<T>(rule, param);
                return Expression.Lambda<Func<T, bool>>(expression, param).Compile();
            }
            catch (Exception exception)
            {
                //We would want to log this failure so the rule can be corrected.
                Debug.WriteLine(exception.ToString());
                //Return an expresssion that would always return false
                Expression<Func<T, bool>> defaultLambda = x => false;
                return defaultLambda.Compile();
            }

        }

        private Expression BuildExpression<T>(Rule rule, ParameterExpression param)
        {
            var left = MemberExpression.Property(param, rule.PropertyName);
            var propertyType = typeof(T).GetProperty(rule.PropertyName).PropertyType;
            ExpressionType binaryExpressionType;

            if (ExpressionType.TryParse(rule.Operand, out binaryExpressionType))
            {
                var right = Expression.Constant(Convert.ChangeType(rule.TargetValue, propertyType));
                return Expression.MakeBinary(binaryExpressionType, left, right);
            }
            else
            {
                var methodName = propertyType.GetMethod(rule.Operand);
                var parameterType = methodName.GetParameters()[0].ParameterType;
                var right = Expression.Constant(Convert.ChangeType(rule.TargetValue, parameterType));
                return Expression.Call(left, methodName, right);
            }
        }
    }
}

A Rule would be a class to hold the definition from the database.

using System;
using System.Collections.Generic;
using System.Linq;

namespace RulesEngine.Model
{
    public class Rule
    {
        public string PropertyName { get; private set; }
        public string Operand { get; private set; }
        public string TargetValue { get; private set; }

        public Rule(string propertyName, string operand, string targetValue)
        {
            PropertyName = propertyName;
            Operand = operand;
            TargetValue = targetValue;
        }
    }
}

Now we create an object to hold the instance data.  (Replace foo with your threshold instance data).

public class Foo
{
    public string Name { get; private set; }
    public int Weight { get; private set; }
    public int Size { get; private set; }

    public Foo(string name, int weight, int size)
    {
        Name = name;
        Weight = weight;
        Size = size;
    }
}

And finally putting it all together...comparing instance data with the rule.

private static void RunExample()
        {
            var rule = new Rule("Weight","Equal", "100");
            var foo = new Foo("FooName", 100, 200);

            var expressionBuilder = new ExpressionBuilder();
            Func<Foo, bool> fooRule = expressionBuilder.Compile<Foo>(rule, foo.GetType());

            Console.WriteLine("Is weight equal to 100 for foo?" + fooRule(foo)); //true
        }

Since it's generic you can use it as a mini rules engine that can take any instance data and compare it against a set of rules to return true/false.


问:
When asynchronous tasks make a bad UX
I'm writing a COM add-in that's extending an IDE that desperately needs it. There are many features involved, but let's narrow it down to 2 for the sake of this post:

There's a Code Explorer toolwindow that displays a treeview that lets the user navigate modules and their members.

There's a Code Inspections toolwindow that displays a datagridview that lets the user navigate code issues and automatically fix them.

Both tools have a "Refresh" button that starts an asynchronous task that parses all the code in all opened projects; the Code Explorer uses the parse results to build the treeview, and the Code Inspections uses the parse results to find code issues and display the results in its datagridview.

What I'm trying to do here, is to share the parse results between features, so that when the Code Explorer refreshes, then the Code Inspections knows about it and can refresh itself without having to redo the parsing work that the Code Explorer just did.

So what I did, I made my parser class an event provider that the features can register to:

```<code>    private void _parser_ParseCompleted(object sender, ParseCompletedEventArgs e)
    {
        Control.Invoke((MethodInvoker) delegate
        {
            Control.SolutionTree.Nodes.Clear();
            foreach (var result in e.ParseResults)
            {
                var node = new TreeNode(result.Project.Name);
                node.ImageKey = "Hourglass";
                node.SelectedImageKey = node.ImageKey;

                AddProjectNodes(result, node);
                Control.SolutionTree.Nodes.Add(node);
            }
            Control.EnableRefresh();
        });
    }

    private void _parser_ParseStarted(object sender, ParseStartedEventArgs e)
    {
        Control.Invoke((MethodInvoker) delegate
        {
            Control.EnableRefresh(false);
            Control.SolutionTree.Nodes.Clear();
            foreach (var name in e.ProjectNames)
            {
                var node = new TreeNode(name + " (parsing...)");
                node.ImageKey = "Hourglass";
                node.SelectedImageKey = node.ImageKey;

                Control.SolutionTree.Nodes.Add(node);
            }
        });
    }
</code>```

And it works. The problem I'm having, is that... it works - I mean, when the code inspections get refreshed, the parser tells the code explorer (and everyone else) "dude, someone's parsing, anything you want to do about it?" - and when parsing completes, the parser tells its listeners "guys, I have fresh parse results for you, anything you want to do about it?".

Let me walk you through an example to illustrate the problem this creates:

User brings up the Code Explorer, which tells the user "hold on, I'm working here"; user continues to work in the IDE, the Code Explorer redraws itself, life is beautiful.

User then brings up the Code Inspections, which tell the user "hold on, I'm working here"; the parser tells the Code Explorer "dude, someone's parsing, anything you want to do about it?" - the Code Explorer tells the user "hold on, I'm working here"; user can still work in the IDE, but can't navigate the Code Explorer because it's refreshing. And he's waiting for the code inspections to complete, too.

User sees a code issue in the inspection results they want to address; they double-click to navigate to it, confirm there's an issue with the code, and click the "Fix" button. The module was modified and needs to be re-parsed, so the code inspections proceed with it; the Code Explorer tells the user "hold on, I'm working here", ...

See where this is going? I don't like it, and I bet users won't like it either. What am I missing? How should I go about sharing parse results between features, but still leave the user in control of when the feature should do its work?

The reason I'm asking, is because I figured that if I postponed the actual work until the user actively decides to refresh, and "cached" the parse results as they come in... well then I'd be refreshing a treeview and locating code issues in a possibly stale parse result... which literally brings me back to square one, where each feature works with its own parse results: is there any way I can share parse results between features and have a lovely UX?

The code is c#, but I'm not looking for code, I'm looking for concepts.

答:
The way that I would probably approach this would be to focus less on providing perfect results, and instead focus on a best-effort approach. This would result in at least the following changes:

Convert the logic that currently starts a re-parse to request instead of initiate.

The logic for requesting a re-parse may end up looking something like this:

```<code>IF parseIsRunning IS false
  startParsingThread()
ELSE
  SET shouldParse TO true
END
</code>```

This will be paired with logic wrapping the parser, that may look something like this:

```<code>SET parseIsRunning TO true
DO
  SET shouldParse TO false
  doParsing()
WHILE shouldParse IS true
SET parseIsRunning TO false
</code>```

The important thing is that the parser run until the most recent re-parse request has been honored, but no more than one parser is running at any given time.

Remove the ParseStarted callback. Requesting a re-parse is now a fire and forget operation.

Alternately, convert it to do nothing other than show a refreshing indicator in some out of the way part of the GUI that does not block user interaction.

Try to provide minimal handling for stale results.

In the case of the Code Explorer, that may be as simple as looking a reasonable number of lines up and down for a method the user wants to navigate to, or the nearest method if an exact name wasn't found.

I'm not sure what would be appropriate for the Code Inspector.

I'm not sure of the implementation details, but overall, this is very similar to how the NetBeans editor handles this behavior. It is always very quick to point out that it's currently refreshing, but also does not block access to the functionality.

Stale results are often good enough - especially when compared to no results.

Title: When asynchronous tasks make a bad UX

Body:
The way that I would probably approach this would be to focus less on providing perfect results, and instead focus on a best-effort approach. This would result in at least the following changes:

Convert the logic that currently starts a re-parse to request instead of initiate.

The logic for requesting a re-parse may end up looking something like this:

IF parseIsRunning IS false
  startParsingThread()
ELSE
  SET shouldParse TO true
END

This will be paired with logic wrapping the parser, that may look something like this:

SET parseIsRunning TO true
DO
  SET shouldParse TO false
  doParsing()
WHILE shouldParse IS true
SET parseIsRunning TO false

The important thing is that the parser run until the most recent re-parse request has been honored, but no more than one parser is running at any given time.

Remove the ParseStarted callback. Requesting a re-parse is now a fire and forget operation.

Alternately, convert it to do nothing other than show a refreshing indicator in some out of the way part of the GUI that does not block user interaction.

Try to provide minimal handling for stale results.

In the case of the Code Explorer, that may be as simple as looking a reasonable number of lines up and down for a method the user wants to navigate to, or the nearest method if an exact name wasn't found.

I'm not sure what would be appropriate for the Code Inspector.

I'm not sure of the implementation details, but overall, this is very similar to how the NetBeans editor handles this behavior. It is always very quick to point out that it's currently refreshing, but also does not block access to the functionality.

Stale results are often good enough - especially when compared to no results.


问:
Testing front-end app that hits a REST service
A lot of questions about testing here... And I have another one. Forgive me, but I want to make sure I do this right.

Let's say I have a front-end application, be it a mobile app, or a single-page website, or anything else. This app hits a REST service, that I also develop. The service fetches data from 3rd party REST APIs, processes this data, and returns the results to the application.

My service is well tested and developed in a hexagonal manner, with comprehensive black-box unit tests (canned data) and few integration tests (hitting 3rd party services) to see that adapters are working ok with ports (see here).

My front end is also well tested with unit tests and mock data (it doesn't really hit the service in tests). I feel though that it would be nice if it was tested together with the service I develop. The few things I am unsure of:

Should I be using canned data when testing my service, or should I be hitting 3rd party APIs in the tests?

Should these be comprehensive automated tests (provided that all functionality is already tested with canned data on front end, and the service is really well tested too, so a lot of these tests would be testing what's already tested), or should it be just few manual tests, like hitting some buttons and seeing if the data comes through? Here I am mainly thinking about the cost/benefit ratio.

Are there any frameworks to write comprehensive automated tests like that?

I am sure many of you were in similar situation. So it would be great to get some advice. If you can link a white paper or a conference about the subject, it would be even better. Thanks in advance for any suggestions.

答:
Yes you should always test the system with all real-world architecture if you can, some problem may be only occurred in real system/data tests (out of memory/locked connection/environment stableness).

If the business logic and data communication is proven to be working great, the next thing you should focus on will be stress test for the service: Regards to your server stacks, how many request can it handled in given time? how is the bandwidth/CPU/thread/memory of the web application server you deployed can stand with?

For the stress test framework, we tried WAPT and it should be good enough for general stress test case.


问:
Should I use inheritance to differentiate objects even if they have the same fields?
Consider this simple class that models a real world mobile device:

///
///     Model that represents a device.
///
public class Device
{
    public DateTime CreationDate { get; set; }

    public bool Enabled { get; set; }

    ///
    ///     Gets or sets the device's hardware identifier.
    ///
    /// <remarks>Commonly filled with data like device's IMEI.</remarks>
    public string HardwareId { get; set; }

    public int Id { get; set; }

    public DateTime? LastCommunication { get; set; }
}
```

<p>Now suppose a new requirement arrived and I need to start differentiating a device by platform, like <code>Windows Phone</code>, <code>Android</code> and <code>iOS</code>. The most common option I think would be to create an enumeration class:</p>

<pre class="lang-cs prettyprint-override"><code>/// <summary>
///     Defines a type of device.
/// </summary>
enum PlatformType
{
    /// <summary>
    ///     Device is an Android.
    /// </summary>
    Android,

    /// <summary>
    ///     Device is an Windows platform.
    /// </summary>
    Windows,

    /// <summary>
    ///     Device is an iOS platform.
    /// </summary>
    Ios,
}
</code>```

and then add a new property to the device class:

public class Device
{
    ...

    public PlatformType Platform { get; set; }

    ...
}
```

<p>Another approach would be to create a inheritance hierarchy on the device class itself:</p>

<pre class="lang-cs prettyprint-override"><code>public class AndroidDevice : Device { }

public class IosDevice : Device { }

public class WindowsPhoneDevice : Device { }
</code>```

When should I choose one of those approaches over the other? Should I always choose the second one or is there a reason not to?

答:
If there is a lot of "common code" (or abstractions that all platforms make use of), another option is composition, rather than inheritance.  I believe that anything you can do with inheritance, you can also accomplish through composition (I'm probably going to regret saying "anything").  Inheritance is going to lock you into that base implementation, composition gives you a choice.

Using a contrived example, if you were going to implement a base class that had common functionality such as:

```<code>class BaseFoo
{
    public DoThis() {
    }

    public DoThat() {
    }
}
</code>```

And subclasses:

```<code>class MyFoo : BaseFoo {
}

class YourFoo : BaseFoo {
}
</code>```

Those subclasses are locked into the behavior of the base class.  (Yes, you can make methods virtual and override their behavior, but, for the sake of argument, let's say that what the base methods do is extremely complex and you don't want to/can't re-implement it.)

If you instead had each implement the same interface (representing the Foo abstraction) and composed the classes, they are free do implement the abstraction how they see fit:

```<code>interface IFoo
{
    void DoThis();
    void DoThat();
}

class MyFoo : IFoo {
    private readonly IThisStrategy _thisStrategy;
    private readonly IThatStrategy _thatStrategy;

    public MyFoo(IThisStrategy thisStrategy, IThatStrategy thatStrategy) {
        _thisStrategy = thisStrategy;
        _thatStrategy = thatStrategy;
    }

    public void DoThis() {
        _thisStrategy();
    }
}
</code>```

It may take a bit more work to implement the solution through composition, but the benefits include decoupling, flexibility, and reusable components (the strategy implementations).  This also has testing benefits as you can unit test individual behaviors that you're injecting without having to test the object at large.  And this also avoids polluting your code with a bunch of switch statements everywhere that later cause a maintenance headache should you ever need to support a new platform or change that platform's behavior.

I'm a firm believer in composition over inheritance in a great many cases, especially when inheritance is not being used to actually extend a functional base.

Body:
If there is a lot of "common code" (or abstractions that all platforms make use of), another option is composition, rather than inheritance.  I believe that anything you can do with inheritance, you can also accomplish through composition (I'm probably going to regret saying "anything").  Inheritance is going to lock you into that base implementation, composition gives you a choice.

Using a contrived example, if you were going to implement a base class that had common functionality such as:

class BaseFoo
{
    public DoThis() {
    }

    public DoThat() {
    }
}

And subclasses:

class MyFoo : BaseFoo {
}

class YourFoo : BaseFoo {
}

Those subclasses are locked into the behavior of the base class.  (Yes, you can make methods virtual and override their behavior, but, for the sake of argument, let's say that what the base methods do is extremely complex and you don't want to/can't re-implement it.)

If you instead had each implement the same interface (representing the Foo abstraction) and composed the classes, they are free do implement the abstraction how they see fit:

interface IFoo
{
    void DoThis();
    void DoThat();
}

class MyFoo : IFoo {
    private readonly IThisStrategy _thisStrategy;
    private readonly IThatStrategy _thatStrategy;

    public MyFoo(IThisStrategy thisStrategy, IThatStrategy thatStrategy) {
        _thisStrategy = thisStrategy;
        _thatStrategy = thatStrategy;
    }

    public void DoThis() {
        _thisStrategy();
    }
}

It may take a bit more work to implement the solution through composition, but the benefits include decoupling, flexibility, and reusable components (the strategy implementations).  This also has testing benefits as you can unit test individual behaviors that you're injecting without having to test the object at large.  And this also avoids polluting your code with a bunch of switch statements everywhere that later cause a maintenance headache should you ever need to support a new platform or change that platform's behavior.

I'm a firm believer in composition over inheritance in a great many cases, especially when inheritance is not being used to actually extend a functional base.


问:
How can I unit test a class which requires a web service call?
I'm trying to test a class which calls some Hadoop web services. The code is pretty much of the form:

```<code>method() {
    ...use Jersey client to create WebResource...
    ...make request...
    ...do something with response...
}
</code>```

e.g. there is a create directory method, a create folder method etc.

Given that the code is dealing with an external web service that I don't have control over, how can I unit test this? I could try and mock the web service client/responses but that breaks the guideline I've seen a lot recently: "Don't mock objects you don't own". I could set up a dummy web service implementation - would that still constitute a "unit test" or would it then be an integration test? Is it just not possible to unit test at this low a level - how would a TDD practitioner go about this?

答:
What I've done, and it works:

Have all code call webservices through proxy.

The proxy calls a class that statically knows if we are using proxy or not and redirects accordingly. Mocks are just HashMaps that for each request returns a given reply.

Run the tests several times in this order:

3.1 First all webservices are tested. From each machine, even developer's machines. These are the real webservices, but running in development envioronment. This means webservices can never be down or reply erroneous values, because otherwise every developer complains that he can't compile.

3.2 Then all unit tests internal to the application are run. This means that all webservices are mocked and tested runnning the same tests as 3.1 (anbde they should pass too, otherwise out mocks are wrong), and being invoked by the real application as if they were really being used. If the mocks are wrong, you can run the test in 3.1 and record those (request, reply) values in a HashMap.

3.3 Then the same tests as 3.2 are run, but this time against the real webservices running in the development environment.

After all these has been completed, for the real production environment you just need to provide the real address for each webservice. Hopefully this doesn't require too much change in the configuration.


答:
In general, an Info object encapsulates information about an object's state at some moment in time.  If I ask the system to look at a file and give me a FileInfo object associated with its size, I would expect that object to report the size of the file at the time the request was given (or, to be more precise, the size of the file at some moment between when the call was made and when it returned).  If the size of the file changes between the time the request returns and a time the FileInfo object is examined, I would not expect such a change to be reflected in the FileInfo object.

Note that this behavior would be very different from that of a File object.  If a a request to open a disk file in non-exclusive mode yields a File object which has a Size property, I would expect the value returned thereby to change when the size of the disk file changes, since the File object doesn't merely represent the state of a file--it represents the file itself.

In many cases, objects that attach to a resource must be cleaned up when their services are no longer needed.  Because *Info objects do not attach to resources, they do not require cleanup.  As a consequence, in cases where an Info object will satisfy a client's requirements, it may be better to have code use one than to to use an object which would represent the underlying resource, but whose connection to that resource would have to be cleaned up.


答:
Mocks are acceptable in this case, but you don't need it. Instead of unit testing method(), instead unit test just the portion that handles the response.

Extract a function that takes ResponseData (of whatever kind is appropriate) and then performs the action.

Instead of mocking, now you just construct a ResponseData object and pass it in.

You can leave the calling of the service to full integration tests - that will cover method() in total

Title: How can I unit test a class which requires a web service call?

Body:
I'm trying to test a class which calls some Hadoop web services. The code is pretty much of the form:

```<code>method() {
    ...use Jersey client to create WebResource...
    ...make request...
    ...do something with response...
}
</code>```

e.g. there is a create directory method, a create folder method etc.

Given that the code is dealing with an external web service that I don't have control over, how can I unit test this? I could try and mock the web service client/responses but that breaks the guideline I've seen a lot recently: "Don't mock objects you don't own". I could set up a dummy web service implementation - would that still constitute a "unit test" or would it then be an integration test? Is it just not possible to unit test at this low a level - how would a TDD practitioner go about this?


答:
In general I prefer composition over inheritance. That has several reasons:

Humans are bad at dealing with complexity. And dealing with high inheritance trees is complexity. I want light structures on my brain, which I could overlook easily. The same goes for dozens of types even derived from one base class.

You are able to switch moving parts out. You could have a simple device, which does runOperatingSystem(), instead of making two different device-classes, you make only one and give it an Operating System. If you want to test behavior, you could inject a mockOperatingSystem and see, if it does, what it should.

You are able to extend behaviour, simply by injecting more behavioral components.

In terms of abstraction, you are better off, designing a generic device type:
In Python the design would look like the following

```<code>class Device:
    def __init__(self, OS, name):
        self.OS=OS
        self.name=name
    def browseInterNet(self):
        self.OS.browseInterNet()

class Android:
    def browseInterNet(self):
        print("I'm browsing")
</code>```

You have a generic device which runs an operating system. Every userinteraction is delegated to this OS. Perhaps you want to test only the browsing call dependent on any operating systen, you could easily swap it out.

The next step for this design would be, to create a configuration-object, which takes the common parameters (CreationDate, HardwareId and so on). Inject this configuration and the appropriate OS via constructor injection and you are done.

You define common behaviour in a contract (interface), which determines, what you could do with a phone and the operation system deals with the implementation.

Translated to everyday language: If you text with your phone, there is no difference in doing it with an iPhone, Android or Windows in that respect, that you are texting, although the mechanisms from OS to OS differ. How they deal technically with it is uninteresting for the device. The OS runs the texting app, which itself takes care of its implementation. It is all a question of abstracting commonalities.

On the other hand: this is only one way of doing it. It depends on you and your model of the domain.

From the comments:

But you have to agree with me that this would require one to create a lot of wrapper methods to make the API simpler

This depends on what exactly you want to model. To extend the given example of texting:

Say, you simply have some basic jobs, you want the device to do, you define an API for that; in our case simply the method sendSMS(text).You have then the Device, where the message "send text" is called upon. The device in turn delegates that call to the used  operating system, which does the actual sending.

If you want to model more than a handful of services your device offers, you have to make bloated API.

This is a sign, that your abstraction level is too low.

The next step would be to abstract the concept of an app out of the system.

In principle, you have a device which interacts with the inner logic of an app, which runs on an operating system. You have input, which is processed and changes the display of the device.

In terms of MVC, e.g. your keyboard is the controller, the display is the view and there is the model within the app, which is modified. And since the view observes the model it reflects any changes.

With such an abstract concept, you are very flexible to build / model a lot of use cases.

I also am not seeing exactly how you would handle the operations concept here. There are still many types of operations, each with differing parameters, that can or can't be applied to a given device.

As said above:it is all a matter of abstraction. The more power you want, the more abstract your model has to be.

Where would the OS be located now after this abstraction?

Taking the example further, you have to develop several abstractions / patterns, which help in this case.

Mediator-Pattern: The operating system acts as a mediator, i.e. it takes signals in form of commands, sends it to the app and takes in response commands to e.g. update the view

Command-Pattern: The command pattern is the form of abstraction, which is used to describe the communication flow between components. Say, the user presses A, than this could be abstracted as Keypressed-command with a value of A. Another command would be update display with the value of keypress.value or in this case A.

MVC The display as the view, the keyboard as the controller and in between the (app-)model.

Your imagination is your limit.

This is the kind of stuff, OOP was invented for originally: simulating independent components and their interaction

Title: Should I use inheritance to differentiate objects even if they have the same fields?

Body:
Consider this simple class that models a real world mobile device:

///
///     Model that represents a device.
///
public class Device
{
    public DateTime CreationDate { get; set; }

    public bool Enabled { get; set; }

    ///
    ///     Gets or sets the device's hardware identifier.
    ///
    /// <remarks>Commonly filled with data like device's IMEI.</remarks>
    public string HardwareId { get; set; }

    public int Id { get; set; }

    public DateTime? LastCommunication { get; set; }
}
```

<p>Now suppose a new requirement arrived and I need to start differentiating a device by platform, like <code>Windows Phone</code>, <code>Android</code> and <code>iOS</code>. The most common option I think would be to create an enumeration class:</p>

<pre class="lang-cs prettyprint-override"><code>/// <summary>
///     Defines a type of device.
/// </summary>
enum PlatformType
{
    /// <summary>
    ///     Device is an Android.
    /// </summary>
    Android,

    /// <summary>
    ///     Device is an Windows platform.
    /// </summary>
    Windows,

    /// <summary>
    ///     Device is an iOS platform.
    /// </summary>
    Ios,
}
</code>```

and then add a new property to the device class:

public class Device
{
    ...

    public PlatformType Platform { get; set; }

    ...
}
```

<p>Another approach would be to create a inheritance hierarchy on the device class itself:</p>

<pre class="lang-cs prettyprint-override"><code>public class AndroidDevice : Device { }

public class IosDevice : Device { }

public class WindowsPhoneDevice : Device { }
</code>```

When should I choose one of those approaches over the other? Should I always choose the second one or is there a reason not to?

Body:
In general I prefer composition over inheritance. That has several reasons:

Humans are bad at dealing with complexity. And dealing with high inheritance trees is complexity. I want light structures on my brain, which I could overlook easily. The same goes for dozens of types even derived from one base class.

You are able to switch moving parts out. You could have a simple device, which does runOperatingSystem(), instead of making two different device-classes, you make only one and give it an Operating System. If you want to test behavior, you could inject a mockOperatingSystem and see, if it does, what it should.

You are able to extend behaviour, simply by injecting more behavioral components.

In terms of abstraction, you are better off, designing a generic device type:
In Python the design would look like the following

class Device:
    def __init__(self, OS, name):
        self.OS=OS
        self.name=name
    def browseInterNet(self):
        self.OS.browseInterNet()

class Android:
    def browseInterNet(self):
        print("I'm browsing")

You have a generic device which runs an operating system. Every userinteraction is delegated to this OS. Perhaps you want to test only the browsing call dependent on any operating systen, you could easily swap it out.

The next step for this design would be, to create a configuration-object, which takes the common parameters (CreationDate, HardwareId and so on). Inject this configuration and the appropriate OS via constructor injection and you are done.

You define common behaviour in a contract (interface), which determines, what you could do with a phone and the operation system deals with the implementation.

Translated to everyday language: If you text with your phone, there is no difference in doing it with an iPhone, Android or Windows in that respect, that you are texting, although the mechanisms from OS to OS differ. How they deal technically with it is uninteresting for the device. The OS runs the texting app, which itself takes care of its implementation. It is all a question of abstracting commonalities.

On the other hand: this is only one way of doing it. It depends on you and your model of the domain.

From the comments:

But you have to agree with me that this would require one to create a lot of wrapper methods to make the API simpler

This depends on what exactly you want to model. To extend the given example of texting:

Say, you simply have some basic jobs, you want the device to do, you define an API for that; in our case simply the method sendSMS(text).You have then the Device, where the message "send text" is called upon. The device in turn delegates that call to the used  operating system, which does the actual sending.

If you want to model more than a handful of services your device offers, you have to make bloated API.

This is a sign, that your abstraction level is too low.

The next step would be to abstract the concept of an app out of the system.

In principle, you have a device which interacts with the inner logic of an app, which runs on an operating system. You have input, which is processed and changes the display of the device.

In terms of MVC, e.g. your keyboard is the controller, the display is the view and there is the model within the app, which is modified. And since the view observes the model it reflects any changes.

With such an abstract concept, you are very flexible to build / model a lot of use cases.

I also am not seeing exactly how you would handle the operations concept here. There are still many types of operations, each with differing parameters, that can or can't be applied to a given device.

As said above:it is all a matter of abstraction. The more power you want, the more abstract your model has to be.

Where would the OS be located now after this abstraction?

Taking the example further, you have to develop several abstractions / patterns, which help in this case.

Mediator-Pattern: The operating system acts as a mediator, i.e. it takes signals in form of commands, sends it to the app and takes in response commands to e.g. update the view

Command-Pattern: The command pattern is the form of abstraction, which is used to describe the communication flow between components. Say, the user presses A, than this could be abstracted as Keypressed-command with a value of A. Another command would be update display with the value of keypress.value or in this case A.

MVC The display as the view, the keyboard as the controller and in between the (app-)model.

Your imagination is your limit.

This is the kind of stuff, OOP was invented for originally: simulating independent components and their interaction


问:
Handling my antiquated coworker
I'm a fairly young programmer, and I work at a medium sized company's IT department. I have a coworker, and he is a really good Visual Basic 6 programmer. And I mean really good. Honestly. He can deliver working applications, containing very few bugs, in the time I need to get my first cup of coffee, and boot my machine. He is just that good.

Thing is, we are working with a team, and his working style is completely antiquated. He doesn't believe in versioning software (if you just make sure your code is correct, you don't need all that nonsense). Doesn't believe in deployment (I can deliver a working executable. How that is deployed is for the sysadmins to figure out). Doesn't believe in abstraction. ('if you want to create a subroutine, go ahead, but don't call any subroutines from that subroutine. It gets messy that way, and the code is hard to follow. This way every one can follow every step on the way.' or 'yeah, sure you can use that library to do that for you, but that way you don't really understand what's going on') and certainly doesn't believe in OOP. (we work in VB.net)

He is so good in what he does, he can deliver applications way faster than I can. But it just doesn't work in a team. Our other team member is quiet, and doesn't like to speak out, though he tends to agree. Our manager thinks I make valid points, but is not a programmer.

I have a really hard time maintaining programs he has written, and it doesn't make for a good team atmosphere. What do you think is the best thing for me to do?

答: Talk to your manager, plain and simple like you did here. There is potential here for growth - if your coworker is good as you say he is it shouldn't take him much convincing to make him start converting to using source control and .Net with proper OO concepts.</p>

Title: Handling my antiquated coworker


问:
Why should I use an MVC pattern?
It seems everyone doing web applications nowadays wants to use MVC for everything. I find it hard to convince myself to use this pattern, however. I understand the general idea is to separate the backend logic from the frontend that represents the program. Generally, it seems that the views always depend on the controller to some extent, which ends up depending on the model. I don't see what advantage adding the controller gets me. I've read a lot of hype about "this is the way applications should be designed", but maybe I still don't understand what is supposed to go where. Whenever I talk to others about MVC it seems everyone has a different idea of what belongs in what category.

So, why should I use MVC? What do I gain by using MVC over just separating the frontend from the backend logic? (Most "advantages" I see of this pattern are gained just by separating interface from implementation, and fail to explain the purpose of having a separate "controller")

答:
I think MVC is used just a buzzword by theorists that are managers.  However, having said that, the current iteration of the web with HTML5 prevalent, responsive design, and trying to create a single line of database programming that will work on the web and on an iPhone lends itself to the general ideas of MVC.  The web front-end technology is literally moving at the speed of light right now with Jquery, new iterations of CSS control, whereas the server side of things is moving at the pace of a snail.

Eventually, everything on the server will really just be services or "applets" that pump data to the front-end and depending on what kind of client you have, that data will be consumed and displayed differently.  In that sense, MVC makes sense.

In this regard, I believe in the current real world, the MVVM is really a better "pattern" or whatever you want to call it than a controller because a controller always has to go back to the model to change the view and this is slow.  In the MVVM pattern the ViewModel can give immediate updates to the view.  In addition the MVVM model promotes RESTful design principals IMHO.

Title: Why should I use an MVC pattern?


问:
What if I can't make my unit test fail in "Red, Green, Refactor" of TDD?
So let's say that I have a test:

```<code>@Test
public void MoveY_MoveZero_DoesNotMove() {
    Point p = new Point(50.0, 50.0);
    p.MoveY(0.0);
    Assert.assertAreEqual(50.0, p.Y);
}
</code>```

This test then causes me to create the class Point:

```<code>public class Point {
    double X; double Y;
    public void MoveY(double yDisplace) {
        throw new NotYetImplementedException();
    }
}
</code>```

Ok.  It fails.  Good.  Then I remove the exception and I get green. Great, but of course I need to test if it changes value.  So I write a test that calls p.MoveY(10.0) and checks if p.Y is equal to 60.0.  It fails, so then I change the function to look like so:

```<code>public void MoveY(double yDisplace) {
    Y += yDisplace;
}
</code>```

Great, now I have green again and I can move on.  I've tested not moving and moving in the positive direction, so naturally I should test a negative value.  The only problem with this test is that if I wrote the test correctly, then it doesn't fail at first.  That means that I didn't fit the principle of "Red, Green, Refactor."

Of course, This is a first-world problem of TDD, but getting a fail at first is helpful in that it shows that your test can fail.  Otherwise this seemingly innocent test that is just passing for incorrect reasons could fail later because it was written wrong.  That might not be a problem if it happened 5 minutes later, but what if it happens to the poor-sap that inheirited your code two years later.  What he knows is that MoveY does not work with negative values because that is what the test is telling him.  But, it really could work and just be a bug in the test.

I don't think that would happen in this particular case because the code sample is so simple, but if it were a large complicated system that might not be the case.  It seems crazy to say that I want to fail my tests, but that is an important step in TDD, for good reasons.

答:
The Red-Green part of the cycle tests the test. If you have a hunch that a particular edge case needs to be considered, or just to show that it's been accounted for, I'd argue it's legitimate to artificially force a failure to prove that a test locks the implementation into a correct behavior.

In the example case, it's probably unnecessary. But, if you ever need a more complicated MoveY implementation that accounts for ... weird rules, barriers, bounds, and the like -- it is potentially helpful to ensure that any additional rules and bounds-checking operate on 0 as expected (not at all).

So ... write the code incorrectly:

```<code>public void MoveY(double yDisplace) {
    Y += 100;  // to test the test
    Y += yDisplace;
}
</code>```

Run the test to verify that the relevant MoveY test(s) fail. And then ensure that removing the bad code causes the test(s) to pass:

```<code>public void MoveY(double yDisplace) {
    Y += yDisplace;
}
</code>```

If your project has been rigidly TDD from the start; you usually won't need to do this sort of thing. But, even on largely TDD'd code, I've encountered transient bugs that I couldn't be confident I'd solved without temporarily simulating a failure in down-the-line code in a similar fashion.

Similarly, in the process of porting code from an old system to a new one, I've written tests that would have failed on the OLD code but not the NEW code simply because the new code was far simpler. So, manually failing those tests gives me the confidence that future complexities won't reintroduce bugs that the OLD complexity initially produced: my test has been tested to protect against them!

Body:
The Red-Green part of the cycle tests the test. If you have a hunch that a particular edge case needs to be considered, or just to show that it's been accounted for, I'd argue it's legitimate to artificially force a failure to prove that a test locks the implementation into a correct behavior.

In the example case, it's probably unnecessary. But, if you ever need a more complicated MoveY implementation that accounts for ... weird rules, barriers, bounds, and the like -- it is potentially helpful to ensure that any additional rules and bounds-checking operate on 0 as expected (not at all).

So ... write the code incorrectly:

public void MoveY(double yDisplace) {
    Y += 100;  // to test the test
    Y += yDisplace;
}

Run the test to verify that the relevant MoveY test(s) fail. And then ensure that removing the bad code causes the test(s) to pass:

public void MoveY(double yDisplace) {
    Y += yDisplace;
}

If your project has been rigidly TDD from the start; you usually won't need to do this sort of thing. But, even on largely TDD'd code, I've encountered transient bugs that I couldn't be confident I'd solved without temporarily simulating a failure in down-the-line code in a similar fashion.

Similarly, in the process of porting code from an old system to a new one, I've written tests that would have failed on the OLD code but not the NEW code simply because the new code was far simpler. So, manually failing those tests gives me the confidence that future complexities won't reintroduce bugs that the OLD complexity initially produced: my test has been tested to protect against them!


问:
Can a UML class diagram show two different relationships between two classes?
I have a class which has an inner (nested) class. I have shown this relationship between the two classes in my class diagram. However, I am also using the inner class within the outer class... do I show another relationship for this or is the containment relationship enough?</p>

答:
I would say no. You don't have to specify another relationship.

Inner classes AFAIK are implied to be used by their container. That's why they're an inner class. No one else needs to know about this class and no one has a use for it. This inner class is separate from it's containing object because it's different from the containing object, yet the container has an explicit need for this class and only this object has this need. Therefore, specifying a relationship between the containing class and inner class is enough to inherently imply these two classes are communicating with each other.

If the container class and inner class WEREN'T communicating with each other or worse yet, another object was calling directly to the inner class would show a clear design flaw of ever having this class as an inner class because its design purpose of being an inner class was not being correctly fulfilled.

If you wanted to go deeper in your design at some point you'd specify how the containing class is using the inner class and not just specify the container is using this inner class.


问:
Ternary operator considered harmful?
For example, would you prefer this one-liner

```<code>int median(int a, int b, int c) {
    return (a<b) ? (b<c) ? b : (a<c) ? c : a : (a<c) ? a : (b<c) ? c : b;
}
</code>```

or an if/else solution involving multiple return statements?

When is ?: appropriate, and when is it not? Should it be taught to or hidden from beginners?

答:
When is ?: appropriate

When it makes your code more concise and readable.

and when is it not?

When it makes your code unreadable.

If you're doing it just to please a refactoring tool like ReSharper and not the person who has to maintain the code

If you have any logic or function calls inside the ternary expression, you're making it horrible to look at.

Title: Ternary operator considered harmful?