问:
C++ serialization design review
I am writing a C++ application. Most applications read and write data citation needed and this one is no exception. I created a high level design for the data model and serialization logic. This question is requesting a review of my design with these specific goals in mind:

To have an easy and flexible way to read and write data models in arbitrary formats: raw binary, XML, JSON, et. al. The format of data should be decoupled from the data itself as well as the code that is requesting serialization.

To ensure that serialization is as error-free as reasonably possible. I/O is inherently risky for a variety of reasons: does my design introduce more ways for it to fail? If so, how could I refactor the design to mitigate those risks?

This project uses C++. Whether you love it or hate it, the language has its own way of doing things and the design aims to work with the language, not against it.

Finally, the project is built on top of wxWidgets. While I am looking for a solution applicable to a more general case, this specific implementation should work nicely with that toolkit.

What follows is a very simple set of classes written in C++ that illustrate the design. These are not the actual classes that I have partially written so far, this code simply illustrates the design I am using.

First, some sample DAOs:

#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <vector>

// One widget represents one record in the application.
class Widget {
public:
  using id_type = int;
private:
  id_type id;
};

// Container for widgets. Much more than a dumb container,
// it will also have indexes and other metadata. This represents
// one data file the user may open in the application.
class WidgetDatabase {
  ::std::map<Widget::id_type, ::std::shared_ptr<Widget>> widgets;
};
```

<p>Next, I define pure virtual classes (interfaces) for reading and writing DAOs. The idea is to abstract the serialization of data from the data itself (SRP).</p>

```class WidgetReader {
public:
  virtual Widget read(::std::istream &in) const abstract;
};

class WidgetWriter {
public:
  virtual void write(::std::ostream &out, const Widget &widget) const abstract;
};

class WidgetDatabaseReader {
public:
  virtual WidgetDatabase read(::std::istream &in) const abstract;
};

class WidgetDatabaseWriter {
public:
  virtual void write(::std::ostream &out, const WidgetDatabase &widgetDb) const abstract;
};
```

<p>Finally, here is the code that gets the proper reader/writer for the desired I/O type. There would be subclasses of the readers/writers also defined, but these add nothing to the design review:</p>

```enum class WidgetIoType {
  BINARY,
  JSON,
  XML
  // Other types TBD.
};

WidgetIoType forFilename(::std::string &name) { return ...; }

class WidgetIoFactory {
public:
  static ::std::unique_ptr<WidgetReader> getWidgetReader(const WidgetIoType &type) {
    return ::std::unique_ptr<WidgetReader>(/* TODO */);
  }

  static ::std::unique_ptr<WidgetWriter> getWidgetWriter(const WidgetIoType &type) {
    return ::std::unique_ptr<WidgetWriter>(/* TODO */);
  }

  static ::std::unique_ptr<WidgetDatabaseReader> getWidgetDatabaseReader(const WidgetIoType &type) {
    return ::std::unique_ptr<WidgetDatabaseReader>(/* TODO */);
  }

  static ::std::unique_ptr<WidgetDatabaseWriter> getWidgetDatabaseWriter(const WidgetIoType &type) {
    return ::std::unique_ptr<WidgetDatabaseWriter>(/* TODO */);
  }
};
```

Per the stated goals of my design, I have one specific concern. C++ streams can be opened in text or binary mode, but there is no way to check an already-opened stream. It could be possible through programmer error to provide e.g. a binary stream to an XML or JSON reader/writer. This could cause subtle (or not so subtle) errors. I would prefer the code to fail fast, but I am not sure this design would do that.

One way around this could be to offload the responsibility of opening the stream to the reader or writer, but I believe that violates SRP and would make the code more complex. When writing a DAO, the writer should not care about where the stream is going: it could be a file, standard out, an HTTP response, a socket, anything. Once that concern is encapsulated in the serialization logic it becomes far more complex: it must know the specific type of stream and which constructor to call.

Aside from that option, I am not sure what would be a better way to model these objects that is simple, flexible, and helps to prevent logic errors in the code that uses it.

The use case with which the solution must be integrated is a simple file selection dialog box. The user selects "Open..." or "Save As..." from the File menu, and the program opens or saves the WidgetDatabase. There will also be "Import..." and "Export..." options for individual Widgets.

When the user selects a file to open or save, wxWidgets will return a file name. The handler that responds to that event must be general purpose code that takes the file name, acquires a serializer, and calls a function to do the heavy lifting. Ideally this design would also work if another piece of code is performing non-file I/O, such as sending a WidgetDatabase to a mobile device over a socket.

Does a widget save to its own format? Does it interoperate with existing formats? Yes! All of the above. Going back to the file dialog, think about Microsoft Word. Microsoft were free to develop the DOCX format however they wanted within certain constraints. At the same time, Word also reads or writes legacy and third-party formats (e.g. PDF). This program is no different: the "binary" format I talk about is a yet-to-be-defined internal format designed for speed. At the same time, it must be able to read and write open standard formats in its domain (irrelevant to the question) so it can be able to work with other software.

Finally, there is only one type of Widget. It will have child objects, but those will be handled by this serialization logic. The program will never load both Widgets and Sprockets. This design only needs to be concerned with Widgets and WidgetDatabases.

答:
I may be wrong, but your design seems to be horribly overengineered. To serialize just one Widget, you want to define WidgetReader, WidgetWriter, WidgetDatabaseReader, WidgetDatabaseWriter interfaces which each have implementations for XML, JSON, and binary encodings, and a factory to tie all those classes together. This is problematic for the following reasons:

If I want to serialize a non-Widget class, let's call it Foo, I have to reimplement this whole Zoo of classes, and create FooReader, FooWriter, FooDatabaseReader, FooDatabaseWriter interfaces, times three for each serialization format, plus a factory to make it even remotely usable. Don't tell me there won't be any copy&paste going on there! This combinatorial explosion seems to be fairly unmaintainable, even if each of those classes essentially only contains a single method.

Widget can't be reasonably encapsulated. Either you open up everything that should be serialized up to the open world with getter methods, or you have to friend each and every WidgetWriter (and probably also all WidgetReader) implementations. In either case, you will introduce considerable coupling between the serialization implementations and the Widget.

The reader/writer zoo invites inconsistencies. Whenever you add a member to Widget, you will have to update all related serialization classes to store/retrieve that member. This is something that can't be statically checked for correctness, so you will also have to write a separate test for each reader and writer. At your current design, that's 4*3=12 tests per class you want to serialize.

In the other direction, adding a new serialization format such as YAML is also problematic. For each class that you want to serialize, you will have to remember to add a YAML reader and writer, and add that case to the enum and to the factory. Again, this is something that can't be statically tested, unless you get (too) clever and draw up a templated interface for factories that's independent of Widget and makes sure an implementation for each serialization type for each in/out operation is provided.

Maybe the Widget now satisfies the SRP since it's not responsible for serialization. But the reader and writer implementations clearly don't, with the “SRP = each object has one reason to change” interpretation: the implementations must change when either the serialization format changes, or when the Widget changes.

If you are able to invest a minimum of time beforehand, please try to draw up a more generic serialization framework than this ad-hoc tangle of classes. For example, you could define a common interchange representation, let's call it SerializationInfo, with a JavaScript-like object model: most objects can be seen as a std::map<std::string, SerializationInfo>, or as a std::vector<SerializationInfo>, or as a primitive such as int.

For each serialization format, you would then have one class that manages reading and writing a serialization representation from that stream. And for each class you want to serialize, you would have some mechanism that converts instances from/to the serialization representation.

I have experienced such a design with cxxtools (homepage, GitHub, serialization demo), and it is mostly extremely intuitive, broadly applicable, and satisfactory for my use cases – the only problems being the fairly weak object model of the serialization representation that requires you to know during deserialization precisely which kind of object you are expecting, and that deserialization implies default-constructible objects that can be initialized later. Here's a contrived usage example:

```<code>class Point {
  int _x;
  int _y;
public:
  Point(x, y) : _x(x), _y(y) {}
  int x() const { return _x; }
  int y() const { return _y; }
};

void operator <<= (SerializationInfo& si, const Point& p) {
  si.addMember("x") <<= p.x();
  si.addMember("y") <<= p.y();
}

void operator >>= (const SerializationInfo& si, Point& p) {
  int x;
  si.getMember("x") >>= x;  // will throw if x entry not found
  int y;
  si.getMember("y") >>= y;
  p = Point(x, y);
}

int main() {
  // cxxtools::Json<T>(T&) wrapper sets up a SerializationInfo and manages Json I/O
  // wrappers for other formats also exist, e.g. cxxtools::Xml<T>(T&)

  Point a(42, -15);
  std::cout << cxxtools::Json(a);
  ...
  Point b(0, 0);
  std::cin >> cxxtools::Json(p);
}
</code>```

I am not saying that you should use cxxtools or exactly copy that design, but in my experience its design makes it trivial to add serialization even for small, one-off classes, provided that you don't care too closely about the serialization format (e.g. the default XML output will use member names as element names, and will never use attributes for your data).

The problem with binary/text mode for streams does not seem solvable, but that isn't so bad. For one thing, it only matters for binary formats, on platforms I don't tend to program for ;-) More seriously, it's a restriction of your serialization infrastructure you'll just have to document and hope everyone uses correctly. Opening the streams within your readers or writers is way too inflexible, and C++ does not have a built-in type-level mechanism to distinguish text from binary data.

Title: C++ serialization design review

Body:
I may be wrong, but your design seems to be horribly overengineered. To serialize just one Widget, you want to define WidgetReader, WidgetWriter, WidgetDatabaseReader, WidgetDatabaseWriter interfaces which each have implementations for XML, JSON, and binary encodings, and a factory to tie all those classes together. This is problematic for the following reasons:

If I want to serialize a non-Widget class, let's call it Foo, I have to reimplement this whole Zoo of classes, and create FooReader, FooWriter, FooDatabaseReader, FooDatabaseWriter interfaces, times three for each serialization format, plus a factory to make it even remotely usable. Don't tell me there won't be any copy&paste going on there! This combinatorial explosion seems to be fairly unmaintainable, even if each of those classes essentially only contains a single method.

Widget can't be reasonably encapsulated. Either you open up everything that should be serialized up to the open world with getter methods, or you have to friend each and every WidgetWriter (and probably also all WidgetReader) implementations. In either case, you will introduce considerable coupling between the serialization implementations and the Widget.

The reader/writer zoo invites inconsistencies. Whenever you add a member to Widget, you will have to update all related serialization classes to store/retrieve that member. This is something that can't be statically checked for correctness, so you will also have to write a separate test for each reader and writer. At your current design, that's 4*3=12 tests per class you want to serialize.

In the other direction, adding a new serialization format such as YAML is also problematic. For each class that you want to serialize, you will have to remember to add a YAML reader and writer, and add that case to the enum and to the factory. Again, this is something that can't be statically tested, unless you get (too) clever and draw up a templated interface for factories that's independent of Widget and makes sure an implementation for each serialization type for each in/out operation is provided.

Maybe the Widget now satisfies the SRP since it's not responsible for serialization. But the reader and writer implementations clearly don't, with the “SRP = each object has one reason to change” interpretation: the implementations must change when either the serialization format changes, or when the Widget changes.

If you are able to invest a minimum of time beforehand, please try to draw up a more generic serialization framework than this ad-hoc tangle of classes. For example, you could define a common interchange representation, let's call it SerializationInfo, with a JavaScript-like object model: most objects can be seen as a std::map<std::string, SerializationInfo>, or as a std::vector<SerializationInfo>, or as a primitive such as int.

For each serialization format, you would then have one class that manages reading and writing a serialization representation from that stream. And for each class you want to serialize, you would have some mechanism that converts instances from/to the serialization representation.

I have experienced such a design with cxxtools (homepage, GitHub, serialization demo), and it is mostly extremely intuitive, broadly applicable, and satisfactory for my use cases – the only problems being the fairly weak object model of the serialization representation that requires you to know during deserialization precisely which kind of object you are expecting, and that deserialization implies default-constructible objects that can be initialized later. Here's a contrived usage example:

class Point {
  int _x;
  int _y;
public:
  Point(x, y) : _x(x), _y(y) {}
  int x() const { return _x; }
  int y() const { return _y; }
};

void operator <<= (SerializationInfo& si, const Point& p) {
  si.addMember("x") <<= p.x();
  si.addMember("y") <<= p.y();
}

void operator >>= (const SerializationInfo& si, Point& p) {
  int x;
  si.getMember("x") >>= x;  // will throw if x entry not found
  int y;
  si.getMember("y") >>= y;
  p = Point(x, y);
}

int main() {
  // cxxtools::Json<T>(T&) wrapper sets up a SerializationInfo and manages Json I/O
  // wrappers for other formats also exist, e.g. cxxtools::Xml<T>(T&)

  Point a(42, -15);
  std::cout << cxxtools::Json(a);
  ...
  Point b(0, 0);
  std::cin >> cxxtools::Json(p);
}

I am not saying that you should use cxxtools or exactly copy that design, but in my experience its design makes it trivial to add serialization even for small, one-off classes, provided that you don't care too closely about the serialization format (e.g. the default XML output will use member names as element names, and will never use attributes for your data).

The problem with binary/text mode for streams does not seem solvable, but that isn't so bad. For one thing, it only matters for binary formats, on platforms I don't tend to program for ;-) More seriously, it's a restriction of your serialization infrastructure you'll just have to document and hope everyone uses correctly. Opening the streams within your readers or writers is way too inflexible, and C++ does not have a built-in type-level mechanism to distinguish text from binary data.


问:
Why doesn't "object reference not set to an instance of an object" tell us which object?
We're launching a system, and we sometimes get the famous exception NullReferenceException with the message Object reference not set to an instance of an object.

However, in a method where we have almost 20 objects, having a log which says an object is null, is really of no use at all. It's like telling you, when you are the security agent of a seminar, that a man among 100 attendees is a terrorist. That's really of no use to you at all. You should get more information, if you want to detect which man is the threatening man.

Likewise, if we want to remove the bug, we do need to know which object is null.

Now, something has obsessed my mind for several months, and that is:

Why doesn't .NET give us the name, or at least the type of the object reference, which is null?. Can't it understand the type from reflection or any other source?

Also, what are the best practices to understand which object is null? Should we always test nullability of objects in these contexts manually and log the result? Is there a better way?

Update:
The exception The system cannot find the file specified has the same nature. You can't find which file, until you attach to the process and debug. I guess these types of exceptions can become more intelligent. Wouldn't it be better if .NET could tell us c:\temp.txt doesn't exist. instead of that general message? As a developer, I vote yes.

答:
If you wanted to go with @stijn's answer and put null checks in your code, this code snippet should help.  Here's some info about code snippets.  Once you have this set up, just type argnull, hit tab twice, and then fill in the blank.

```<code><CodeSnippet Format="1.0.0">
  <Header>
    <Title>EnsureArgNotNull</Title>
    <Shortcut>argnull</Shortcut>
  </Header>
  <Snippet>
    <Declarations>
      <Literal>
        <ID>argument</ID>
        <ToolTip>The name of the argument that shouldn't be null</ToolTip>
        <Default>arg</Default>
      </Literal>
    </Declarations>
    <Code Language="CSharp">
      <![CDATA[if ($argument$ == null) throw new ArgumentNullException("$argument$");$end$]]>
    </Code>
  </Snippet>
</CodeSnippet>
</code>```

ContentLicense: CC BY-SA 3.0

Body:
If you wanted to go with @stijn's answer and put null checks in your code, this code snippet should help.  Here's some info about code snippets.  Once you have this set up, just type argnull, hit tab twice, and then fill in the blank.

<CodeSnippet Format="1.0.0">
  <Header>
    <Title>EnsureArgNotNull</Title>
    <Shortcut>argnull</Shortcut>
  </Header>
  <Snippet>
    <Declarations>
      <Literal>
        <ID>argument</ID>
        <ToolTip>The name of the argument that shouldn't be null</ToolTip>
        <Default>arg</Default>
      </Literal>
    </Declarations>
    <Code Language="CSharp">
      <![CDATA[if ($argument$ == null) throw new ArgumentNullException("$argument$");$end$]]>
    </Code>
  </Snippet>
</CodeSnippet>


答:
Exceptions have been created as a tool to signal exceptional non-fatal conditions up the call chain. That is, they are not designed as a debugging tool.

If a null-pointer exception were a debugging tool, it would abort program execution right on the spot, allowing a debugger to connect, pointing it right at the incriminating line. This would give the programmer all the context information that is available. (Which is pretty much what a Segfault due to a null pointer access does in C, albeit a bit crudely.)

However, the null-pointer exception is designed as a valid runtime condition that can be thrown and caught in normal program flow. Consequently, performance considerations need to be taken into account. And any customization of the exception message requires string objects being created, concatenated, and destroyed at runtime. As such, a static message is undisputably faster.

I'm not saying that the runtime could not be programmed in a way that would yield the name of the incriminating reference, though. That could be done. It would just make exceptions even slower than they are. If anyone cared enough, such a feature could even be made switchable, so that it would not slow down production code, but allow for easier debugging; but for some reason nobody seems to have cared enough.

Title: Why doesn't "object reference not set to an instance of an object" tell us which object?

Body:
We're launching a system, and we sometimes get the famous exception NullReferenceException with the message Object reference not set to an instance of an object.

However, in a method where we have almost 20 objects, having a log which says an object is null, is really of no use at all. It's like telling you, when you are the security agent of a seminar, that a man among 100 attendees is a terrorist. That's really of no use to you at all. You should get more information, if you want to detect which man is the threatening man.

Likewise, if we want to remove the bug, we do need to know which object is null.

Now, something has obsessed my mind for several months, and that is:

Why doesn't .NET give us the name, or at least the type of the object reference, which is null?. Can't it understand the type from reflection or any other source?

Also, what are the best practices to understand which object is null? Should we always test nullability of objects in these contexts manually and log the result? Is there a better way?

Update:
The exception The system cannot find the file specified has the same nature. You can't find which file, until you attach to the process and debug. I guess these types of exceptions can become more intelligent. Wouldn't it be better if .NET could tell us c:\temp.txt doesn't exist. instead of that general message? As a developer, I vote yes.


问:
How important is graceful degradation of JavaScript?
Should web developers continue to spend effort progressively enhancing our web applications with JavaScript, ensuring that features gracefully degrade, thereby ensuring accessibility?  Or should we spend that time focused on new features or other areas of development?

The subtext of that question would be:  How many of our customers/clients/users utilize our websites or applications with JavaScript disabled?  Do you have any projects with requirements that specifically demand JavaScript functionality (almost all of mine do), and do those requirements also demand graceful degradation?

For the sake of asking this question, I pulled up programmers.stackexchange.com without JavaScript enabled, and I was greeted with this message: "Programmers - Stack Exchange works best with JavaScript enabled".  It was difficult to log in, albeit the site seemed to generally work okay.  (I wasn't able to vote up any questions.)

I think this is a satisfactory approach to development.  Imagine the effort involved in making all of the site's features work with plain old HTML and server-side logic. On the other hand, I wonder how many users have been alienated by this approach.

We've all been trained (at least the good developers among us) to use progressive enhancement and to ensure our web applications' dynamic features degrade gracefully.  Is this progressive enhancement just pissing into the wind, or do some of our customers actually utilize certain web services without JavaScript enabled?

答:
Rather than focusing on making sure an entire page degrades gracefully, I try to make sure about 75% (or more, if it's easily or quickly done) of the page gracefully degrades (or works sans JavaScript). I also try to make sure this 75% completes a whole part of the page's functionality.

For example, I use JavaScript to load comments for posts on my blog; It gave me flexibility, consistency in comment rendering, and it helps me maintain a self-imposed single query/request limit. However, the main reason why you're going to my blog - reading posts - remains server-generated and will work with any browser. Comments are completely self-contained in a clean .js file.

TL;DR The key here is what degrades gracefully, not how much degrades gracefully.

ContentLicense: CC BY-SA 2.5


问:
When to use absolute path?
I had given an answer on SO, the question was concerning a problem with a relative path.  My answer was to use an absolute path, which I thought seemed simpler.  The asker claimed to need a relative path, but I couldn't tell why.

It seems reasonable that if you know to go to ../../../foo/bar/, then you would also know to go to /home/willie/foo/bar/.

I can't think of a situation which requires relative paths except in a build script.  Are there others I'm not thinking of?  Is it bad practice to use one or the other in any situation?

Sorry if this question is off topic, all my googling yielded was how to use them rather than why.

答:
I can't think of a situation which requires relative paths

A possible reason to use relative path would be to use paths related to the location of the executable (and not to the current work directory); e.g. if your executable sits in /home/will/bin/foo you would use /home/will/bin/../data/resource (which is /home/will/data/resource) for some resource files. See this answer for details.

Then, you could ship a file tree (e.g. a .tar archive) containing the executable (with some relative paths like bin/foo for the executable and data/resource for resources used by it), your user would install it at any place he likes (e.g. under /home/will/, or /home/joe/soft/ or /opt/ ...) and be able to run the executables and access resources.

This practice is not very common (IIRC, xemacs used it), because most systems have conventions about files, like the Filesystem Hierarchy Standard & hier(7) and software gets installed (e.g. by some make install step) there.

Title: When to use absolute path?


问:
OPTION STRICT set to off
I am working on an application with over one million lines of code.  OPTION STRICT is set to off!.

I want to set it to ON during the next work iteration.  I believe the only reason OPTION STRICT should be OFF is when converting a legacy system e.g. VB6 to .NET.  You should then set OPTION STRICT to ON ASAP.

Am I right in this thought or do developers leave OPTION STRICT to OFF permanently? Is there any guidance.  I have looked here: http://msdn.microsoft.com/en-us/library/zcd4xwzs.aspx, but I cannot find an answer to my specific question.

答:
It is a real pity Microsoft defaults to Option Strict Off, although I sort of understand from their point of view.

Yes, for any professional coding you ought to use Option Strict On, and only turn it off in files that need to use late-binding on Object.

Nevertheless, once you have a large project where you want to turn Option Strict On you run into the problem that, in the IDE, Microsoft limits to reporting 100 errors or warnings. For recent versions they've removed that limit from the command line compiler so you can know how big your task is to fix the missing casts.

A quirk I have noticed when adding casts is that the error messages are sometimes "better" from the "simple" Option Strict Off automatic conversion failures than those returned by explicit casts.

Title: OPTION STRICT set to off


问:
"Do you have any questions for us?" In an interview
You know the prospective company fairly well but are asked "Do you have any questions for us?".  To show interest, what are some of your favorite questions to reply?</p>

答:
I ask about the build/deploy process. I also make it a point to ask the tech guy. This gives me many insights into the company culture and the developer skill level and maturity. Stuff that tells the tale:

Is every step automated?

Do they write tests?

What tools do they use?

Heck, do they even use source control?

How often they deploy to production? That's the best way to tell if somebody claiming to be oh-so-agile really is.

How do they fix bugs and push fixes to production?

I draw tons of conclusions from answers to the above. And I love it how everybody shares as many juicy details as possible since, superficially, that looks like a tech question to ask.


问:
Android Pass Data between fragments
I have a question about passing data using bundle between fragments. I need to pass the URL from a Product object to the next fragment, so I don't know which is the best approach: to pass only the URL or the whole object? What are the reasons of choosing one over another?

```<code>Bundle bundle = new Bundle();
bundle.putString(PRODUCT_KEY, product.toJson());
</code>```

or

```<code>Bundle bundle = new Bundle();
bundle.putString(PRODUCT_KEY, product.getUrl);
</code>```

答:
If you need to pass only the URL, then pass only the URL. No need to over think it.

There are several disadvantages of passing the whole object:

the performance cost of json serialization and deserialization

weaker encapsulation and weaker information hiding: the source fragment reveals more information to the other than necessary

If you only need to pass one field of many, then most certainly it's best to pass just the one field.

If you need to pass a few fields of many, then it's probably still better to pass only the needed fields, for the above reasons.

If you need to pass two product fields out of three, then it might be acceptable to pass the entire product.

OwnerDisplayName: Laura

Title: Android Pass Data between fragments

OwnerDisplayName: janos


问:
In what programming language did the use of the percent sign (%) to mean modulo/remainder originate?
In what programming language did the use of the percent sign (%) to mean modulo/remainder originate?

This previous post1 explains that the symbol % was likely chosen because it includes a slash, clever for an operation related to division. It also mentions the influence of C's use of the symbol. However, I'm not certain that it originated in C. The B programming language was a precursor to C, and I've found a User's guide for B (PDF, page 12) that states:

The operator % denotes modulo. If both operands are positive, the result is correct. It is undefined otherwise.

That user's guide is dated 1972 though, approximately when C appeared. That makes it still theoretically possible to have originated in C, but then back-ported to B. I've also not yet been able to find specifications for other languages prior to this indicating use of the % symbol.

To which I believe this question is not a duplicate: That one asks why the modulo operation is fundamental, I'm asking about when the symbol in particular appeared to mean modulo.

答:
The earliest reference I can find is from the "B" programming language developed by Ken Thompson with Dennis Ritchie around 1969.
B Reference

As this was an implementation/improvement of BPCL I have to assume the operator was part of BPCL but I cannot find a specific reference for this.


问:
What is the most efficient way to discover devices on a network?
I've been programming a C web server from scratch as an interface for controlling ESP8266 WiFi modules that I plan to use to control appliances & lighting with relays. In an attempt to make a user-friendly interface, I hope to implement auto-device discovery in an attempt to make the experience more seamless. In what way should I approach this? Here is my initial concept:

WiFi module connects to your network.

Have it host a UDP server that will wait for packets on port X.

Have main server use subnet mask to send a UDP packet to all IP addresses on port X containing a packet of data saying "Hey, I'm the main server!"

The WiFi module will acknowledge this by sending an HTTP POST request to the main server saying "Hey, I'm a device with ID Y! Add me to your list!"

At this point, WiFi module stops listening for UDP packets.

Module sets up TCP server to listen for commands. Commands between main server and devices will happen over TCP.

Is there any flaws in my plan? What about IPv6 (if those devices even support it)?

答: There are existing protocols for performing discovery of devices; it would be better to use one of these than roll your own. The leading competitors are mDNS  (aka Bonjour) and SSDP (aka Universal Plug and Play). I'd suggest reading up on these, and then picking up one of the many open source implementations to start working from.</p>


问:
Good practice for holding immutable data
I'm wondering what is the best practice for holding immutable data, more specifically in C#.

For instance, lets say I have an immutable object called Foo.

```<code>public sealed class Foo {
    public int Bar { get; }

    public Foo(int bar) {
        Bar = bar;
    }
}
</code>```

Currently, I have been holding these objects in a static class like so.

```<code>public static class FooList {
    private static List<Foo> fooList;

    static Foo {
        fooList = new List<Foo>();
        fooList.Add(new Foo(1));
        fooList.Add(new Foo(2));
    }

    public static Foo GetFoo(int index) {
        if (index >= 0 && index < fooList.Count) {
            return fooList[index];
        }

        // I don't know if this is right, but besides the point
        throw;
    }
}
</code>```

From there, any class can have their own reference to a Foo object by calling GetFoo(int). However, I have been reading up lately that static classes should be avoided due to them being hard to maintain (I don't know the specific reason, but I would assume it is because they can't be instantiated).

If this is the case, what would be the best practice for holding immutable data in this situation? I am aware of the Singleton Pattern, but I don't know if this is the best practice for this situation.

答:
The problem is that you've effectively created a global variable for accessing these objects, the Foolist class. This has drawbacks for things like testability and is in general just poor design.

Global state doesn't help make code easy to read and the consuming classes can never be isolated from the Foos (look up mocking) d when testing.

Avoid the static and pass either the foos or foolists around as instance variables.


答:
Fundamentally, there's no problem described in the question that actually needs a solution. You've given no reason for a Foo holder to exist, or what it should be able to do. So really, FooList is completely useless.

If you need a Foo, there's a language feature for that- new Foo(1). There's no reason for any additional holding to be baked in to the Foo class.

Edit: You can use a really simple non-static cache and simply pass around the cache.

```<code>public class FooCache {
    private Dictionary<int, Foo> cache = new Dictionary<int, Foo>();
    public FooCache() {}
    public Foo GetFoo(int i) {
        if (!cache.ContainsKey(i))
            cache[i] = new Foo(i);
        return cache[i];
    }
}
</code>```

This more directly holds the Foo objects that you actually want, instead of newing up a pre-set list and then just hoping that they're correct, it's a lot more transparent, you can still use new Foo if you need to, and you can have several instances of it if you want to (e.g. unit tests).

Title: Good practice for holding immutable data

Body:
I'm wondering what is the best practice for holding immutable data, more specifically in C#.

For instance, lets say I have an immutable object called Foo.

```<code>public sealed class Foo {
    public int Bar { get; }

    public Foo(int bar) {
        Bar = bar;
    }
}
</code>```

Currently, I have been holding these objects in a static class like so.

```<code>public static class FooList {
    private static List<Foo> fooList;

    static Foo {
        fooList = new List<Foo>();
        fooList.Add(new Foo(1));
        fooList.Add(new Foo(2));
    }

    public static Foo GetFoo(int index) {
        if (index >= 0 && index < fooList.Count) {
            return fooList[index];
        }

        // I don't know if this is right, but besides the point
        throw;
    }
}
</code>```

From there, any class can have their own reference to a Foo object by calling GetFoo(int). However, I have been reading up lately that static classes should be avoided due to them being hard to maintain (I don't know the specific reason, but I would assume it is because they can't be instantiated).

If this is the case, what would be the best practice for holding immutable data in this situation? I am aware of the Singleton Pattern, but I don't know if this is the best practice for this situation.

Body:
Fundamentally, there's no problem described in the question that actually needs a solution. You've given no reason for a Foo holder to exist, or what it should be able to do. So really, FooList is completely useless.

If you need a Foo, there's a language feature for that- new Foo(1). There's no reason for any additional holding to be baked in to the Foo class.

Edit: You can use a really simple non-static cache and simply pass around the cache.

public class FooCache {
    private Dictionary<int, Foo> cache = new Dictionary<int, Foo>();
    public FooCache() {}
    public Foo GetFoo(int i) {
        if (!cache.ContainsKey(i))
            cache[i] = new Foo(i);
        return cache[i];
    }
}

This more directly holds the Foo objects that you actually want, instead of newing up a pre-set list and then just hoping that they're correct, it's a lot more transparent, you can still use new Foo if you need to, and you can have several instances of it if you want to (e.g. unit tests).


答:
(This entry is a wiki. Please feel free to improve this answer)

Here is argumented how using static for immutable might be preferable, and related concepts.

Constants themselves are defined as global. Objects that wont change not only during runtime, but wont have alternatives values (like a filesystem path might change depending configuration) a priori will be just as good to be defined as static.

These would be instances on indexed values that would not change between executions:

A Cache of precomputed values (e.g. like some graphic engines hold trigonometric tables , especially in early 90's when there was no floating point in processor).

Like a FlyWeight pattern, where we would be attempting to save memory using canonical instances rather than having many objects with the same value. For example if we load "Smith" surname 10,000 times, we might either keep in memory that value 10,000 times, or keep the first instance in a dictionary, and reference that same canonical instance for every posterior duplicate.

There is ongoing debate about static values being something to avoid (as in this popular question in Stack Overflow about the Singleton Pattern)

The alternative would be to create an instance that encapsulates all this values (and therefore passing that context as a parameter to any method that needs it).

In Test Driven Development that would allow to use custom instances for testing. However, as we talk of immutable data, that might either be an "universal constant", or some custom data that might be loaded as easily from an alternative configuration file.

That passing the context as a parameter, might end up in awkward situations, where one or many huge context/component objects are passed along methods, without being very clear what is their use (an extreme case of Stamp Coupling). Expressed a bit poignantly:

I have seen several developers go to extraordinary lengths to avoid a global because they considered using one as an admission of failure..


问:
set author name for a forked and changed source code
Here is the Makefile I found on the internet for using rf24 on raspberrypi:

```<code>#############################################################################
#
# Makefile for librf24 examples on Raspberry Pi
#
# License: GPL (General Public License)
# Author:  gnulnulf <arco@appeltaart.mine.nu>
# Date:    2013/02/07 (version 1.0)
#
# Description:
# ------------
# use make all and make install to install the examples
# You can change the install directory by editing the prefix line
#
prefix := /usr/local

# The recommended compiler flags for the Raspberry Pi
CCFLAGS=-Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s
#CCFLAGS=

# define all programs
PROGRAMS = rpi-hub scanner

SOURCES = ${PROGRAMS:=.cpp}

all: ${PROGRAMS}

${PROGRAMS}: ${SOURCES}
g++ ${CCFLAGS} -Wall -I../ -lrf24-bcm $@.cpp -o $@

clean:
    rm -rf $(PROGRAMS)

install: all
    test -d $(prefix) || mkdir $(prefix)
    test -d $(prefix)/bin || mkdir $(prefix)/bin
    for prog in $(PROGRAMS); do \
      install -m 0755 $$prog $(prefix)/bin; \
    done

.PHONY: install
</code>```

but this make file is not working with raspberrypi 2, and I want to write a code for raspberry pi 2 and find this make file useful, so I changed compiler flag in line 17 from -march=armv6zk to -march=armv7-a to work with raspberrypi 2.

now if I want to publish this code on GitHub, should I change author`s name to my name or I should keep author`s name or something else?

答: You can add your name to the actual author's name as a contributor for files you've made code changes to. For anything you didn't change, you aren't the author - you would be taking credit for somebody else's work if you change the author's name to your own. If an employer or potential contributor sees that, it will raise some big questions about your ethics.</p>


答:
The benefit of immutability is that it doesn't matter as much what you do with your references to it.  Globals, static classes, and singletons are much less problematic than their mutable counterparts, because you don't have to synchronize mutations and track the order dependencies that creates.  However, they still have the issues with mocking out for unit testing.

On the other end of the spectrum, you can have as many references as you want, or even outright copies.  This is because you don't have to worry about propagating any changes to the other copies, since there are no changes.  This is the hardest part for people to get used to, if they are accustomed to mutability, but is usually the easiest to maintain, and retains the benefits for mocking in unit tests.


问:
Should I separate the interface or use single one
I'm developing a game, I will generate objects. I have create an interface called IObject which has the following properties:

```<code>String tag // Tag for the object
Vector3 position // Where the element is positioned
Mesh mesh // This is how the object looks like
Material material // The material from which the object is build
void draw() // Method which draw the object
</code>```

Now I wonder which will be better design practice to create another interface which takes all the things associated with drawing (position, mesh, material and the draw method) or to leave it this way?

答:
Definitely take the stuff that relates to drawing out. Something like Drawable or Sprite or anything which clarifies the specific intended purpose of the object would be better

Interfaces are useful because they establish a specific contract regarding what you expect an object to provide; they should only include as much functionality as they need to for a specific range of use cases. Remember, objects can implement multiple interfaces; you don't have to have one giant interface which defines everything you could ever need in all cases, because that will get bloated and harder to mock for testing purposes. Single responsibility is your friend!


问:
Can 32/64 bit version of Dart SDK have any effect on produced javascript code?
I just started collaborating remotely on a project. Project manager explicitly asked me to download Dart SDK 32bit version. Since I have 64bit machine I asked why to find out more about it. I was told that "we're compiling the Dart code into Javascript that will then run within website/webapp. Therefore," he said " we need to avoid compatibility issues with 32bit machines visiting our site."

I've been programming javascript for 8 years. I never came across any web javascript API that would come near problems such as 32/64bit. So what am I missing? How can SDK bit version affect produced .js code? I decided to ask here before I raise any argument, especially since it's not really important whether I use 32/64 bit in this case.

答:
I would have to agree with you that generating javascript ought to be the same whether from the 32-bit or 64-bit SDK.  Further, I fail to see the project manager's concern about 32-bit clients visiting your site.

However, it is conceivable that despite all intentions to the contrary, the 32-bit and 64-bit software (SDK) behave differently (i.e. one has a bug that the other one doesn't have).

I am a big fan of having a well-known and documented baseline of tools for a project, of having reproducible results across development machines.  In fact, in some organizations I've been part of compare the output of development (e.g. binaries) to make sure that the software being released is the same as that being (source) archived and is the same as what was actually tested.  I've seen more than a few bugs caught by being that methodical (mostly bugs in the build system where clean didn't fully clean, so old binary stuff was unknowingly being used instead of recompiled).

So, in general, I'd be in favor of settling on which SDK to use in advance, and everyone using the identical SDK.


问:
Best Practices: URL Path Parameters
What's the current best practice around path parameters in URLs?

For instance

/artist/name

A long time ago I might have made artist.html and then passed in a query parameter /artist.html?name=name but it seems path parameters are the standard (and nicer to look at).

So assume I'm using apache, nginx, etc.  Are these just rewritting /artist/name to '/artist.html?name=name` and then the Javascript is reading the query parameters? How is this done in the static html / ajax world we live in?

Thanks

答:
While that's probably how it used to be before (and I do remember writing stuff like that myself), modern websites tend to use web frameworks such as Flask or Django or Ruby on Rails instead of static pages and rewrites.

These frameworks include URL routing, where a certain pattern in the path, for example /artist/<name>, can be mapped to a function getArtist(name).

The query string may then be read by either the backend program or some JavaScript in the page.

Title: Best Practices: URL Path Parameters


问:
Where to put the Country Table?
It might sounds like a silly question but here is my problem.

We have 100s of databases and in each of those databases, there is a country table. It was ok this way but we ran into minor problems at some point like : the different tables were using different country code (2 letters, 3 letters), some country code were incorrects for some reason or some database were lagging behind (yes country change name so you need to update your database).

So, at some point, we decided to put only one country table in a "reference" database. This way the country table would always be up to date and it would be the same for everyone. Anyway, all those country tables were exactly the same right?

The only issue now is that each database is used by a different application and each application has some logic related to the countries. For example, if the country is XXX do that and the way we did it before was by adding a column in the country table "is_XXX". Since we decided to combine the country table, we would now have 100s of columns "is_XXX" in the new country table and each of these columns is most likely only useful to 1 specific application.

So, should we have 1 country table referenced by everything else or 1 country table per database?

答:
The answer may be simpler than you might have originally thought: replace the "Countries" table shared across monolithic database-centric apps with a microservice, or simple webservice that exposes the same functionality with a simple REST call (note: I'm suggesting REST though that is not your only option, though it is probably the lightest-weight option).

Your country example is a perfect opportunity to pull some of the "database" centric logic of your applications out into a simple pattern of a webservice.  I think your gut reaction to having the same table exist in each schema correctly throws off the DRY alert - you're literally repeating yourself not only in terms of the data schema, creation, maintenance etc of the data layer (as small as it may be) but also in terms of the data access logic as well.

There are some significant advantages of this approach and a few disadvantages as well to consider before making your final decision.

Disadvantages:

Microservices and Maintenance: Obviously maintaining the production and staging implementations of a service-based system is going to be different and more than likely more costly at first than what your team is already familiar with in terms of database-centric solutions.  Plus there's the whole "versioning" bit:

Once a microservice makes an endpoint public, subsequent development must pay the cost of either supporting multiple versions of services or the deployment of services in sync. Microservices, in this sense, increase the maintenance cost of a software system by increasing the number of published API endpoints.

The above article also correctly points out that this specific approach may introduce the complexity of advanced distributed systems to your applications where none perviously existed.

You also will need to introduce support for some additional assumptions of network connectivity into your applications that may only have a limited built-in assumption of client-server (app + database) in their current incarnations.  This also presumes management of time synchronization at some level, at least with respect to deploying changes and supporting multiple versions for backwards compatibility.

Performance is also another concern.  Although in general smaller microservices can be more easily optimized, the mechanism they employ for delivering their data via web services is different than the mechanisms you currently use for your client server apps and require a different skill set and set of techniques to optimize. It can be done, but it may increase the complexity or delivery time at least on your first iteration.

Advantages:

Microservices are here to stay.  Monoliths aren't exactly going anywhere, but the trend is towards smaller monoliths not larger ones.  You might as well start somewhere easy both for the developers to learn and also for the business to assume the least risk with the easiest rewards.

Decomposing into Microservices make the app easier to Test and maintain over time, even if complexity increases.  That complexity is easier to manage via automation than the monoliths are - it's a tradeoff. You have to master automation, but there are so many benefits to that process that it hardly seems like a negative at this point.

Speaking of automation, deployments become more easy as well.  So does maintaining multiple synchronized environments and dev / test / staging environments that are exact replicas of production.  The added benefit of not having to deal with "it works on my system" type of issue is one nice extra but so is the entire DevOps culture that you can begin developing in and around your system now.  Even Martin Fowler agrees!

I also agree with this post that suggests that the microservice approach more closely aligns with both business objectives and capabilities as well as reducing redundancy at the expense of a little more complexity.  Keep in mind that build, testing, and deployments will tend to occur more quickly with this model and the efficiencies will likely begin to pay for the extra complexity introduced in no time at all.

As the number of microservices grows so does the overall complexity and management costs of your app.  This is undoubtedly true, but it is actually a perfectly good justification for starting out with a single microservice, mastering the skills needed to develop, integrate, and maintain one in your stack and then expanding from there as opposed to a true reason to reject the approach.

Title: Where to put the Country Table?


问:
DRY principle in good practices?
I am trying to follow the DRY principle in my programming as hard as I can. Recently I have been learning design patterns in OOP and I have ended up repeating myself quite a bunch.

I have created a Repository pattern along with a Factory and Gateway patterns to handle my persistence. I'm using a database in my application but that shouldn't matter since I should be able to swap out the Gateway and switch to another kind of persistence if I wished.

The problem I've ended up creating for myself is that I create the same objects for the number of tables I have. For example these will be the objects I need to handle a table comments.

```<code>class Comment extends Model {

    protected $id;
    protected $author;
    protected $text;
    protected $date;
}

class CommentFactory implements iFactory {

    public function createFrom(array $data) {
        return new Comment($data);
    }
}

class CommentGateway implements iGateway {

    protected $db;

    public function __construct(\Database $db) {
        $this->db = $db;
    }

    public function persist($data) {

        if(isset($data['id'])) {
            $sql = 'UPDATE comments SET author = ?, text = ?, date = ? WHERE id = ?';
            $this->db->prepare($sql)->execute($data['author'], $data['text'], $data['date'], $data['id']);
        } else {
            $sql = 'INSERT INTO comments (author, text, date) VALUES (?, ?, ?)';
            $this->db->prepare($sql)->execute($data['author'], $data['text'], $data['date']);
        }
    }

    public function retrieve($id) {

        $sql = 'SELECT * FROM comments WHERE id = ?';
        return $this->db->prepare($sql)->execute($id)->fetch();
    }

    public function delete($id) {

        $sql = 'DELETE FROM comments WHERE id = ?';
        return $this->db->prepare($sql)->execute($id)->fetch();
    }
}

class CommentRepository {

    protected $gateway;
    protected $factory;

    public function __construct(iFactory $f, iGateway $g) {
        $this->gateway = $g;
        $this->factory = $f;
    }

    public function get($id) {

        $data = $this->gateway->retrieve($id);
        return $this->factory->createFrom($data);
    }

    public function add(Comment $comment) {

        $data = $comment->toArray();
        return $this->gateway->persist($data);
    }
}
</code>```

Then my controller looks like

```<code>class Comment {

    public function view($id) {

        $gateway = new CommentGateway(Database::connection());
        $factory = new CommentFactory();
        $repo = new CommentRepository($factory, $gateway);

        return Response::view('comment/view', $repo->get($id));
    }
}
</code>```

So I thought I was using design patterns correctly and keeping good practices, but the problem with this thing is that when I add a new table, I have to create the same classes just with other names. This raises suspicion in me that I may be doing something wrong.

I thought of a solution where instead of interfaces I had abstract classes which using the class name figure out the table they need to manipulate but that doesn't seem like the right thing to do, what if I decide to switch to a file storage or memcache where there are no tables.

Am I approaching this correctly, or is there a different perspective I should be looking at?

答:
The problem you facing is an old one: code for persistent objects often looks similar for each class, it is simply boilerplate code. That's why some smart people invented Object Relational Mappers - they solve exactly that problem. See this former SO post for a list of ORMs for PHP.

When existing ORMs do not suffer your needs, there is also an alternative: you can write your own code generator, which takes a meta description of your objects to persist and generates the repeating part of the code from that. That is actually not too hard, I did this in the past for some different programming languages, I am sure it will be also possible to implement such things also in PHP.

Title: DRY principle in good practices?


答:
Both

Have a central controlled table with:

ID int PK

Code varchar

Then let app have table with:

ID  PK FK to central

add as many flag columns as they want

This way you still have one column for Code

Another option is an app table

CountryID

FlagID

Value

This way your columns become rows

Problem you have here is rewrite a lot of queries

Title: Where to put the Country Table?

Body:
It might sounds like a silly question but here is my problem.

We have 100s of databases and in each of those databases, there is a country table. It was ok this way but we ran into minor problems at some point like : the different tables were using different country code (2 letters, 3 letters), some country code were incorrects for some reason or some database were lagging behind (yes country change name so you need to update your database).

So, at some point, we decided to put only one country table in a "reference" database. This way the country table would always be up to date and it would be the same for everyone. Anyway, all those country tables were exactly the same right?

The only issue now is that each database is used by a different application and each application has some logic related to the countries. For example, if the country is XXX do that and the way we did it before was by adding a column in the country table "is_XXX". Since we decided to combine the country table, we would now have 100s of columns "is_XXX" in the new country table and each of these columns is most likely only useful to 1 specific application.

So, should we have 1 country table referenced by everything else or 1 country table per database?


问:
How to explain why multi-threading is difficult
I am a fairly good programmer, my boss is also a fairly good programmer. Though he seems to underestimate some tasks such as multi-threading and how difficult it can be (I find it very difficult for anything more than running a few threads, waiting for all to finish, then return results).

The moment you start having to worry about deadlocks and race conditions, I find it very difficult, but the boss doesn't seem to appreciate this - I don't think he has ever come across this. Just slap a lock on it is pretty much the attitude.

So how can I introduce him, or explain why he might be underestimating the complexities of concurrency, parallelism, and multi-threading? Or maybe I am wrong?

Edit: Just a bit on what he has done - loop through a list, for each item in that list create a thread that executes a database update command based on the information in that item. I'm not sure how he controlled how many threads executed at once, I guess he must have added them to a queue if there were too many running (he wouldn't have used a semaphore).

答:
Short answer in two words: OBSERVABLE NONDETERMINISM

Long answer:
It depends on which approach to concurrent programming you use given your problem. In the book Concepts, Techniques, and Models of Computer Programming, authors clearly explain four main practical approaches to writing concurrent programs:

Sequential programming: a baseline approach that has no concurrency;

Declarative concurrency: usable when there is no observable nondeterminism;

Message-passing concurrency: concurrent message passing between lots of entities, where each entity internally process the message sequentially;

Shared state concurrency: thread updating shared passive objects by means of coarse grained atomic actions, e.g. locks, monitors and transactions;

Now the easiest of these four approaches apart from obvious sequential programming is declarative concurrency, because the programs written using this approach have no observable nondeterminism. In other words, there are no race conditions, as race condition is just an observable nondeterministic behaviour.

But the lack of observable nondeterminism means, that there are some problems we can not tackle using declarative concurrency. Here is where the last two not so easy approaches come into play. The not so easy part is a consequence of observable nondeterminism. Now they both fall under stateful concurrent model and are also equivalent in expressiveness. But because of the ever increasing number of cores per CPU, it seems the industry has taken more interest recently in message passing concurrency, as can be seen in the rise of message passing libraries (e.g. Akka for JVM) or programming languages (e.g. Erlang).

The previously mentioned Akka library, which is backed by a theoretical Actor model simplifies building concurrent applications, as you don't have to deal any more with locks, monitors or transactions. On the other hand it requires different approach to designing solution, i.e. thinking in a way of how to hierarchically composite actors. One could say that it requires a totally different mindset, which again can be in the end even harder than using plain state shared concurrency.

Concurrent programming is hard because of observable nondeterminism, but when using the right approach for the given problem and the right library that supports that approach, then a lot of issues can be avoided.


答:
The problem you are addressing is quite fundamental.

I have experienced the same problem when I worked for a company that
made a large J2EE application that consisted of several hundred web pages and over a million and a half lines of Java code. This code used ORM (JPA) for persistence.

This problem get worse when you use 3rd party technologies in every layer of the architecture and the technologies all require their own data representation.

Your problem can not be solved at the level of the programming language you are using. Using patterns is good but as you see it cause repetition of code (ore more accurately put: repetition of designs).

The way I see it there are only 3 possible solutions. In practice these solutions come down to the same.

Solution 1: Use some other persistence framework that allows you to state only what must be persisted. There is probably such a framework around. The problem with this approach is that it is rather naive because not all you patterns will be persistence related. You wil also want to use patterns for user interface code so you'd then need a GUI framework that can re-use the data representations of the persistence framework you choose. If you can not re-use them you'll need to write boiler plate code to bridge the data representations of the GUI framework and the persistence framework.. and this is contrary to the DRY principle again.

Solution 2: Use another - more powerful - programming language that has constructs that allow you to express the repetitive design so you can re-use the design-code. This is probably not an option for you but suppose for a moment it is. Then again when you start creating a user interface on top of the persistence layer you'll want the language again to be powerful enough to support creating the GUI without having to write boiler plate code. It is unlikely that there is a language powerful enough to do what you want since most languages rely on 3rd party frameworks for GUI building that each require their own data representation to work.

Solution 3: Automate the repetition of code and design using some form of code generation. Your worry is about having to hand-code repetitions of patterns and designs since hand-coding repetitive code/design violate the DRY principle.
Nowadays there are very powerful code generator frameworks out there. There are even "language workbenches" that allow you to quickly (half a day when you have no experience) create your own programming language and generate any code (PHP/Java/SQL - any thinkable text file) using that language. I have experience with XText but MetaEdit and MPS seem to be fine as well. I strongly advice you
to check one of these language workbenches out. To me it was the most liberating experience in my professional life.

Using Xtext you can have your machine generate the repetitive code.
Xtext even generates a syntax highlighting editor for you with code completion for your own language specification. From that point you simply take your gateway and factory class and turn them into code templates by punching holes in them.
You feed them to your generator (which is called by a parser of your language that is also completely generated by Xtext) and the generator will fill in the holes in your templates. The result is generated code. From that point on you can take out any repetition of code anywhere (GUI code persistence code etc).

Title: DRY principle in good practices?

Body:
I am trying to follow the DRY principle in my programming as hard as I can. Recently I have been learning design patterns in OOP and I have ended up repeating myself quite a bunch.

I have created a Repository pattern along with a Factory and Gateway patterns to handle my persistence. I'm using a database in my application but that shouldn't matter since I should be able to swap out the Gateway and switch to another kind of persistence if I wished.

The problem I've ended up creating for myself is that I create the same objects for the number of tables I have. For example these will be the objects I need to handle a table comments.

```<code>class Comment extends Model {

    protected $id;
    protected $author;
    protected $text;
    protected $date;
}

class CommentFactory implements iFactory {

    public function createFrom(array $data) {
        return new Comment($data);
    }
}

class CommentGateway implements iGateway {

    protected $db;

    public function __construct(\Database $db) {
        $this->db = $db;
    }

    public function persist($data) {

        if(isset($data['id'])) {
            $sql = 'UPDATE comments SET author = ?, text = ?, date = ? WHERE id = ?';
            $this->db->prepare($sql)->execute($data['author'], $data['text'], $data['date'], $data['id']);
        } else {
            $sql = 'INSERT INTO comments (author, text, date) VALUES (?, ?, ?)';
            $this->db->prepare($sql)->execute($data['author'], $data['text'], $data['date']);
        }
    }

    public function retrieve($id) {

        $sql = 'SELECT * FROM comments WHERE id = ?';
        return $this->db->prepare($sql)->execute($id)->fetch();
    }

    public function delete($id) {

        $sql = 'DELETE FROM comments WHERE id = ?';
        return $this->db->prepare($sql)->execute($id)->fetch();
    }
}

class CommentRepository {

    protected $gateway;
    protected $factory;

    public function __construct(iFactory $f, iGateway $g) {
        $this->gateway = $g;
        $this->factory = $f;
    }

    public function get($id) {

        $data = $this->gateway->retrieve($id);
        return $this->factory->createFrom($data);
    }

    public function add(Comment $comment) {

        $data = $comment->toArray();
        return $this->gateway->persist($data);
    }
}
</code>```

Then my controller looks like

```<code>class Comment {

    public function view($id) {

        $gateway = new CommentGateway(Database::connection());
        $factory = new CommentFactory();
        $repo = new CommentRepository($factory, $gateway);

        return Response::view('comment/view', $repo->get($id));
    }
}
</code>```

So I thought I was using design patterns correctly and keeping good practices, but the problem with this thing is that when I add a new table, I have to create the same classes just with other names. This raises suspicion in me that I may be doing something wrong.

I thought of a solution where instead of interfaces I had abstract classes which using the class name figure out the table they need to manipulate but that doesn't seem like the right thing to do, what if I decide to switch to a file storage or memcache where there are no tables.

Am I approaching this correctly, or is there a different perspective I should be looking at?


问:
Abstracton layer to control services access to denormalized db entity
Our db is optimized for minimum join count (partially denormalized). E.g. our User entity contains account data (nickname, facebook id, etc), user numerical statistics (total games played, total wins, etc), guild related user information (guild id, membership type, etc) and so on - everything in the same table.

We use ORM - NHibernate. The user table is mapped (with all the fields) to User class.

Now I'm refactoring a model class AccountManagementService that provides a possibility to do some actions on an enclosed User. The model has the two dependencies: NHibernate and the User entity. The model logic is strictly tied to ORM methods (performs selects, does updates).

I think it's bad that the model knows about so many fields which it's not going to use. It doesn't need User.GuildId, statistics, etc. But since the model already should use ORM it's logical that it should know about entity classes.

I'm also worried that some operations with User should be done only through special services but other services theoretically can access and change any of the User's fields. E.g. AccountManagementService should not change User.Money directly but use UserMoneyService instead. But from a compiler viewpoint such change is perfectly valid.

Should I introduce other abstraction layers between services and entities to control an access and how can I do it? Can you see any other possibilities to improve the situation?

答: Your problem sounds like it is caused by a failure to follow the Interface Segregation Principle. Fortunately, there's a fairly simple solution: take your entity objects and create one interface in each for each type of client, containing only the methods that make sense for that client. Then, for each client, create a wrapper for your ORM that works using the appropriate interfaces for that client rather than the concrete entity classes. Finally, to combat the anaemic domain model problem identified above, you can start refactoring by moving methods that operate on entity interfaces from the client services into the entity itself.</p>


问:
Using self.method vs the scope :method DSL
According to the Thoughbot Rails Style Guide, we should

Use def self.method, not the scope :method DSL.

My question is: is this simply for the sake of choosing one of these styles and sticking with it for consistency, or is there another reason I'm missing?

Regardless of whether or not you would adhere to this style guide, I was just curious.

答:
I'm currently working on a big project with 6 developers. We have a lot of models and I noticed that if you have like 5 or 6 scopes things start to look cluttered. If we are using the self. syntax things look a lot cleaner then a lambda.

So I guess 2 things:
- looks cleaner
- consistency (like you said)

Note that this post is solely based on personal experience. I could be wrong. :)


问:
Is web sockets the best solution for my problem?
I have created a Slackbot that integrates with Submittable.com. For example, I can trigger a response that displays all current submissions in Slack.

I now need my Slackbot to post in Slack whenever there are any changes or new submissions on Submittable.com.

Do I need to open a web-socket that is always listening to Submittable.com, and is ready to emit events to my node server? What is the best way to do this, without being to harsh on submittables API?

答:
I'm not familiar with the specific site you're integrating with, so this answer is about the general approach to this kind of problem.

The best thing to do in this situation is ask the administrators of the site in question how they want you to do it. Of course, this isn't always possible, so if you can't do this, then the following approaches are in rough order of niceness:

use a push notification service supported by the site (it may use such a service to communicate with mobile apps, so check how these work if you can) - this has basically no overhead for the site, so should definitely be the way to do it when you can

use a publicly specified websocket api - this is likely to be the next most efficient at the server end because it has the fewest layers of protocol to pass through.

use a long polling ajax ("comet") api - this has higher overhead because a new http request is needed for each notification

poll an api that returns instantly

poll an html page and scrape results from the text


问:
Const means Thread-safe?
I was put onto this video:

http://channel9.msdn.com/posts/C-and-Beyond-2012-Herb-Sutter-You-dont-know-blank-and-blank

By https://codereview.stackexchange.com/users/39810/glampert

Because I asked this question:

https://codereview.stackexchange.com/questions/82616/const-cast-of-stdmutex-in-get-member

Marking a class std::mutex as mutable is the right answer to my original question and the video is an excellent and enjoyable discussion around that. I am grateful to glampert.

However I disagree with the premise of the talk that "const == thread-safe" (see time-point 16:00).

Below is my proposal for how we should interpret const in a multi-threaded world. It's not as simple as Herb's proposal but (let's face it) if you think any of the answers in multi-threading are simple you've completely failed to grasp the challenge of multi-threading.

Comments please. What do you think const means for multi-threaded programs? Has its meaning fundamentally changed?

const means logically unmodified by dereferences through the const
  reference in question.

Multi-threading footnote #1:  In objects that form part of the shared
  state of a multi-threaded program “logically unmodified” will mean
  “logically const member functions only perform reads on the object” and so any
  implementation that actually performs writes (such as cached values,
  instrumentation and even employs synchronization mutexes) needs to
  adequately make them thread-safe to maintain the ‘logical’ appearance
  of ‘only reads’.

Single-threading footnote : Of course even in a single threaded
  application const is by no means a guarantee that an object won’t
  change during the lifetime of a given const reference. There may be
  non-const references (aliases) and even a single threaded program
  might use to modify an object which has one or more const
  references.

Multi-threaded footnote #2: That lack of guarantee that an object will
  not be modified just because there is a const reference to it is true
  in spades for multi-threaded applications. So in many senses – no
  change there.

I think my greatest concern is that through I am sure Herb Sutter would confirm them as dreadful fallacies, I fear that reading const as ‘thread-safe’ leads too easily to:

The fallacy that adding std::lock_guard guard(this->mutex) to the start of all methods and the destructor of a class somehow make any use of it ‘thread-safe’.

The fallacy that if you only call const methods on a class your application has a thread-safe guarantee and you can complain to the implementer if not.

Finally, the fallacy that if you don’t modify any mutable members and don’t cast away const anywhere you don’t need to worry about thread-safety because (apparently) “const means thread-safe”.

Fallacy 1 is best exemplified by supposing you can get any sense iterating through a collection that is being modified by another thread just because you know the methods are lock-guarded.

Fallacy 2 pushes a potentially onerous (and even impossible) burden on to implementers who can (of course) add lock-guards to all their methods but may (at best) be wasting time and (at worst) just setting you up for fallacy 1.

Fallacy 3 is the fallacy that thread-safety is all about competing for simultaneous access. Memory caching however means that to obtain a coherent state within a const method there may still be a requirement to ensure some kind of memory barrier has been performed (e.g. at least “acquire”).

答:
In C++ for example, a const class or struct can have mutable members. Mutable members are typically used in situations where the logical value of an object doesn't change, but the internal representation my change.

Changing mutable members is obviously not automatically thread safe. Therefore, accessing const objects is not automatically thread safe.

Another example would be a class holding a pointer to a file. I can read or write from that file, even if the instance is const. But these operations are unlikely to be thread safe.

Title: Const means Thread-safe?


问:
What is the difference between "Wide character" set and "Unicode character set"?
Today I was reading my favourite C++ Programming book (C++ Primer Plus) and the section which was about variables and character sets in C++,
however I got really confused about Unicode and Wide character set.

Can anyone explain me why we should use wchar_t? and isn't it possible to use Unicode (\u) instead of it?

答:
Unicode has several encodings, the most widely used being the variable length UTF-8 encoding (on 8 bit bytes, i.e. char on most C++ implementations). Hence getting the nth Unicode character (or code point) in an UTF-8 byte string requires iterating on that string (because a single Unicode character can take 1 to 6 bytes). UTF-8 is today very common (e.g. used in most web sites). See utfeverywhere.org suggested by a comment from Erik Eidt. Perhaps use an UTF8 library (like libunistring for C or utf8cpp for C++)

wchar_t could be 16 bits -e.g. for UTF-16- (but is often 32 bits, and IIRC the 32 bits is required by latest C++14 standard, but I could be wrong), and wchar_t might use a non Unicode encoding.

AFAIK, an implementation might provide char and wchar_t strings without having Unicode (at least for old C++ standards up to C++03).

In the previous century, many incompatible (and Unicode incompatible) character standards and encodings existed, e.g. EBCDIC on mainframes, KOI for cyrillic, etc etc.


问:
Should MVVM models have behaviour?
I am trying to wrap my head around MVVM and "models should not have behaviour".

If my getter depends on an environment variable,

should it be in the model or viewmodel?

Does it make a difference if that getter is specific to one viewmodel vs many?

Also, I have complex setters that might have side-effects and logic. Does that automatically mean they belong into a viewmodel?

Sources on this:

Models ... are not responsible for getting data, saving data,
...

Separate your User Interface concerns (View) from your Business
objects and behaviors (View Model) and from your data/persistence
layer (Model)

model ... holds the information, but not behaviors

Based on these I'm looking for some guidance for how to separate logic between model and viewmodel.

答:
Your model classes should be simple and only store the data you wish to model for your application. You should avoid having any complicated methods or business logic in your model classes. I usually have constructors and basic properties (i.e. public getters, private setters) in my model classes and that tends to suffice.

Your view model classes should contain business logic and anything else required to facilitate presenting the data in your model classes in the corresponding views. View model classes can also access other required dependencies, such as environment variables. If you find that several view model classes require access to environment variables, you may want to introduce a separate class that accesses environment variables and then include this class as a dependency in your view model classes, preferably using dependency injection.

ContentLicense: CC BY-SA 4.0

Title: Should MVVM models have behaviour?


问:
What was your most difficult bug hunt and how did you find it and kill it?
This is a "Share the Knowledge" question. I am interested in learning from your successes and/or failures.

Information that might be helpful...

Background:

Context: Language, Application,
Environment, etc.

How was the bug identified ?

Who or what identified the bug ?

How complex was reproducing the bug ?

The Hunting.

What was your plan  ?

What difficulties did you encounter ?

How was the offending code finally found ?

The Killing.

How complex was the fix ?

How did you determine the scope of the fix ?

How much code was involved in the fix ?

Postmortem.

What was the root cause technically ? buffer overrun, etc.

What was the root cause from 30,000 ft ?

How long did the process ultimately take ?

Were there any features adversely effected by the fix ?

What methods, tools, motivations did you find particularly helpful ? ...horribly useless ?

If you could do it all again
?............

These examples are general, not applicable in every situation and possibly useless. Please season as needed.

答:
The networking data race condition from hell

I was writing a networking client/server (Windows XP/C#) to work with a similar application on a really old (Encore 32/77) workstation written by another developer.

What the application did essentially was share/manipulate certain data on the host to control the host process running the system with our fancy PC based multi-monitor touchscreen UI.

It did this with a 3 layered structure. The communications process read/wrote data to/from the host, did all of the necessary format conversions (endianness, floating point format, etc) and wrote/read the values to/from a database. The database acted as a data intermediary between the comms and touchscreen UIs. The touchscreen UI's app generated touch screen interfaces based on how many monitors were attached to the PC (it automatically detected this).

In the time frame given a packet of values between the host and our pc could only send 128 values max across the wire at a time with a max latency of ~110ms per round trip (UDP was used with a direct x-over ethernet connection between the computers). So, the number of variables allowed based on the variable number of attached touchscreens was under strict control. Also, the host (although having a pretty complex multi-processor architecture with shared memory bus used for real time computing) had about 1/100th the processing power of my cell phone so it was tasked to do as little processing as possible and it's server/client had to be written in assembly to assure this (the host was running a full real time simulation that couldn't be affected by our program).

The issue was. Some values, when changed on the touchscreen wouldn't take just the newly entered value but would cycle randomly between that value and the previous value. That and only on a few specific values on a few specific pages with a certain combination of pages ever exhibited the symptom. We almost missed the issue completely until we started running it through the initial customer acceptance process

To pin down the issue I picked one of the oscillating values:

I checked the Touchscreen app, it was oscillating

I checked the database, oscillating

I checked the comms app, oscillating

Then I broke out wireshark and started manually decoding packet captures. Result:

Not oscillating but the packets didn't look right, there was too much data.

I stepped through every detail of the comms code a hundred times finding no flaw/error.

Finally I started firing off emails to the other dev asking in detail how his end worked to see if there was something I was missing. Then I found it.

Apparently, when he sent data he didn't flush the array of data before transmission so, essentially, he was just overwriting the last buffer used with the new values overwriting the old, but the old values not overwritten still being transmitted.

So, if a value was at position 80 of the data array and the list of values requested changed to less than 80 but that same value was contained within the new list, then both values would exist in the data buffer for that specific buffer at any given time.

The value being read from the database depended on the time slice of when the UI was requesting the value.

The fix was painfully simple. Read in the number of items incoming on the data buffer (It was actually contained as part of the packet protocol) and don't read the buffer beyond that number of items.

Lessons learned:

Don't take modern computing power for granted. There was a time when computers didn't support ethernet and when flushing an array could be considered expensive. If you really want to see how far we've come, imagine a system that has virtually no form of dynamic memory allocation. IE, the executive process had to pre-allocate all of the memory for all of the programs in order and no program could grow beyond that boundary. IE, allocating more memory to a program without recompiling the whole system could cause a massive crash. I wonder if people will talk about the pre-garbage collection days in the same light someday.

When doing networking with custom protocols (or handling binary data representation in general) make sure you read the spec until you understand every function of every value being sent across the pipe. I mean, read it until your eyes hurt. People handle data by manipulating individual bits or bytes have very clever and efficient ways of doing things. Missing the tiniest detail could break the system.

The overall time to fix was 2-3 days with most of that time spent working on other things when I got to frustrated with this.

SideNote: The host computer in question didn't support ethernet by default. The card to drive it was custom made and retrofitted and the protocol stack virtually didn't exist. The developer I was working with was one hell of a programmer, he not only implemented a stripped down version of UDP and a mimimal fake ethernet stack (the processor wasn't powerful enough to handle a full ethernet stack) on the system for this project but he did it in less than a week. He had also been one of the original project team leaders who had designed and programmed the OS in the first place. Lets just say, anything he ever had to share about computers/programming/architecture no matter how long winded or how much I already new, I'd listen to every word. There is nothing more valuable than working with good people who have a genuine passion for what they do.


问:
Ensuring program output is always the same
I am working on a +10k LOC program, and I need to ensure its output is always the same for given input. The program consists of dozens of modules and classes, inherited by a MainClass. (The examples below are very simplified compared to the actual code.)

Initially I created tests ensuring multiple instances of MainClass have the same output for given input.

```<code>def check_consistent_instances(input_dict):
    """Checks if all results for given input are the same."""
    first_instance_result = MainClass(input_dict).result()

    for i in range(10000):
        result = MainClass(input_dict).result()
        if first_instance_result != result:
            raise Exception('Different result detected!!')
</code>```

This however can't detect different results in multiple runs caused by sets/dicts having a different order due to a new hash seed in each run (this could in some rare cases affect the output).

For example:

```<code>class MyClass(object):
    AVAILABLE_MONEY = 6

    ITEMS_CATALOG = {'a': 5, 'b': 5, 'c': 5, 'd': 5, 'e': 3}

    def buy_most_expensive(self):
        """Deducts the most expensive items from the available money."""

        for i in self.ITEMS_CATALOG:
        # Assume I made a mistake here! I should have used sorted(self.ITEMS_CATALOG, key=lambda x: self.ITEMS_CATALOG[x])
        # but accidentally i used only self.ITEMS_CATALOG.
            cost = self.ITEMS_CATALOG[i]

            if cost <= self.AVAILABLE_MONEY:
                self.AVAILABLE_MONEY -= cost
</code>```

Code like the above would pass my check_consistent_instances() test, since on each run the PYTHONHASHSEED would have a specific value and all results would be the same during a specific run. The results would differ only between different runs.

Question:

Which are the best practices when it comes to checking whether a program's results are consistent?

答: I would add a bunch of unit tests for the individual modules and use something like Jenkins to compile and run the tests every time you make code changes. If you are finding variations when running, this should help you narrow it down so that you can change module logic to ensure repeatability.</p>


答:
Since you wrote in your comment you want to make the output of the unchanged program stable when it is not changed between two runs, you already excluded "accidental changes to module variables" - without any changes, there can be no "accidental changes".

The SO link you posted in your question mentioned how to initialize Python's hash seed to a fixed value, so that should be obviously the next thing to do. Same measure will apply when your program uses some kind of pseudo random numbers directly.

So what remains are the places of your program where it uses some external input like data from a clock, or data from processes outside your own program (like calling an OS function telling you how many other processes are currently running on the machine), these are AFAIK the only things where non-determinism can be introduced in a typical Python program. We actually do not know the internals of your program, but you should know. So the best recommendation I can give you: make a thorough inspection if your program contains calls to external functions of the type I mentioned, and avoid to use them inside the part of the program where the output is calculated.

Additionally, to detect if you overlooked something in your inspection, you should consider to create automated regression tests (not necessarily unit tests, but lots of people mix these terms up). Pick a set of well-chosen input data, run your program to produce the desired output, and write a simple comparer tool which allows you to detect if a new run of the program still produces the previous output again. That is also the standard technique to detect if the output of "version 1.1" of your program is still the same as the output of "version 1.0", when the changes from 1.0 to 1.1 should have not affected the results.

Title: Ensuring program output is always the same

Body:
I am working on a +10k LOC program, and I need to ensure its output is always the same for given input. The program consists of dozens of modules and classes, inherited by a MainClass. (The examples below are very simplified compared to the actual code.)

Initially I created tests ensuring multiple instances of MainClass have the same output for given input.

```<code>def check_consistent_instances(input_dict):
    """Checks if all results for given input are the same."""
    first_instance_result = MainClass(input_dict).result()

    for i in range(10000):
        result = MainClass(input_dict).result()
        if first_instance_result != result:
            raise Exception('Different result detected!!')
</code>```

This however can't detect different results in multiple runs caused by sets/dicts having a different order due to a new hash seed in each run (this could in some rare cases affect the output).

For example:

```<code>class MyClass(object):
    AVAILABLE_MONEY = 6

    ITEMS_CATALOG = {'a': 5, 'b': 5, 'c': 5, 'd': 5, 'e': 3}

    def buy_most_expensive(self):
        """Deducts the most expensive items from the available money."""

        for i in self.ITEMS_CATALOG:
        # Assume I made a mistake here! I should have used sorted(self.ITEMS_CATALOG, key=lambda x: self.ITEMS_CATALOG[x])
        # but accidentally i used only self.ITEMS_CATALOG.
            cost = self.ITEMS_CATALOG[i]

            if cost <= self.AVAILABLE_MONEY:
                self.AVAILABLE_MONEY -= cost
</code>```

Code like the above would pass my check_consistent_instances() test, since on each run the PYTHONHASHSEED would have a specific value and all results would be the same during a specific run. The results would differ only between different runs.

Question:

Which are the best practices when it comes to checking whether a program's results are consistent?


问:
Linking two or more different programming languages
I would like to ask how optimizer software written in C/C++ can be linked to simulator software written in FORTRAN or any other language. I have copied the section of journal article of Singh and Chakrabarty (2011).

In the present study, MODFLOW 2000 and MT3DMS 5.0 are
  linked as independent modules with the optimization code.
  Modifications are made to the codes of the simulators in such a
  way that they can be run through input files, and both of them
  are then compiled. One of the files required to run MODFLOW
  2000 is prepared by the optimization algorithm. This file contains
  the latest values of the decision variables. The NSGA II separately
  calls both MODFLOW 2000 and MT3DMS 5.0 in their compiled
  forms as independent modules. MODFLOW 2000 uses the file
  prepared by NSGA II to calculate hydraulic head and prepare
  an output file containing these values. Similarly, MT3DMS 5.0 calculates
  contaminant concentrations at selected locations and produces
  an output file containing the concentration values. The output
  files produced by the simulators are used by NSGA II as input files
  to produce updated values of the decision variables. The optimization
  problem, thus, runs until convergence. Obviously, writing of
  interface programs for linking codes written in different languages
  is altogether eliminated in this technique of linking.

I believe from here I can move forward with my research.
Thanks to you all.

答:
I think all they're saying here is that there are two components (one containing MODFLOW 2000 and MT3DMS 5.0, and the other containing NGSA II, with the two components being written in different languages) which simply use files as their interprocess communication (IPC) mechanism - hence the two components are logically linked while not being linked as in the "linker" step of a traditional compiler-linker chain.

However, this is not an innovative technique in any way, so either I've misinterpreted things or the authors are spinning things a little bit too much in the quote you've emphasised.


问:
Defining and testing detailed user interface requirements
I am in the process of designing and building a small web app. While implementing a first prototype I discovered that I make many unwritten assumptions about the behaviour of the interface. For example:

When the user selects a product in the product browser, the product inspector quickly slides out the left side displaying the product data. If the inspector is already opened, the data is only updated. The header background color changes with a radial animation.

Right now it's just me on the project, so I define these implicit requirements on the fly. But after every change that could break something I have to recall all of them in order to test them. I obviously should write them down somewhere.  I know unit testing, I know scenarios and personas, use-case diagrams; this seems to be something different and I don't know how to do it properly.

So, what is the usual way of defining, documenting, and also guaranteeing such requirements? Where do I put them? How do I structure them? How do I test them effectively? Should I ship them with the source code or put them in the project Wiki?

Also, these requirements are likely to change frequently, especially since I am using a rapid prototyping approach. I do not want to spend a lot of time drawing diagrams, etc. But simply dumping them into a text file without any structure seems to be a time waster as well, as soon as I have to test a specific part of the application.

答:
Sure, rapid prototyping can lead to frequent changes on your APIs for a duration of time, but I will expect changes to eventually mature and stabilize after requirements fall into place and you can essentially do an 'API freeze'.

If you are making changes to undo past changes, then you may be getting ahead of yourself and straying away from the You Aren't Gonna Need It principle. The point here is to know when and how you need to put a stop to making more requirements' changes.

With that out of the way, I think unit testing is definitely a potential starting point to validate any new changes you think you are going to implement with what is working currently. However, don't code weak unit tests that are either incomplete, or only performing the more superficial test cases (e.g. making sure fail-fast for null arguments work, without stepping through the actual logic). Try to unit-test for more meaningful edge cases, which tend to be your first line of defense when you head back to the drawing board. It will be even more helpful if you can write your unit tests in a BDD-style that gives a good definition of a class's contract.

You should also try to document your API design/code from the viewpoint of an end-user, or as a tabula rasa developer. Linking to the first point, once you feel you have reached a sufficiently mature point of your API design, start to document your codebase from scratch. Make sure to update the parts where your original 'implicit requirements' have changed. These can be included on your project's wiki page. If you are also placing your project documentation under version control, e.g. putting them up on GitHub, then you will also have a working version history to learn how the documentation plus your codebase have evolved.