问:
Trying to get a better understanding of object-oriented design's performance pitfalls
I'm currently in a high-performance computing class taught in C++. Usually, I do work in C#, meaning everything is taken care of for me, and optimization comes behind maintainability and higher-level features. It's like... a nice productivity furnace that keeps me nice and warm in the programming project winter at the expense of my CPU cycle/cache miss electricity bill. However, now that I'm in C++ and efficient algorithm land, that stuff takes a back seat to optimization.

Since most of my work has been in C#, object-oriented programming is sort of my style. However, I have been reading/hearing more and more about how object-oriented code is an enemy of performance. As my understanding of software architecture shifts from being exclusively about class structure and encapsulation to understanding how things are disposed of from L1 cache and pipelining, I'm trying to understand the real reasons why object-oriented design (especially as it applies to C++) causes waste of hardware resources. Can you guys give me a few basic reasons why it impacts computer performance? I know there are other debates about OOP, but I'd like to just keep it to performance on a hardware and algorithmic level.

答:
I'll tackle only the design side of the question, not the implementation mechanics (the hot/cold field splitting and SIMD focus below will only be exemplary to highlight the point of what designs will and will not allow further optimizations without cascading interface breakages).

This applies to all languages potentially. The biggest issue if you are going for max performance (and you absolutely shouldn't do this everywhere, a profiler will keep you honest and productive even when efficiency is a critical competitive goal) is a design related one.

```<code>// Models the design of a *single* point.
class Point
{
public:
    ...
private:
    float x;   // hot field, accessed sequentially.
    float y;   // hot field, accessed sequentially.
    float z;   // hot field, accessed sequentially.
    char id;   // cold field, rarely accessed.
               // 3 bytes of padding.
};
</code>```

Such a class gives you little room to optimize for, say, cache efficiency. You'll want to reach around the class and try to find ways to make its data fields interact with other points. A peak efficiency mindset has to do just that, and demolish this structure in favor of something more like this:

```<code>// Models the design of *many* points.
class Points
{
public:
    ...
private:
    vector<float> x; // hot field, accessed sequentially.
    vector<float> y; // hot field, accessed sequentially.
    vector<float> z; // hot field, accessed sequentially.
    vector<char> id; // cold field, rarely accessed.
};
</code>```

... now you're good given the memory access patterns. We're allowing SoA SIMD instructions (either handwritten or compiler-generated) and we've reduced the memory usage for a large number of points by eliminating per-point 3-byte padding without messing with alignment (3 bytes is actually kind of a huge deal when an L1 cache line is 64 bytes and the total size of the L3 cache is just 2 megs per core, e.g., and also relatively a big deal when a point is 13 bytes w/o padding and 16 bytes w/padding, not to mention that only 12 bytes are hot).

Or let's change the dynamics a bit. Let's say your system's most critical loops access points at random, but the id field is still cold. In that case, an AoS representation will do better, and we can change the above without breaking anything externally using the Points class:

```<code>class Points
{
public:
    ...
private:
    vector<vec3f> xyz; // hot field, accessed randomly.
    vector<char> id;   // cold field, rarely accessed.
};
</code>```

The key here is that Points gives you that breathing room to iterate towards faster solutions. You can forget half of what I suggested here about hot/cold field splitting, cache efficiency, padding, SoA SIMD access. I've done this kind of stuff long enough and measured it repeatedly against vtune and benchmarks to know how they pay off (though still reaching for vtune anyway, always). It's not critical to know this stuff upfront so much. The point is that Points gave me that room to optimize, Point didn't. You can even start off with this simple implementation:

```<code>// Models the design of *many* points.
class Points
{
public:
    ...
private:
    struct Point
    {
        float x;
        float y;
        float z;
        char id;
    };
    vector<Point> points; // simple representation
};
</code>```

... doesn't matter, the use of Point here is a private detail you can optimize away later as needed since the rest of the system won't have access to it, only Points.

That's the key above all else: it's designing for performance. Design is something you have to account for upfront. If you know your system is going to be accessing points by the masses (hundreds of thousands to millions repeatedly each frame, e.g.), then the basic design consideration to take into account upfront is whether you design a Point class or a Points class. The latter will give exponentially more breathing room to tweak and tune the hell out of it (not just at the memory optimization level, but also one central target to optimize data structures), Point will leave you trapped with a sub-optimal memory representation.

It's that simple to me, really -- this is the first and biggest step to consider when applying object-oriented design in a performance-critical context, and upfront, since you can't have a codebase that has 10,000 lines of code dependent on a Point interface and then change your mind later without serious grief.

There's other issues like runtime abstraction cost (dynamic dispatch with virtual function calls, dylib calls, std::function, etc) but to me that's kind of petty stuff. If you design your performance-critical interfaces at a coarse level, these concerns become moot -- pennies. When you start dealing with observer patterns with callbacks and things like that, same mentality. We want this:

```<code>void (*transform_many_points)(int num_points, float x[], float y[], float z[]);
</code>```

... more than something like this if we can help it:

```<code>void (*transform_one_point)(float& x, float& y, float& z);
</code>```

... same goes for virtual functions, dylib APIs, etc. If you can process many things at once in a performance-critical context, deal with many things at once. Avoid trapping yourself into the design corner of dealing with teeny little things, accessible only one at a time.

In some cases if your code feels trapped into accessing little teeny things one at a time, one strategy is to have each little access write some trivially-cheap local state. Then, in a deferred process, plow through all the local state of each little thing and process it in a bulk transformation, doing all the heavy-duty work there. If you can't avoid accessing little teeny things one at a time, then simply don't do the heavy-lifting there immediately. Do ultra-light work and defer the heavy-lifting work elsewhere. On top of making it easier to optimize, it'll make it easier to reason about what goes on in your system when you flatten the heavy-lifting work this way and not spread it across little teeny isolated code branches.

It's all design. Object-oriented design is just that, a way of design. And it's only an obstacle to performance if you utilize it to model the most granular objects in the most performance-critical areas, at which point such a design style will trap you into a state representation which cannot possibly get anywhere close to peak efficiency.

If you go further, it's worth looking at concepts like entity-component systems and how they end up flattening systems that process components in bulk (with the most optimized ones often skipping unnecessary components that don't need processing).

But OOP is still plenty applicable for even the most performance-critical applications, the key is to leave yourself breathing room to use more efficient data structures, data representations, and message passing as needed. The desire to encapsulate every little teeny thing into a teeny little object can counteract those goals at the design level.

Understand this, and the rest will take care of itself with a profiler in hand, chasing hotspots and tuning the places that really matter while learning computer architecture and developing that understanding of why these hotspots exist.

Body:
I'll tackle only the design side of the question, not the implementation mechanics (the hot/cold field splitting and SIMD focus below will only be exemplary to highlight the point of what designs will and will not allow further optimizations without cascading interface breakages).

This applies to all languages potentially. The biggest issue if you are going for max performance (and you absolutely shouldn't do this everywhere, a profiler will keep you honest and productive even when efficiency is a critical competitive goal) is a design related one.

// Models the design of a *single* point.
class Point
{
public:
    ...
private:
    float x;   // hot field, accessed sequentially.
    float y;   // hot field, accessed sequentially.
    float z;   // hot field, accessed sequentially.
    char id;   // cold field, rarely accessed.
               // 3 bytes of padding.
};

Such a class gives you little room to optimize for, say, cache efficiency. You'll want to reach around the class and try to find ways to make its data fields interact with other points. A peak efficiency mindset has to do just that, and demolish this structure in favor of something more like this:

// Models the design of *many* points.
class Points
{
public:
    ...
private:
    vector<float> x; // hot field, accessed sequentially.
    vector<float> y; // hot field, accessed sequentially.
    vector<float> z; // hot field, accessed sequentially.
    vector<char> id; // cold field, rarely accessed.
};

... now you're good given the memory access patterns. We're allowing SoA SIMD instructions (either handwritten or compiler-generated) and we've reduced the memory usage for a large number of points by eliminating per-point 3-byte padding without messing with alignment (3 bytes is actually kind of a huge deal when an L1 cache line is 64 bytes and the total size of the L3 cache is just 2 megs per core, e.g., and also relatively a big deal when a point is 13 bytes w/o padding and 16 bytes w/padding, not to mention that only 12 bytes are hot).

Or let's change the dynamics a bit. Let's say your system's most critical loops access points at random, but the id field is still cold. In that case, an AoS representation will do better, and we can change the above without breaking anything externally using the Points class:

class Points
{
public:
    ...
private:
    vector<vec3f> xyz; // hot field, accessed randomly.
    vector<char> id;   // cold field, rarely accessed.
};

The key here is that Points gives you that breathing room to iterate towards faster solutions. You can forget half of what I suggested here about hot/cold field splitting, cache efficiency, padding, SoA SIMD access. I've done this kind of stuff long enough and measured it repeatedly against vtune and benchmarks to know how they pay off (though still reaching for vtune anyway, always). It's not critical to know this stuff upfront so much. The point is that Points gave me that room to optimize, Point didn't. You can even start off with this simple implementation:

// Models the design of *many* points.
class Points
{
public:
    ...
private:
    struct Point
    {
        float x;
        float y;
        float z;
        char id;
    };
    vector<Point> points; // simple representation
};

... doesn't matter, the use of Point here is a private detail you can optimize away later as needed since the rest of the system won't have access to it, only Points.

That's the key above all else: it's designing for performance. Design is something you have to account for upfront. If you know your system is going to be accessing points by the masses (hundreds of thousands to millions repeatedly each frame, e.g.), then the basic design consideration to take into account upfront is whether you design a Point class or a Points class. The latter will give exponentially more breathing room to tweak and tune the hell out of it (not just at the memory optimization level, but also one central target to optimize data structures), Point will leave you trapped with a sub-optimal memory representation.

It's that simple to me, really -- this is the first and biggest step to consider when applying object-oriented design in a performance-critical context, and upfront, since you can't have a codebase that has 10,000 lines of code dependent on a Point interface and then change your mind later without serious grief.

There's other issues like runtime abstraction cost (dynamic dispatch with virtual function calls, dylib calls, std::function, etc) but to me that's kind of petty stuff. If you design your performance-critical interfaces at a coarse level, these concerns become moot -- pennies. When you start dealing with observer patterns with callbacks and things like that, same mentality. We want this:

void (*transform_many_points)(int num_points, float x[], float y[], float z[]);

... more than something like this if we can help it:

void (*transform_one_point)(float& x, float& y, float& z);

... same goes for virtual functions, dylib APIs, etc. If you can process many things at once in a performance-critical context, deal with many things at once. Avoid trapping yourself into the design corner of dealing with teeny little things, accessible only one at a time.

In some cases if your code feels trapped into accessing little teeny things one at a time, one strategy is to have each little access write some trivially-cheap local state. Then, in a deferred process, plow through all the local state of each little thing and process it in a bulk transformation, doing all the heavy-duty work there. If you can't avoid accessing little teeny things one at a time, then simply don't do the heavy-lifting there immediately. Do ultra-light work and defer the heavy-lifting work elsewhere. On top of making it easier to optimize, it'll make it easier to reason about what goes on in your system when you flatten the heavy-lifting work this way and not spread it across little teeny isolated code branches.

It's all design. Object-oriented design is just that, a way of design. And it's only an obstacle to performance if you utilize it to model the most granular objects in the most performance-critical areas, at which point such a design style will trap you into a state representation which cannot possibly get anywhere close to peak efficiency.

If you go further, it's worth looking at concepts like entity-component systems and how they end up flattening systems that process components in bulk (with the most optimized ones often skipping unnecessary components that don't need processing).

But OOP is still plenty applicable for even the most performance-critical applications, the key is to leave yourself breathing room to use more efficient data structures, data representations, and message passing as needed. The desire to encapsulate every little teeny thing into a teeny little object can counteract those goals at the design level.

Understand this, and the rest will take care of itself with a profiler in hand, chasing hotspots and tuning the places that really matter while learning computer architecture and developing that understanding of why these hotspots exist.


问:
What is "Split Data Model", mentioned in the book "Java Concurrency In Practice"?
I'm learning Java multithreading programming by the book "Java Concurrency In Practice". In chapter 9.4.2 Split Data Model, I read this:

From the perspective of the GUI, the Swing table model classes like TableModel and treeModel are the official
  repository for data to be displayed. However, these model objects are often themselves "views" of other objects
  managed by the application. A program that has both a presentation‐domain and an application domain data model is
  said to have a split‐model design (Fowler, 2005).

In a split‐model design, the presentation model is confined to the event thread and the other model, the shared model,
  is thread‐safe and may be accessed by both the event thread and application threads. The presentation model registers
  listeners with the shared model so it can be notified of updates. The presentation model can then be updated from the
  shared model by embedding a snapshot of the relevant state in the update message or by having the presentation
  model retrieve the data directly from the shared model when it receives an update event.

The snapshot approach is simple, but has limitations. It works well when the data model is small, updates are not too
  frequent, and the structure of the two models is similar. If the data model is large or updates are very frequent, or if one
  or both sides of the split contain information that is not visible to the other side, it can be more efficient to send
  incremental updates instead of entire snapshots. This approach has the effect of serializing updates on the shared
  model and recreating them in the event thread against the presentation model. Another advantage of incremental
  updates is that finer‐grained information about what changed can improve the perceived quality of the display if only
  one vehicle moves, we don't have to repaint the entire display, just the affected regions.

What is the meaning of "Split Data Model"? Can you show me an example to help me understand it?

答:
Consider software that controls a complex instrument.  Periodically it polls the instrument to read a bunch of values: voltages, pressures, percent complete, warning flags, etc.  Imagine that the data comes down as XML/JSON, or maybe some binary form, over USB or Ethernet.  This data is displayed in a modeless dialog for the user to monitor.  That dialog may be a two way interaction, i.e. is has an "Abort" button. In Java, you would probably have a Thread doing this polling, then parsing the data.  Many other languages would do similar.

Then, where to put the data, and how?

Somewhere deep inside that Dialog is a Panel inside a Panel that contains a Slider or Button or TextField to show these results.  Is it at all reasonable that this deeply buried data is THE model, the official true repository of the official true status of the instrument?  For example, if the voltage gets too high and you want to pop up an alert or send an email, should that code need to look through the nested JPanels?  No.

Is it reasonable for your Polling Thread to even know how to find the buttons within that Dialog?  Should it know to do (very hand waving over bad code) getComponent(EAST).getComponent(3).getStatusTextField().setText("4.56 pounds");  Almost certainly not.  If you are following Law of Demeter, that might become a bit simpler, getEscapeModuleForCapsule3StatusTextField().  But even that creates a ton of linkage between the Thread and the GUI.  What if you also want to have an Android and an HTML5 version of your code?  What if Marketing changes some of the widgets to Sliders or Spinners?  How about a European version using kilograms?  What if that voltage field is really 3 similar fields on three different JPanels, two are Text and one a Spinner?

O.K., I admit that I am exaggerating the previous two issues a bit.

Most importantly, which is the main reason this topic came up in JCiP, even if you work around all these problems and design issues so that the polling Thread can get to the relevant widgets, it's a pain in the butt to modify the value, because Swing is single threaded.  All the calls coming from the polling Thread are on the wrong thread and have to be wrapped in awkward   SwingUtilities.invokeLater(new Runnable() { public void run() {// real code here } });

Shared Data Model

In a "Shared Data Model", you are free to do things in an arguably much more natural way.  You define an InstrumentModel class, one that makes sense to your company and instrument, with relevant setters, getters, and, oh yeah, bounds checks.  It could fire special events when that voltage gets too high.  This model will make a lot more sense to your internal scientists and engineeers than many levels of nested JPanels.   This model must be made to be thread safe.

Note that this model has no knowledge of whether it will be Swing, GWT, HTML5 or American Sign Language that will be the output.  That's Decoupling.  The Polling Thread puts the data into the InstruementModel.  It (or something) then fires an event to the GUI - in the simplest form, theHugeDialog.repaint();  Note that in Swing these repaint requests are queued, so, hopefully, your dialog doesn't repaint 100s of times per change.

The GUI, in paintComponent() or similar (there are a few gotchas), then pulls data from the InstrumentModel.  It is automatically running on the proper Swing AWT Thread, so no need for invokeLaters().  Since you cleverly made the InstrumentModel thread safe, reading data doesn't clash with the PollingThread writing data.  If there is also a VeryImportantVoltage text field on the main application window, it can update too from the InstrumentModel.

This is the "snapshot" update - basically, you redraw the entire GUI.  If the GUI is huge and you are updating 100s of times a second, this may be too slow.  Then you go to an incremental update where only the changed data is updated.  This gets very complicated very quickly.

OwnerDisplayName: FireSun

ContentLicense: CC BY-SA 3.0


问:
Is it good practice to have your C++/Qt functions always check all its arguments for null values?

Backstory

While developing with Qt Signal/Slots, I came across a few segmentation faults that had me puzzled as to what was causing it. Eventually I figured out that you could actually pass a slot function without providing it any of its arguments, which of course would cause a Segmentation Fault if the argument was used.

To avoid this pitfall, I am getting into the habit of checking all my arguments to make sure they are not NULL:

```<code>void MyClass::setMyString(QString input)
{
    if (input.isNull()) {
        qDebug() << "Error: setMyString() received NULL argument";
        return;
    }

    m_MyString = input;
    emit myStringChanged();
}
</code>```

I'm thinking I ought to do this with all my functions from now on. Part of the reasoning is that I figure that it can not hurt to do this, and that if I or someone else ever needs to re-factor my code, it is less likely they will omit a necessary null value check.

Questions:

Is this an acceptable style in all or most circumstances?

Should I be introducing a runtime error, halting the program, instead of simply returning the function?

Does this style of coding improve security?

Does this style of coding improve stability?

Are there any performance considerations, to the extent that checking for null values may take longer depending on the type?

Beyond c++ and Qt, what other languages benefit from this style?

Are there any significant drawbacks worth considering?

答:
Kind of echoing Basile here but with a slightly more negative tone. I'd say "yes" too, but be careful with that if you are allowing silent violations of preconditions. As a personal example, I worked in a C codebase that did this kind of stuff through an API:

```<code>int f(struct Foo* foo)
{
    if (!foo)
        return error;
    ...
    return success;
}
</code>```

Perhaps even with a debug log in the middle. Yet it was a massive codebase, tens of millions of lines of code, over 30 years of development, and with pretty shoddy standards. The warnings in places like logs were filled to the brim with developers having developed the habit of ignoring the output.

I found, most unfortunately, when trying to change such error checks into obnoxiously-loud assertions that there were thousands of places in the system that were violating these preconditions and simply ignoring the errors (if there were any reported, some functions just returned without doing anything in those cases). The developers just worked around it and kept trying stuff and adding more code until their code "worked", blissfully unaware of their original mistake that they were passing nulls to a function that did not allow it.

As a result, I strongly recommend doing like this:

```<code>void MyClass::setMyString(QString input)
{
    assert(!input.isNull() && "Error: setMyString() received NULL argument.");
    m_MyString = input;
    emit myStringChanged();
}
</code>```

This will bring your application to a grinding halt if the assertion fails, showing you the precise source file and line number in which the assertion failed along with this message.

This is for cases where your function is not allowed to receive null (in your case, "null" here means "empty string"). For ones that are allowed, you might simply do something else, but it wouldn't be reporting a bug (for that, use the loud and obnoxious assert which cannot be ignored).

An example of where you might use if might be like this:

```<code>bool do_something(int* out_count = 0)
{
    ...
    if (out_count)
       *out_count = ...; // write the result back.
    return true;
}
</code>```

For ones that are not allowed to receive a null, use references when possible. However, you might still encounter "nulls" if you accept smart pointers, e.g., or if you expand your definition of "null" to include empty strings as another example. In those cases, assert your preconditions liberally if you can. assert has the advantage of not only bringing your application to a grinding halt (good thing), but also pointing out where it was brought to a grinding halt even outside of a debugging session (but still with a debug build, e.g.), and it's also an effective means of documentation.

qDebug is a little too silent usually. A team with good habits that never allows those outputs to be ignored might get away with keeping those to zero. But an assert will protect you even against the sloppiest teams by bringing the entire process to a grinding halt, making these programmer errors impossible to ignore. Another minor benefit of assert is that it can't slow down your release (production) builds, while if (...) qDebug(...) will.

For errors caused by external sources outside of your control (ex: failing to connect to a server that was down, failing to allocate a huge block of memory, trying to read from a file the user tried to load that was corrupt, etc), throw exceptions, but not for programmer bugs like accessing an array out of bounds or receiving a null in a place that never should receive null (unless you're working in a very mission-critical software where the software attempts to gracefully recover from even programmer bugs as opposed to making them as easy to detect and reproduce as possible). For these cases, assert.

Body:
Kind of echoing Basile here but with a slightly more negative tone. I'd say "yes" too, but be careful with that if you are allowing silent violations of preconditions. As a personal example, I worked in a C codebase that did this kind of stuff through an API:

int f(struct Foo* foo)
{
    if (!foo)
        return error;
    ...
    return success;
}

Perhaps even with a debug log in the middle. Yet it was a massive codebase, tens of millions of lines of code, over 30 years of development, and with pretty shoddy standards. The warnings in places like logs were filled to the brim with developers having developed the habit of ignoring the output.

I found, most unfortunately, when trying to change such error checks into obnoxiously-loud assertions that there were thousands of places in the system that were violating these preconditions and simply ignoring the errors (if there were any reported, some functions just returned without doing anything in those cases). The developers just worked around it and kept trying stuff and adding more code until their code "worked", blissfully unaware of their original mistake that they were passing nulls to a function that did not allow it.

As a result, I strongly recommend doing like this:

void MyClass::setMyString(QString input)
{
    assert(!input.isNull() && "Error: setMyString() received NULL argument.");
    m_MyString = input;
    emit myStringChanged();
}

This will bring your application to a grinding halt if the assertion fails, showing you the precise source file and line number in which the assertion failed along with this message.

This is for cases where your function is not allowed to receive null (in your case, "null" here means "empty string"). For ones that are allowed, you might simply do something else, but it wouldn't be reporting a bug (for that, use the loud and obnoxious assert which cannot be ignored).

An example of where you might use if might be like this:

bool do_something(int* out_count = 0)
{
    ...
    if (out_count)
       *out_count = ...; // write the result back.
    return true;
}

For ones that are not allowed to receive a null, use references when possible. However, you might still encounter "nulls" if you accept smart pointers, e.g., or if you expand your definition of "null" to include empty strings as another example. In those cases, assert your preconditions liberally if you can. assert has the advantage of not only bringing your application to a grinding halt (good thing), but also pointing out where it was brought to a grinding halt even outside of a debugging session (but still with a debug build, e.g.), and it's also an effective means of documentation.

qDebug is a little too silent usually. A team with good habits that never allows those outputs to be ignored might get away with keeping those to zero. But an assert will protect you even against the sloppiest teams by bringing the entire process to a grinding halt, making these programmer errors impossible to ignore. Another minor benefit of assert is that it can't slow down your release (production) builds, while if (...) qDebug(...) will.

For errors caused by external sources outside of your control (ex: failing to connect to a server that was down, failing to allocate a huge block of memory, trying to read from a file the user tried to load that was corrupt, etc), throw exceptions, but not for programmer bugs like accessing an array out of bounds or receiving a null in a place that never should receive null (unless you're working in a very mission-critical software where the software attempts to gracefully recover from even programmer bugs as opposed to making them as easy to detect and reproduce as possible). For these cases, assert.


问:
OpenGL, multithreading, and throwing destructors
How do you make an class that properly warns a developer in the future that they've made a mistake somewhere in their implementation that resulted in an object that gets deconstructed in a state that prevents the release of it's resources?

Background:

I recently upgraded to Visual Studio 2015 and began reloading and compiling code for a game engine I'm working on and ran into a new series of warnings "warning C4297: '*': function assumed not to throw an exception but does". A quick search revealed a C++ convention that I'd missed and the reasons behind said convention: destructors should not throw exceptions. I also can't really argue with the reasons, but I'm also not sure how to work around the problem.

Within OpenGL a Context basically holds all of the state information for the OpenGL engine. Only one thread may have a context at any given time and each thread may only have one current context. When the engine starts it creates the context and then relinquishes control over the context and starts up another thread which picks it up and proceeds to handle the graphics rendering for the engine. To handle all of this, I created a graphics engine class that uses semantics similar to a mutex to claim and relinquish the graphics engine and make sure that no mistakes are made that might some day result in someone attempting to do things with a context that it doesn't own.

During destruction, the graphics engine and a number of other classes that rely on it all check to make sure that the current thread has claimed the graphics engine before they perform actions that are necessary in their destruction. If the thread didn't have the graphics context claimed, the destructor was throwing. My goal was really to provide some basic protection against the class being used improperly on accident in the future, not to make the graphics engine thread-safe. Now... I'm uncertain of how best to handle this.

I've contemplated just switching over to a mutex-based approach which I could use to block access to the graphics context until a thread was done, possibly making the graphics engine class fully multi-threading capable (not that I can understand why you'd want to perform multi-threading with an OpenGL context, as the calls needed to do so are expensive enough to negate any benefit you might get out of it from what I understand).

The most tempting option has been to just log an error terminate any thread that attempts to misuse the class. Unfortunately, I can't find an OS-independent way of terminating just the current thread. If I was to go this route, I'd have to look up OS-appropriate ways to terminate the current threads.

I'm also not certain that I'm not being overly paranoid. Maybe I should just document the proper use of the class and if someone misuses it let them and hope that they're able to figure out why their application isn't doing what it's supposed to. I'm also worried about myself being the fool who misuses the class some day in the future.

答:
I think this is strictly an OGL question, and the solution doesn't have to be so hard. I've dealt with this issue many times before, encountering the same issues years before when I first tried to wrap OGL resources into object-oriented designs -- and got burnt both ways, not just trying to destroy resources outside of a valid GL context, but also trying to create them outside of a valid context.

There's an easy solution for that. It's not as complex as it seems when you first run into this issue. Just centralize one kind of GL resource manager which actually does all the resource allocation/deallocation for the raw, low-level GL resources (VBOs, shaders, textures, etc).

Your objects then turn into like handles. Simplified example:

```<code>class GpuTexture
{
public:
    explicit GpuTexture(GpuManager& imanager):
        manager(&imanager), texture_id(new GLuint(invalid_texture))
    {
        // The manager may not create the texture immediately
        // if it's outside a valid context. It might push it to a
        // queue of things to initialize the next time it's in a
        // valid context.
        manager->initialize_texture(texture_id);
    }

    ~GpuTexture()
    {
        // The manager may not destroy the texture immediately
        // if it's outside a valid context. It might push it to a
        // queue of things to destroy the next time it's in a
        // valid context. If the texture hasn't been initialized
        // yet, this request will simply be ignored and the texture
        // will be removed from the "to initialize" queue.
        manager->destroy_texture(texture_id);
    }

    ...

private:
    GpuManager* manager;
    shared_ptr<GLuint> texture_id;
};
</code>```

That's all there is to it. You can generalize it and simplify the resource manager just passing like std::function telling what to do when a context is valid, e.g. -- make it as fancy as you like. I know people tend to discourage "Manager" names, but can't think of a more appropriate one in this case for a central GPU resource "manager".

I didn't actually use shared_ptr in the final production version (we didn't have shared_ptr yet as part of the standard back then), but that's the easiest way when combined with a safe concurrent data structure like a concurrent queue or Intel's TBB concurrent_vector. More efficient might use a fixed allocator and possibly make manager globally-accessible as kind of a singleton. I haven't found a need for that level of efficiency since most of the OGL objects I've dealt with a rather bulky (whole texture, VBO with at least thousands of triangles worth of vertex attribute data, etc).

For VBOs, you can take this concept even further and allow initialization (as in full content generation with what would normally be glBufferData and not merely VBO acqusition through glGenBuffers) of the VBO outside a valid GL context. Simply write the buffer to system memory (memcpy to a private buffer, e.g.), and then send a request to initialize that buffer to a GPU-allocated buffer through the manager when the display context is valid.

All you have to do to make life much simpler and turn what seems to be this terrible nightmare scenario into something that'll never become a thorn in your side again is to simply avoid the mentality that your object has to be the one that actually does the GPU resource allocation/deallocation. Just centralize it to one place and it'll become easy to allocate and deallocate the resources only when the context is valid, and you'll no longer have to deal with destructors that can fail because they're not in a valid context (though there's a little more work to do if we want to make it impossible to fail since pushing to the queue might fail due to OOM, e.g.).

OwnerDisplayName: Darinth

Body:
I think this is strictly an OGL question, and the solution doesn't have to be so hard. I've dealt with this issue many times before, encountering the same issues years before when I first tried to wrap OGL resources into object-oriented designs -- and got burnt both ways, not just trying to destroy resources outside of a valid GL context, but also trying to create them outside of a valid context.

There's an easy solution for that. It's not as complex as it seems when you first run into this issue. Just centralize one kind of GL resource manager which actually does all the resource allocation/deallocation for the raw, low-level GL resources (VBOs, shaders, textures, etc).

Your objects then turn into like handles. Simplified example:

class GpuTexture
{
public:
    explicit GpuTexture(GpuManager& imanager):
        manager(&imanager), texture_id(new GLuint(invalid_texture))
    {
        // The manager may not create the texture immediately
        // if it's outside a valid context. It might push it to a
        // queue of things to initialize the next time it's in a
        // valid context.
        manager->initialize_texture(texture_id);
    }

    ~GpuTexture()
    {
        // The manager may not destroy the texture immediately
        // if it's outside a valid context. It might push it to a
        // queue of things to destroy the next time it's in a
        // valid context. If the texture hasn't been initialized
        // yet, this request will simply be ignored and the texture
        // will be removed from the "to initialize" queue.
        manager->destroy_texture(texture_id);
    }

    ...

private:
    GpuManager* manager;
    shared_ptr<GLuint> texture_id;
};

That's all there is to it. You can generalize it and simplify the resource manager just passing like std::function telling what to do when a context is valid, e.g. -- make it as fancy as you like. I know people tend to discourage "Manager" names, but can't think of a more appropriate one in this case for a central GPU resource "manager".

I didn't actually use shared_ptr in the final production version (we didn't have shared_ptr yet as part of the standard back then), but that's the easiest way when combined with a safe concurrent data structure like a concurrent queue or Intel's TBB concurrent_vector. More efficient might use a fixed allocator and possibly make manager globally-accessible as kind of a singleton. I haven't found a need for that level of efficiency since most of the OGL objects I've dealt with a rather bulky (whole texture, VBO with at least thousands of triangles worth of vertex attribute data, etc).

For VBOs, you can take this concept even further and allow initialization (as in full content generation with what would normally be glBufferData and not merely VBO acqusition through glGenBuffers) of the VBO outside a valid GL context. Simply write the buffer to system memory (memcpy to a private buffer, e.g.), and then send a request to initialize that buffer to a GPU-allocated buffer through the manager when the display context is valid.

All you have to do to make life much simpler and turn what seems to be this terrible nightmare scenario into something that'll never become a thorn in your side again is to simply avoid the mentality that your object has to be the one that actually does the GPU resource allocation/deallocation. Just centralize it to one place and it'll become easy to allocate and deallocate the resources only when the context is valid, and you'll no longer have to deal with destructors that can fail because they're not in a valid context (though there's a little more work to do if we want to make it impossible to fail since pushing to the queue might fail due to OOM, e.g.).


问:
Anonymous namespaces make code untestable
Here is a typical C++ code:

foo.hpp

```<code>#pragma once

class Foo {
public:
  void f();
  void g();
  ...
};
</code>```

foo.cpp

```<code>#include "foo.hpp"

namespace {
    const int kUpperX = 111;
    const int kAlternativeX = 222;

    bool match(int x) {
      return x < kUpperX || x == kAlternativeX;
    }
} // namespace

void Foo::f() {
  ...
  if (match(x)) return;
  ...
</code>```

It looks like a decent idiomatic C++ code - a class, a helper function match which is used by the methods of Foo, some constants for that helper function.

And then I want to write tests.

It would be perfectly logical to write a separate unit test for match, because it's quite non-trivial.

But it resides in an anonymous namespace.

Of course I can write a test which would call Foo::f(). However it won't be a good test if Foo is heavy and complicated, such test won't isolate the testee from other unrelated factors.

So I have to move match and everything else out of the anonymous namespace.

Question: what's the point of putting functions and constants into the anonymous namespace, if it makes them unusable in tests?

答:
It would be perfectly logical to write a separate unit test for match,
  because it's quite non-trivial.

The code you showed for match is a pretty trivial 1-liner without any tricky edge cases, or is that like a simplified example? Anyway, I'll assume it's simplified...

Question: what's the point of putting functions and constants into the
  anonymous namespace, if it makes them unusable in tests?

This question is what wanted to make me jump in here since Deduplicator already showed a perfectly good way to break in and get access through #include trickery. But the wording here makes it sounds like testing every single internal implementation detail of everything is some kind of universal end goal, when it's far from it.

The goal of even unit testing isn't always to test every little granular internal micro-unit of functionality. The same question applies to static file-scope functions in C. You can even make the question harder to answer by asking why developers use pimpls in C++ which would require both friendship and #include trickery to white box, trading easy testability of implementation details for improved compilation times, e.g.

From a kind of pragmatic perspective, it might sound gross but match may not be correctly implemented with some edge cases that cause it to trip up. However, if the sole outer class, Foo, that has access to match cannot possibly use it in a way that encounters those edge cases, then it's rather irrelevant to the correctness of Foo that match has these edge cases that will never be encountered unless Foo changes, at which point the tests of Foo will fail and we'll know immediately.

A more obsessive mindset eager to test every single internal implementation detail (perhaps a mission-critical software, e.g.) might want to break in and party, but a lot of people don't necessarily think that's the best idea, as it would create the most brittle tests imaginable. YMMV. But I just wanted to address the wording of this question which makes it sound like this kind of uber-fine-grained-internal-detail-level testability should be an end goal, when even the most rigorous unit testing mindset might relax a bit here and avoid x-raying the internals of every class.

So why do people define functions in anonymous namespaces in C++ or as file-scope static functions with internal linkage in C, hidden from the outside world? And that's mainly it: to hide them from the outside world. That has a number of effects from reducing compile times to reducing complexity (what cannot be accessed elsewhere cannot cause problems elsewhere) and so forth. Probably testability of private/internal implementation details isn't the number one thing on people's minds when they do it over, say, reducing build times and hiding unnecessary complexity from the outside world.


问:
Pattern for separating UI code from logic in Wicket
I'm using Apache Wicket for developing web apps, I have developed a few  for the last year  and it has been great; today I was looking at a few pages and most of them look like this:

```<code>public class MyPage extends MyBasePage
{
    public MyPage() {
        constructUI();
    }

    private void constructUI() {
        //first build all the models..
        IModel aModel = new SomeModel(new SimeObject());

        //then build forms, links and buttons like this
        Form myForm = new Form("myForm", aModel) {

            //notice that the submit logic is not implemented here
            private void onSubmit() {
                myForm_submit();
            }
        }
    }

    private void myForm_submit() {
        //handle the form submision here, validation, service calling etc..
    }
}
</code>```

I usually handle the form submission and link/button clicking on separate methods in order to keep the constructUI method as short as possible, most pages have 1 or 2 grids, and 2-3 forms for different actions, for my specific needs and use cases this practice gives me these benefits:

The UI can be constructed/deconstructed in different ways (to refactor the markup for example) without having to copy/paste/move-around the whole submit handling logic

Having *_submit, *_click methods allows to easily navigate the class using "ctrl+o" (on Eclipse) to filter and find methods

So my question is, if there exists some software pattern that would allow to separate the "constructUI" logic into a different class, or something similar, because some pages are component heavy (even using custom components) and "constructUI" gets too large.

答:
Wicket has different cycles for building the component tree and rendering it.  Understanding those cycles will help you to avoid creating components in the constructor, which the writers of Apache Wicket consider a bad practice because it can potentially increase the size of your session.  Try writing code that puts model objects in fields, puts instantiation in add methods in an overwritten onInitialize method, and sets visibility in overridden onConfigure methods.</p>

```<code>public class MyPage extends MyBasePage
{

private Form<MyModel> form;
private Model<MyModel> aModel;

public MyPage(PageParameters parms, MyModel aModel) {
    super(parms);
    this.aModel = aModel;

}

    @Override
    public void OnInitialize(){
        add(form(aModel));
    }

private Form<MyModel> form(Model aModel) {
    Form<MyModel> myForm = new Form("form", aModel){
        private static final long serialVersionUID = 1L;

        @Override
        private void onInitialize(){
        add(submit());
        }
    }
}

private AjaxSubmitLink submit(){
    AjaxSubmitLink submit = new AjaxSubmitLink("submit") {
    private static final long serialVersionUID = 1L;

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<MyModel form> form) {
            target.add(anAjaxRenderedComponent());
        }

        @Override
        protected void onError(AjaxRequestTarget target, Form<MyModel> form) {
            target.add(anErrorPanel());
        }

        @Override
        protected void onConfigure() {
            setVisible(someBooleanReturningMethod());
            setOutputMarkupPlaceHolderTag(true);

        }

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

Body:
Wicket has different cycles for building the component tree and rendering it.  Understanding those cycles will help you to avoid creating components in the constructor, which the writers of Apache Wicket consider a bad practice because it can potentially increase the size of your session.  Try writing code that puts model objects in fields, puts instantiation in add methods in an overwritten onInitialize method, and sets visibility in overridden onConfigure methods.

public class MyPage extends MyBasePage
{

private Form<MyModel> form;
private Model<MyModel> aModel;

public MyPage(PageParameters parms, MyModel aModel) {
    super(parms);
    this.aModel = aModel;

}

    @Override
    public void OnInitialize(){
        add(form(aModel));
    }

private Form<MyModel> form(Model aModel) {
    Form<MyModel> myForm = new Form("form", aModel){
        private static final long serialVersionUID = 1L;

        @Override
        private void onInitialize(){
        add(submit());
        }
    }
}

private AjaxSubmitLink submit(){
    AjaxSubmitLink submit = new AjaxSubmitLink("submit") {
    private static final long serialVersionUID = 1L;

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<MyModel form> form) {
            target.add(anAjaxRenderedComponent());
        }

        @Override
        protected void onError(AjaxRequestTarget target, Form<MyModel> form) {
            target.add(anErrorPanel());
        }

        @Override
        protected void onConfigure() {
            setVisible(someBooleanReturningMethod());
            setOutputMarkupPlaceHolderTag(true);

        }

    };
    return submit;
}


问:
Stack and Heap memory in Java
As I understand, in Java, stack memory holds primitives and method invocations and heap memory is used to store objects.

Suppose I have a class

```<code>class A {
       int a ;
       String b;
       //getters and setters
}
</code>```

Where will the primitive a in class A be stored?

Why does heap memory exist at all? Why can't we store everything on the stack?

When the object gets garbage collected, is the stack associated with the objected destroyed?

答:
Stack memory is used to store local variables and function call.

While heap memory is used to store objects in Java. No matter, where object is created in code.

Where will the primitive a in class A be stored?

In this case primitive a is associated with class A object. So it creates in Heap Memory.

Why does heap memory exist at all? Why can't we store everything on the stack?

Variables created on the stack will go out of scope and automatically destroyed.

Stack is much faster to allocate in comparison to variables on the heap.

Variables on the heap must be destroyed by Garbage Collector.

Slower to allocate in comparison to variables on the stack.

You would use the stack if you know exactly how much data you need to allocate before compile time and it is not too big.( primitive local variables store in stack)

You would use the heap if you don't know exactly how much data you will need at runtime or if you need to allocate a lot of data.

When the object gets garbage collected, is the stack associated with the objected destroyed?

Garbage Collector works under the scope of Heap memory, so it destroys objects which are not having reference chain from to root.

Title: Stack and Heap memory in Java


问:
Repository Pattern Class Collection examples with Lazy/Eager loading
When implementing the repository it's fairly easy for a stand alone class.  Unfortunately, we are unable to use an ORM to manage our data access, so I'm trying to recreate some of the functionality manually (uggh).

For example, If I have a class User the implements a generic IRepository.  Additionally, I may have a class called Task that also implements IRepository.  If there is a One-to-Many relationship from User to Task  I would plan to have some code like this:

```<code>Public class User : IRepository<T> where T : IEntity
{
    public string Name{get;set;}

    public list<Task> ....(This is where I start getting fuzzy)
}
</code>```

I would like to be able to chain my calls for example:

```<code>User.Tasks;
</code>```

Would return a list of all of that users task. How would the data access for task should look to handle this, Also, how should the Task be defined in the User class.  And lastly, what about eager/lazy loading the Task on a user?  How can this be accomplished?

答:
Don't implement a repository interface on the entity itself, create a separate (service class) for it.

Given your example I would consider not doing a Task list on the user at all but
just create a TaskRepository with a ListTasksByUser query.

If you need no direct access to tasks (independent of user), you could consider just storing the tasks alongside the other user data. A document database would work well there. With a relational DB you could hide the join inside the repository.

If you plan to have both a UserRepository and a TaskRepository I would consider just associating by ID and leave it there.

To attach references to the real object, eagerly or lazily, you could come up with a bunch of solutions, one may require more instrumentation on your entity then others.

You could map your entities to DTOs which contain ID foreign keys, when loading it will eagerly load the foreign entity and assign it. When done lazily you could use a proxy around the entity property and load on accessing the proxied property.

Another option would be to create a small Reference object to use for each relationship containing a Lazy<T> and the ID. You would need to provide delegates for the Lazy values after loading data.

IMHO it's more trouble then it's worth, lazy loading is overrated. Either you want something eagerly or not at all. A code path touching a lot of lazy properties can give a lot of performance issues (select+1).


问:
Structuring projects in a solution for interfaces
I had this idea that I would achieve some good automation and separation of concerns as follows:

Define an interface, IDataProvider, in a class in a DataMuncher project that needs to both consume and output data.

In separate projects, have different implementations of that interface, e.g., in LunarData.csproj would be LunarDataProvider : IDataProvider, and in SolarData.csproj would be SolarDataProvider : IDataProvider.

In DataMuncher, reflect over the assembly and linked assemblies and find all classes implementing IDataProvider.

Create instances of the IDataProvider-implementing classes that were found, ask them what data they can provide, and if their data matches up with what was similarly learned from IDataConsumer classes, request the appropriate data, and send it onward to the consumers.

The idea is that if I need to add a new data provider, I can do so with only the barest touch on any other projects. I just create a new project, add a class that implements IDataProvider, and whether I'm manufacturing the data (as might occur in a unit test), reading from a text file, connecting to a database, or calling a web API, or any other means of getting the data, as long as I return it in the form required by the interface, it can be consumed. Thus, the quirks of the data are not exposed to the rest of the system and no proper nouns are propagated to other parts when they shouldn't be.

However, I've run into a wee bit of a problem where the provider classes need to depend on the DataMuncher, but the DataMuncher needs to depend on the provider classes (in order to do what ultimately amounts to self dependency-injection).

So for this scenario to work I need at least 3 projects: one where the interface is defined, one where it's implemented (dependent), and one that is dependent on both of them that does what amounts to dependency injection, call this the DataHub project. But that seems like a lot of complexity.

One suggestion was made to just put the interface definition and the data source implementations all in the same project. This would enable the implementing project to have no outside dependencies, and would avoid the need for another coordinating project to which many projects must refer. It also reduces the number of projects in the solution, which is also a possible benefit. (E.g., DataProviders.cs would have all three: IDataProvider plus LunarDataProvider and SolarDataProvider.

What would you do in this scenario? I saw value in having one project per implementation, but I have to admit that I don't have a plethora of experience with various project structures that would have given me an idea of what works best. I also saw value in the division between projects forcing the separation of implementation internals from other projects, so that no one implementation would ever, even by mistake, use code or classes from another implementation. With one project each, a review of the project reference dependency graph could easily establish that the separate implementations are properly isolated from each other. This makes sure the code is truly modular and properly encapsulated.

Another benefit of separate projects is that if the data source doesn't need to access, say, a database, there are no references to database libraries. Perhaps it's file-based, and doesn't need any dependencies. Then, the reference graph can be examined for correctness and anything strange will stick out much better: rather than "hmmm, I guess one of the 10 implementations uses that library", "why is X using Y!?!"

I also considered, still with three projects, defining the interface in the DataHub, but this would prevent it, due to circular reference problems, from doing the reflection to find data sources—the recipient of the benefit of the interface, DataMuncher, would have to perform that task, and instead of LunarData having a reference to DataMuncher, it would be the other way around. This is now more references, and the DataHub class now also has to have a lot of projects referencing it (again, instead of the other way around). All these extra references suggest that perhaps the single project with interface and implementations is better.

Some guidance or ideas would be appreciated.

Hmmmm ... it just occurred to me, 20 minutes after posting, that perhaps I should simply use a dependency injection library. That would use a pattern that is well established, and would remove some of the questions by reducing the number of reasonable ways to structure things. Still thinking on this ...

For Reference

First we go fetch all the types available in all referenced assemblies that implement IDataProvider:

```<code>var types = GetType()
   .Assembly
   .GetReferencedAssemblies()
   .SelectMany(assemblyName => Assembly.Load(assemblyName).GetTypes())
   .Where(type => (typeof (IDataProvider)).IsAssignableFrom(type))
   .ToList();
</code>```

Then we can create instances of these:

```<code>var instantiatedTypes = types
   .Select(Activator.CreateInstance)
   .ToList()
   .AsReadOnly();
</code>```

This list of instantiated types then need to be passed to the core of the system, as a parameter to the DataMuncher class (or perhaps a method).

```<code>public sealed class DataMuncher {
   public DataMuncher(
      IEnumerable<IDataProvider> dataProviders,
      IEnumerable<IDataConsumer> dataConsumers
   ) {
      var consumersAndData = dataConsumers
         .Select(consumer => new { consumer, dataspec = consumer.GetDesiredDataSpecification() })
         .Select(cas => new {
            cas.consumer,
            cas.dataspec,
            data = dataProviders
               .Select(provider => provider.RetrieveData(cas.dataspec))
         })
         .ToList();
      consumersAndData.ForEach(cas => cas.consumer.ReceiveData(cas.data));
   }
}
</code>```

This is very rough, just to show the idea. Don't bother code reviewing this particular code, it is only here to show the basic idea and get assistance in how to structure the interfaces.

Note: I have been reading .Net solution structure of an enterprise application and it is possibly helping, but I don't have a conclusion yet.

答:
You can have one project holding the DataMuncher and the IDataProvider. Reference it from one or more Data Provider projects, implement the IDataProvider there.

From your application's composite root have the concrete Data Provider injected into your DataMuncher before use.

What is not clear from your post is why DataMuncher was/is dependant on the Data Providers. If you invert this dependency properly things would get simple. DataMuncher defines the contract, the Data Provider project(s) provide an implementation.

Your app's composition root configures when to use which implementation.


问:
What does it mean to declare a volatile variable?
Many low level programs use the volatile keyword for types for memory mapping and such, however I'm sort of confused as to what it REALLY does in the background.  In other words, what does it mean when the compiler doesn't "optimize away" the memory address?

答:
The answers seem pretty consistent but missing an important point.  You are telling the compiler that you want to to allocate space and for every access, read OR WRITE, you want it to perform that access.  We dont want it to optimize away those accesses or that variable for some reason.

Yes, one reason is because someone else might change that value for us.  Another reason is that we might be changing that value for someone else.  That someone else be it the one that changes it for us or the one we are changing it for might be hardware/logic or software.  It is often used to define accesses to control and status registers in bare metal embedded programs, writing to or reading from hardware.  As well as software talking to software explained in other answers.

You will also see volatile used to control when and in what order the accesses occur, if you are trying to time a section of code, and you dont use volatile the variables in question (beginning time, end time and difference) only need to be computed near the end the compiler is free to move either of the time measurements around (not where we placed them), not that it cant with volatile but experience shows it less likely.

On occasion, you will see it used to simply burn time, an elementary led blinker, the hello world of bare metal, might use a volatile for a variable that counts to some large number just to burn time for the human eye to see the led change state.  More advanced examples then using timers or other events to burn the time.


问:
How have you found, refined and maintained your coding style?
Recently, I've been switching between several projects and development environments. The expectations for coding style in each is different.

Now, my question is three part, the first, just of curiosity:

How did you define and find your coding style?

How do you keep augmenting and improving it?

How do you maintain it? (From mental notes, keeping a document, using a tool like StyleCop etc.)

答:
This is kind of a weird answer, but I took a really long time to actually pick up programming.  I spent a lot of time working in 'the arts' before considering myself a programmer.

When coding, I tend to think in units like writing - paragraphs, phrases, etc.  Because of this, I'll spread code out over more lines in the pursuit of making it readable like a story/essay/etc.  I get really annoyed when developers try to cram as much as possible onto one line or into a small space, because it doesn't accomplish anything besides making the writer feel clever and annoying any future readers.

If I need to do something weird for the sake of efficiency, I'll comment it to explain why it's like that.

I probably won't get any upvotes for this but perhaps this will spark some discussion anyway.

As for the technical side, like placement of brackets and such, I keep them aligned because the result is increased readability.

ContentLicense: CC BY-SA 2.5


问:
How to ease the maintenance of event driven code?
When using an event based component I often feel some pain at maintenance phase.

Since the executed code is all split around it can be quite hard to figure what will be all the code part that will be involved at runtime.

This can lead to subtle and hard to debug problems when someone adds some new event handlers.

Edit from comments:
Even with some good practices on-board, like having an application wide event bus and handlers delegating business to other part of the app, there is a moment when the code starts to become hard to read because there is a lot of registered handlers from many different places (especially true when there is a bus).

Then sequence diagram starts to look over complex, time spend to figure out what is happening is increasing and debugging session becomes messy (breakpoint on the handlers manager while iterating on handlers, especially joyful with async handler and some filtering on top of it).

//////////////

Example

I have a service that is retrieving some data on the server. On the client we have a basic component that is calling this service using a callback. To provide extension point to the users of the component and to avoid coupling between different components, we are firing some events: one before the query is sent, one when the answer is coming back and another one in case of a failure.
We have a basic set of handlers that are pre-registered which provide the default behavior of the component.

Now users of the component (and we are user of the component too) can add some handlers to perform some change on the behavior (modify the query, logs, data analysis, data filtering, data massaging, UI fancy animation, chain multiple sequential queries, whatever).
So some handlers must be executed before/after some others and they are registered from a lots of different entry point in the application.

After a while, it can happens that a dozen or more handlers are registered, and working with that can be tedious and hazardous.

This design emerged because using inheritance was starting to be a complete mess. The event system is used at a kind of composition where you don't know yet what will be your composites.

End of example

//////////////

So I'm wondering how other people are tackling this kind of code. Both when writing and reading it.

Do you have any methods or tools that let you write and maintain such code without to much pain ?

答:
I wanted to update this answer since I've gotten some eureka moments since after "flattening" and "flattening" control flows and have formulated some new thoughts on the subject.

Complex Side Effects vs. Complex Control Flows

What I've found is that my brain can tolerate complex side effects or complex graph-like control flows as you typically find with event handling, but not the combo of both.

I can easily reason about code that causes 4 different side effects if they're being applied with a very simple control flow, like that of a sequential for loop. My brain can tolerate a sequential loop which resizes and repositions elements, animates them, redraws them, and updates some kind of auxiliary status. That's easy enough to comprehend.

I can likewise comprehend a complex control flow as you might get with cascading events or traversing a complex graph-like data structure if there's just a very simple side effect going on in the process where order doesn't matter the slightest bit, like marking elements to be processed in a deferred fashion in a simple sequential loop.

Where I get lost and confused and overwhelmed is when you have complex control flows causing complex side effects. In that case the complex control flow makes it difficult to predict in advance where you're going to end up while the complex side effects make it difficult to predict exactly what's going to happen as a result and in what order. So it's the combination of these two things that makes it so uncomfortable where, even if the code works perfectly fine right now, it's so scary to change it without fear of causing unwanted side effects.

Complex control flows tend to make it difficult to reason about when/where things are going to happen. That only becomes really headache-inducing if these complex control flows are triggering a complex combination of side effects where it's important to understand when/where things happen, like side effects that have some kind of order dependency where one thing should happen before the next.

Simplify the Control Flow or the Side Effects

So what do you do when you encounter the above scenario which is so difficult to comprehend? The strategy is to either simplify the control flow or the side effects.

A widely-applicable strategy to simplifying side effects is to favor deferred processing. Using a GUI resize event as an example, the normal temptation might be to reapply the GUI layout, reposition and resize the child widgets, triggering another cascade of layout applications and resizing and repositioning down the hierarchy, along with repainting the controls, possibly triggering some unique events for widgets that have custom resizing behavior which trigger more events leading to who-knows-where, etc. Instead of trying to do this all in one pass or by spamming the event queue, one possible solution is to descend down the widget hierarchy and mark what widgets need their layouts to be updated. Then in a later, deferred pass which has a straightforward sequential control flow, reapply all the layouts for widgets that need it. You might then mark what widgets need to be repainted. Again in a sequential deferred pass with straightforward a control flow, repaint the widgets marked as needing to be redrawn.

This has the effect of both simplifying the control flow and side effects since the control flow becomes simplified since it's not cascading recursive events during the graph traversal. Instead the cascades occur in the deferred sequential loop which might then be handled in another deferred sequential loop. The side effects become simple where it counts since, during the more complex graph-like control flows, all we're doing is simply marking what needs to be processed by the deferred sequential loops which trigger the more complex side effects.

This does come with some processing overhead but it might then open up doors to, say, doing these deferred passes in parallel, potentially allowing you to get an even more efficient solution than you started if performance is a concern. Generally performance shouldn't be much of a concern in most cases though. Most importantly, while this might seem like a moot difference, I have found it so much easier to reason about. It makes it much easier to predict what's happening and when, and I can't overestimate the value that can have in being able to more easily comprehend what's going on.


问:
Standardized Data Structure Interface
I want to work with a variety of data structures (arrays, singly/doubly linked lists, sorted structures, etc.) on a plug-and-play basis. For example, I want to be able to easily swap in and out the sorted list and the array (which is re-sorted after every insertion/deletion), to test which one has better performance.

In every language I know of, the public interface to such data structures is very inconsistent. So changing the implementation requires a lot of work.

Is there a language, or a language-agnostic design pattern, that makes it easy to define a generic public interface that works with any data structure?

Of course, I understand how different performance would be (e.g., binary search in a sorted array vs linear search in a regular array). All I ask is that the performance of the data structure doesn't degrade asymptotically or by a large constant factor due to the use of the standard interface.

Example problem: iterate through the container of numbers, find the two numbers that are nearest  each other, and remove the pair of them. (If several pairs are equal distance, pick an arbitrary pair).

I'd like the code to solve the problem to be unchanged as I switch in and out different containers.

答:
Is there a language, or a language-agnostic design pattern, that makes
  it easy to define a generic public interface that works with any data
  structure?

Haskell seems like an awesome suggestion, but maybe a bit hardcore. At least I'm a little bit afraid of Haskell (it's a language whose code always inspires me, but I never actually got the nerve to try anything substantial).

I'd personally recommend C++ for this since the code generation of C++ templates allows you to eliminate any abstraction cost (dynamic dispatch, i.e.) out of the picture and just focus on the efficiency of the data structures themselves while likewise mutating the data structure easily (might be a little bit hard in functional languages without kind of changing the whole way you approach data structures). It's one of the few languages I personally know where you can write a contiguous data structure which performs just as well for random access as a plain old array, e.g., since the optimizer just squashes all that code structure you built down to smithereens.

It also comes with a pretty complete set of standard containers (though missing a few semi-common ones like tries) with a "near" data structure-agnostic interface. A little bit of wrapping should give you a universal interface that lets you do whatever you want, at least for value types (set vs. map). Key/value associative containers are a bit harder to generalize and might need to be in their own category, simply because they tend to call for a very different interface design.

The key to doing this to me is to define your universal interface. A C++ standard sequence like vector has these functions:

```<code>push_back -- appends an element to the back of the container.
insert -- inserts an element to any place in the container.
erase -- erases an element from any place in the container.
range insert -- inserts multiple elements to any place in the container.
range erase -- removes a range of elements from any place in the container.
empty -- returns size() == 0.
size -- returns the number of elements.
clear -- removes all elements from the container.
begin -- returns an iterator pointing to the beginning of the container.
end -- returns an iterator pointing to the end of the container.
</code>```

There's also a fill constructor, range constructor, etc. (and you can even pass in your own memory allocator which usually isn't that helpful for something like vector but can make a huge difference for linked structures).

The linked-list, std::list, conforms to the same interface requirements except with some minor differences in this context like a push_front member function which is omitted from std::vector deliberately to discourage its use there.

You can easily wrap all these containers and, with little effort, apply a universal interface... maybe with functions like so:

```<code>push_front -- insert to front.
push_back -- insert to back.
erase -- erase anywhere.
insert -- insert anywhere with no regard about where the element goes.
insert_sorted -- do an insertion sort.
...
</code>```

Etc. It won't take much time to wrap all applicable existing C++ containers to conform to this universal interface of your design as well as implement new ones that conform to it, and then you can benchmark your heart out and generate graphs and whatever you want.

A major thing to note about C++ is the iterator design driving algorithms. You can implement a custom data structure there, and by merely exposing iterators, hundreds of existing algorithms (not just standard but also third party) suddenly become applicable to your data structure with no extra effort. There's no need to implement like a sort method for your custom data structure, for example, as std::sort will work on it once you expose iterators to it.

Title: Standardized Data Structure Interface

Body:
Is there a language, or a language-agnostic design pattern, that makes
  it easy to define a generic public interface that works with any data
  structure?

Haskell seems like an awesome suggestion, but maybe a bit hardcore. At least I'm a little bit afraid of Haskell (it's a language whose code always inspires me, but I never actually got the nerve to try anything substantial).

I'd personally recommend C++ for this since the code generation of C++ templates allows you to eliminate any abstraction cost (dynamic dispatch, i.e.) out of the picture and just focus on the efficiency of the data structures themselves while likewise mutating the data structure easily (might be a little bit hard in functional languages without kind of changing the whole way you approach data structures). It's one of the few languages I personally know where you can write a contiguous data structure which performs just as well for random access as a plain old array, e.g., since the optimizer just squashes all that code structure you built down to smithereens.

It also comes with a pretty complete set of standard containers (though missing a few semi-common ones like tries) with a "near" data structure-agnostic interface. A little bit of wrapping should give you a universal interface that lets you do whatever you want, at least for value types (set vs. map). Key/value associative containers are a bit harder to generalize and might need to be in their own category, simply because they tend to call for a very different interface design.

The key to doing this to me is to define your universal interface. A C++ standard sequence like vector has these functions:

push_back -- appends an element to the back of the container.
insert -- inserts an element to any place in the container.
erase -- erases an element from any place in the container.
range insert -- inserts multiple elements to any place in the container.
range erase -- removes a range of elements from any place in the container.
empty -- returns size() == 0.
size -- returns the number of elements.
clear -- removes all elements from the container.
begin -- returns an iterator pointing to the beginning of the container.
end -- returns an iterator pointing to the end of the container.

There's also a fill constructor, range constructor, etc. (and you can even pass in your own memory allocator which usually isn't that helpful for something like vector but can make a huge difference for linked structures).

The linked-list, std::list, conforms to the same interface requirements except with some minor differences in this context like a push_front member function which is omitted from std::vector deliberately to discourage its use there.

You can easily wrap all these containers and, with little effort, apply a universal interface... maybe with functions like so:

push_front -- insert to front.
push_back -- insert to back.
erase -- erase anywhere.
insert -- insert anywhere with no regard about where the element goes.
insert_sorted -- do an insertion sort.
...

Etc. It won't take much time to wrap all applicable existing C++ containers to conform to this universal interface of your design as well as implement new ones that conform to it, and then you can benchmark your heart out and generate graphs and whatever you want.

A major thing to note about C++ is the iterator design driving algorithms. You can implement a custom data structure there, and by merely exposing iterators, hundreds of existing algorithms (not just standard but also third party) suddenly become applicable to your data structure with no extra effort. There's no need to implement like a sort method for your custom data structure, for example, as std::sort will work on it once you expose iterators to it.


问:
Status transitions with extra information in RESTful interfaces
How would you design a REST interface that triggers a status change of an object, but requires additional properties in that moment? For example, the deliverer of a package needs to change the status of the package from in transport to delivered, but also specify how it was delivered (letterbox or in person).

I see two possibilities:

POST /packages/:id/deliver with deliveredTo as request body

PATCH /packages/:id with status=delivered&deliveredTo=... as request body

It is generally considered best practice to use the methods POST, PUT or PATCH to update the state of resources in a RESTful API. RPC-style Actions should be avoided.

The problem I see with the second approach is that validation is hard. The initial POST /packages must not accept the deliveredTo field, but the PATCH request that includes status=delivered requires it. This is not only cumbersome to implement (as the frameworks do not usually support it), but also makes for a complicated  API.

So is this a case where custom actions are appropriate?

答:
Would it help you to have more resources?

/packages/12345/status

/packages/12345/status/latest

/packages/12345/status/versions/7

/packages/12345/status?at=20150630T1138-0600

/packages/12345/history/delivery/status

/packages/12345/history/latest/status

/paclages/12345/history/20150630/updates/2

Ceci n'est-pas un package.  Different use cases can use different identifiers to manipulate "the same" data.

Put another way, it's a uniform resource identifier, not a uniform domain entity identifier.  Having many resources that represent a single entity offers you a lot of flexibility.

References

The specification of PUT in RFC 2616 support the notion that a single resource can by represented by more than one URI

A single resource MAY be identified by many different URIs. For
example, an article might have a URI for identifying "the current
version" which is separate from the URI identifying each particular
version. In this case, a PUT request on a general URI might result in
several other URIs being defined by the origin server.

This language is substantially changed in RFC 7231

A PUT request applied to the target resource can have side effects on
other resources.  For example, an article might have a URI for
identifying "the current version" (a resource) that is separate from
the URIs identifying each particular version (different resources
that at one point shared the same state as the current version
resource).  A successful PUT request on "the current version" URI
might therefore create a new version resource in addition to changing
the state of the target resource, and might also cause links to be
added between the related resources.

Fielding's thesis has this to say

For example, the “authors’ preferred version” of an academic paper is a mapping whose value changes over time, whereas a mapping to “the paper published in the proceedings of conference X” is static. These are two distinct resources, even if they both map to the same value at some point in time. The distinction is necessary so that both resources can be identified and referenced independently.


问:
Why does the documentation on some languages say "equivalent to" rather than "is"?
Why does the documentation on some languages say "equivalent to" rather than "is"?

For example, the Python Docs say

itertools.chain(*iterables)

...

Equivalent to:

```<code>def chain(*iterables):
    # chain('ABC', 'DEF') --> A B C D E F
    for it in iterables:
        for element in it:
            yield element
</code>```

Or this C++ reference on find_if:

The behavior of this function template is equivalent to:

```<code>template<class InputIterator, class UnaryPredicate>
  InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  while (first!=last) {
    if (pred(*first)) return first;
    ++first;
  }
  return last;
}
</code>```

If that's not the actual code, can't they post it? And if it is the actual code, why do they have to say it's "Equivalent" rather than simply "is"?

答:
Because the standard writers don't want to actually assert an implementation.  They want to define what it does, but not necessarily how it does it.  So, for example, if you look at the GNU C++ version of find_if, you will see that the implementation is slightly different from what you give, which is based on the C++ standard:

```<code>template<typename _InputIterator, typename _Predicate>
inline _InputIterator
__find_if(_InputIterator __first, _InputIterator __last,
    _Predicate __pred, input_iterator_tag)
{
    while (__first != __last && !bool(__pred(*__first)))
     ++__first;
       return __first;
}
</code>```

This is functionally equivalent to what the standard has, but not exactly the same.  This gives compiler writers flexibility.  There may be a better way to do it  for a particular platform.  The implementor may wish to use a different coding style.

This is particularly true for scripting languages like python in that the implementor may decided to implement in a completely different language for performance reasons.  Someone implementing python may, for instance, write itertools.chain(*iterables) in C++.  This is perfectly fine if the standard says "equivalent to" as long as the code does the same as the provided python.  If the standard said "is" instead, then implementors would be required to either implement in that language, or not meet the standard.

In summary:

Because they don't want to prevent an implementation from writing better code than the standard provided

Because they don't want to prevent an implementation from using an entirely different language, to improve performance

Body:
Because the standard writers don't want to actually assert an implementation.  They want to define what it does, but not necessarily how it does it.  So, for example, if you look at the GNU C++ version of find_if, you will see that the implementation is slightly different from what you give, which is based on the C++ standard:

template<typename _InputIterator, typename _Predicate>
inline _InputIterator
__find_if(_InputIterator __first, _InputIterator __last,
    _Predicate __pred, input_iterator_tag)
{
    while (__first != __last && !bool(__pred(*__first)))
     ++__first;
       return __first;
}

This is functionally equivalent to what the standard has, but not exactly the same.  This gives compiler writers flexibility.  There may be a better way to do it  for a particular platform.  The implementor may wish to use a different coding style.

This is particularly true for scripting languages like python in that the implementor may decided to implement in a completely different language for performance reasons.  Someone implementing python may, for instance, write itertools.chain(*iterables) in C++.  This is perfectly fine if the standard says "equivalent to" as long as the code does the same as the provided python.  If the standard said "is" instead, then implementors would be required to either implement in that language, or not meet the standard.

In summary:

Because they don't want to prevent an implementation from writing better code than the standard provided

Because they don't want to prevent an implementation from using an entirely different language, to improve performance


问:
How does a variable introduce state?
I was reading the "C++ Coding Standards" and this line was there:

Variables introduce state, and you should have to deal with as little state as possible, with lifetimes as short as possible.

Doesn't anything that mutates eventually manipulate state? What does you should have to deal with as little state as possible mean?

In an impure language such as C++, isn't state management really what you are doing? And what are other ways to deal with as little state as possible other than limiting variable lifetime?

答:
Doesn't anything that mutates eventually manipulate state?

Yes, but if it's behind a member function of a small class that is the sole entity in the entire system that can manipulate its private state, then that state has a very narrow scope.

What does you should have to deal with as little state as possible
  mean?

From the variable's standpoint: as few lines of code should be able to access it as possible. Narrow the variable's scope to the minimum.

From the line of code's standpoint: as few variables should be accessible from that line of code as possible. Narrow the number of variables that the line of code can possibly access (it doesn't even matter that much whether it does access it, all that matters is whether it can).

Global variables are so bad because they have maximum scope. Even if they're accessed from 2 lines of code in a codebase, from the line of code's POV, a global variable is always accessible. From the variable's POV, a global variable with external linkage is accessible to every single line of code in the entire codebase (or every single line of code that includes the header anyway). In spite of only being actually accessed by 2 lines of code, if the global variable is visible to 400,000 lines of code, your immediate list of suspects when you find it was set to an invalid state will then have 400,000 entries (perhaps quickly reduced to 2 entries with tools, but nevertheless, the immediate list will have 400,000 suspects and that's not an encouraging starting point).

Chances are, likewise, that even if a global variable starts out only being modified by 2 lines of code in the entire codebase, the unfortunate tendency of codebases to evolve backwards will tend to have that number drastically increase, simply because it can increase as many developers, frantic to meet deadlines, see this global variable and realize they can take shortcuts through it.

In an impure language such as C++, isn't state management really what
  you are doing?

Largely, yes, unless you're using C++ in a very exotic way which has you dealing with custom-made immutable data structures and pure functional programming throughout -- it's also often the source of most bugs when state management becomes complex, and complexity is often a function of the visibility/exposure of that state.

And what are other ways to deal with as little state as possible other
  than limiting variable lifetime?

All of these are in the realm of limiting a variable's scope, but there are many ways to do this:

Avoid raw global variables like the plague. Even some dumb global setter/getter function narrows the visibility of that variable drastically, and at least allows some way of maintaining invariants (ex: if the global variable should never be allowed to be a negative value, the setter can maintain that invariant). Of course, even a setter/getter design on top of what would otherwise be a global variable is pretty poor design, my point is just that it's still way better.

Make your classes smaller when possible. A class with hundreds of member functions, 20 member variables, and 30,000 lines of code implementing it would have rather "global" private variables, since all those variables would be accessible to its member functions which consist of 30k lines of code. You might say the "state complexity" in that case, while discounting local variables in each member function, is 30,000*20=600,000. If there were 10 global variables accessible on top of that, then the state complexity might be like 30,000*(20+10)=900,000. A healthy "state complexity" (my personal kind of invented metric) should be in the thousands or below for classes, not tens of thousands, and definitely not hundreds of thousands. For free functions, say hundreds or below before we start to get serious headaches in maintenance.

In the same vein as above, don't implement something as a member function or friend function that can otherwise be nonmember, nonfriend using only the class's public interface. Such functions cannot access the class's private variables, and thus reduce the potential for error by reducing the scope of those private variables.

Avoid declaring variables long before they're actually needed in a function (i.e., avoid legacy C style which declares all variables at the top of a function even if they're only needed many lines below). If you do use this style anyway, at least strive for shorter functions.

Beyond Variables: Side Effects

A lot of these guidelines I listed above is tackling direct access to raw, mutable state (variables). Yet in a sufficiently complex codebase, just narrowing the scope of raw variables won't be enough to easily reason about correctness.

You could have, say, a central data structure, behind a totally SOLID, abstract interface, fully capable of perfectly maintaining invariants, and still end up running into a lot of grief due to the wide exposure of this central state. An example of central state which isn't necessarily globally accessible but merely widely-accessible is the central scene graph of a game engine or the central layer data structure of Photoshop.

In such cases, the idea of "state" goes beyond raw variables, and just to data structures and things of that sort. It likewise helps to reduce their scope (reduce the number of lines that can call functions that indirectly mutate them).

Note how I deliberately marked even the interface as red here,
  since from the broad, zoomed-out architectural level, accessing that
  interface is still mutating state, albeit indirectly. The class can
  maintain invariants as a result of the interface, but that only goes
  so far in terms of our ability to reason about correctness.

In this case, the central data structure is behind an abstract interface which may not even be globally-accessible. It might merely be injected and then indirectly mutated (through member functions) from a boatload of functions in your complex codebase.

In such a case, even if the data structure perfectly maintains its own invariants, weird things can happen at a broader level (ex: an audio player may maintain all kinds of invariants like that the volume level never goes outside the range of 0% to 100%, but that doesn't protect it from the user hitting the play button and having a random audio clip other than the one he most recently-loaded start playing as an event is triggered which causes the playlist to reshuffle in a valid way but still undesired, glitchy behavior from the broad user perspective).

The way to protect yourself in these complex scenarios is to "bottleneck" the places in the codebase that can call functions which ultimately cause external side effects even from this kind of broader view of the system that goes beyond raw state and beyond interfaces.

As odd as this looks, you can see that no "state" (shown in red, and this does not mean "raw variable", it just means an "object" and possibly even behind an abstract interface) is being accessed by numerous places. Functions each have access to a local state which is also accessible by a central updater, and the central state is only accessible to the central updater (making it no longer central but rather local in nature).

This is only for really complex codebases, like a game which spans 10 million lines of code, but it can help tremendously in reasoning about the correctness of your software, and finding that your changes yield predictable results, when you significantly limit/bottleneck the number of places that can mutate critical states that the entire architecture revolves around to function correctly.

Beyond raw variables is external side effects, and external side effects are a source of error even if they're confined to a handful of member functions. If a boatload of functions can directly call those handful of member functions, then there's a boatload of functions in the system that can indirectly cause external side effects, and that raises complexity. If there's only one place in the codebase that has access to those member functions, and that one path of execution is not triggered by sporadic events all over the place, but is instead executed in a very controlled, predictable fashion, then it reduces complexity.

State Complexity

Even the complexity of state is a rather important factor to take into account. A simple structure, widely-accessible behind an abstract interface, is not so hard to mess up.

A complex graph data structure which represents the core logical representation of a complex architecture is pretty easy to mess up, and in a way that doesn't even violate the graph's invariants. A graph is many times more complex than a simple structure, and so it becomes even more crucial in such a case to reduce the perceived complexity of the codebase to reduce the number of places that have access to such a graph structure to the absolute minimum, and where that kind of "central updater" strategy which inverts to a pull paradigm to avoid sporadic, direct pushes to the graph data structure from all over the place can really pay off.

Title: How does a variable introduce state?