问:
Is it safe in Haskell to save a data structure to a file using "show", and retrieve it using "read"?
Say I have the following types:

```<code>type EndsTup = (Int,Int)
    -- (0-based index from start or end, Frequency)
type FreqTup = (Char, [EndsTup], [EndsTup])
    -- (Character, Freqs from start, Freqs from end)
type FreqData = [FreqTup]
    -- 1 entry in the list for each letter
</code>```

Which I'm using to store data regarding the frequency of a character's position in a word. If I want to then save this to file, is it safe (as in guaranteed not to corrupt if it's written without error) to convert the structure to a string using show, and then read it using something like:

```<code>readData <- readFile filePath
let reconstructed = read readData :: FreqData
</code>```

I'm just asking because that seems "too easy". Is this how it's typically done?

答:
I haven't tried it, but all signs point to "yes", as long as you use the derived instances.

The Prelude has this to say about Show:

Derived instances of Show have the following properties, which are compatible with derived instances of Read:

The result of show is a syntactically correct Haskell expression containing only constants, given the fixity declarations in force at the point where the type is declared. It contains only the constructor names defined in the data type, parentheses, and spaces. When labelled constructor fields are used, braces, commas, field names, and equal signs are also used.

If the constructor is defined to be an infix operator, then showsPrec will produce infix applications of the constructor.

the representation will be enclosed in parentheses if the precedence of the top-level constructor in x is less than d (associativity is ignored). Thus, if d is 0 then the result is never surrounded in parentheses; if d is 11 it is always surrounded in parentheses, unless it is an atomic expression.

If the constructor is defined using record syntax, then show will produce the record-syntax form, with the fields given in the same order as the original declaration.

And it has this to say about Read:

Derived instances of Read make the following assumptions, which derived instances of Show obey:

If the constructor is defined to be an infix operator, then the derived Read instance will parse only infix applications of the constructor (not the prefix form).

Associativity is not used to reduce the occurrence of parentheses, although precedence may be.

If the constructor is defined using record syntax, the derived Read will parse only the record-syntax form, and furthermore, the fields must be given in the same order as the original declaration.

The derived Read instance allows arbitrary Haskell whitespace between tokens of the input string. Extra parentheses are also allowed.

Emphasis mine.


问:
Is duplicate syntax for defining named functions a bad language design decision?
I am modelling a programming language for fun, and the syntax is heavily influenced by Scala - specifically function definitions.

I have encountered a design problem because my language does not differentiate between functions defined via the def syntax (class methods) and anonymous functions assigned to values (created using =>) - it removes the differences in both implementation and behaviour.

The result is that the following two definitions mean the same thing:

```<code>def square(x: Int) = x*x

val square = (x: Int) => x*x
</code>```

There is no reason for the latter form (immediate anonymous function assignment) to be used in any normal situation - it's simply possible to use it instead of the def form.

Would having such duplicate syntax for defining named functions hurt the orthogonality of the language or some other design aspect?

I prefer this solution because it allows for short and intuitive definitions of methods and named functions (via def), and short definitions of anonymous functions (using =>).

Edit: Scala does differentiate between the two - anonymous functions are not the same as methods defined with def in Scala. The differences are relatively subtle though - see the posts I linked before.

答:
I think that having two constructs that mean the same thing but look different should be kept to an absolutely minimum in a language. Any duplication increases how difficult it is to read (and thus write/modify code in ) your language. Eliminating all duplication is unavoidable in a language that can create arbitrary constructs (for example, the equivalence of iteration vs recursion).

So in this case, I think it could be designed better here. A single way to define functions makes the most sense to me. In this case, it sounds like the two scala statements you have actually do have slightly different implications, which again is probably not good design (probably best to have something clear that states what the differences, like a keyword).

In fact, you can apply this principle not only to named functions, but to any function. Why have any difference in defining named functions and anonymous functions? In Lima, functions are always defined like this: fn[<arguments>: <statements>]. If you want it to be "named" you can assign it to a variable: var x = fn[<arguments: <statements>], and if you want to pass it in to another function anonymously: function[fn[<arguments: <statements>]]. If you want it hoisted, make it constant const var x = fn[<arguments: <statements>]. The single form makes it obvious that they mean the same thing.

ContentLicense: CC BY-SA 3.0


问:
Static vs. non-static? (with non-OOP functions)
Although this question has come up before, mine is different because it is not supposed to cover anything OOP but only plain (ANSI) C.

Especially in open-source software, I usually encounter a plethora of functions (please don't call them methods since we're not in OOP) with the static keyword preceding the data type.

But what effect does this actually have with plain C? In my own projects, I've never had an occasion where the static keyword was actually needed. (Although a so-called expert programmer would probably have given me the advice, "This function should be declared static" and I would probably have replied in my own sarcastic way: "Uh-huh. Well, it works as-is, after all". :)).

From reading the OSS code, I assumed it might just generate less overhead when compiling the project. However, CPU have advanced in performance so much that I've wondered many times why there is such an ongoing interest to declare functions static even though it might need some benchmark tool to measure the differences in execution speed.

答:
Static, when applied to a function, means that the function has local scope or file scope, which will disallow someone from declaring a prototype to that function in a header file and using it somewhere else than where it was declared.

This has no performance implications, but is a good practice nevertheless. Why? Because it reduces scope. When the programmer spots a static function, it is an indication that the function will not be used in some other unknown place, thus, if you break that function, at least you know the damage should be confined to the source file in question.

Note though that static is not a hard guarantee that the function can't be called outside the file where is was declared, since someone can still grab a pointer to the function and externalize that pointer.


问:
where exactly should python business logic be placed in django
I have just begun to  learn Django/Python/Web Development. This problem has been troubling me for a while now.

I am creating an application with multiple templates in Django. I have a views.py which is basically just rendering the responses to the respective templates and I have a models.py where I have structured my DB. In one of my templates, I need to upload an image (which I am able to do) and  I need to run a logic which is based on the features of the uploaded image (not yet done). This logic involves a lot of heavy calculations. After performing the calculations, the logic should return some processed information (coordinates) to the template.

I have been able to do all this actions successfully in a standalone python desktop application calling python files one after the other. However, since I now  want to make this a web application I have begun using the Django framework.

I have done a lot of searching but I am still not able to figure out where exactly should I place this Python file containing all the logic. Should I have another class based file (logic.py) and call it from the view.py? I googled and found that many developers are placing their business logic in their models.py in Django. However, I feel it is intuitively not right  since model should exclusively communicate with the back end. Any help would be appreciated.Thanks in advance.

答: Daniel Greenfeld, co-author of "Two Scoops of Django, recommends the business logic should be in the models "when possible, or in the forms if you must." As for Bart's possible duplicate, django may be similar to MVC but it is not MVC. As explained here in the official django documentation faq. @adrita, I think you need may need to go review the official documentation to help you understand the concept of models, views, and templates a bit better.</p>


问:
MVC/P in Desktop Application
I am developping a desktop application in C#, and have separated different layers in an MVC-ish architecture.

As I have switched from GTK# to XWT, only views had to be adjusted, so the seperation of layers was done quite OK.

As XWT does not have a layout designer, everything has to be set up in code, which in turn led to an architectural problem:

I have one controller for displaying outlets, inlets and connections.

This controller sends data to one view (outlined in red). This view in turn has subviews (green and blue), that only communicate with the view in red.

On scrolling / collapsing / expanding the treeviews, the green view send events, which are received by the red view, which in turn trigger redrawing in the blue view.

Controller does not see the green or blue views, every change in connections / outlets / inlets are only sent to the red view.

My problem: As I understand MVC, views should not have much logic. But the green views is a class of 300 lines, the red view's class has 200 lines, which is too many.

What architectural problem can arise from this? Am I overlooking a fault in my MVC logic?

答:
Straight forward, I think MVC is not a very good way to design a desktop application in C#.
(given C# AND desktop application implying that dot net framework including wpf is allowed).

The most valued and best way to design a desktop UI in C# is the MVVM pattern.

MVVM, meaning Model-View-ViewModel has the most direct support from C# UI features and everything seems to just be made for MVVM.

The structure is just little different from MVC. There is no controller part.
(Controller in the sense of MVC formerly was only a way of handling e.g. user input events)

In MVVM you get a three-layered architecture

You have a
Model (domain objects, database access, repository pattern, ...)

ViewModel (some kind of mediator between view and model, handling selected item, translating text, ...)

View (this is just what the user sees and nothing more, no logic here except simple conversion to the user desired format of strings etc)

Please investigate on MVVM. There is a fantastic video showing the core techniques by Jason Dollinger on lab49, which can be found here. It is always worth investing that one hour.

Title: MVC/P in Desktop Application


答:
I have done a lot of searching but I am still not able to figure out where exactly should I place this Python file containing all the logic.

There are a number of options, depending on what your requirements are:

Add the logic to e.g. the Image model. This is a useful option if you need to store per-image meta data in the database, and each model instance (each image) is processed by itself.

Add the logic as a plain Python Image class, e.g. in a file called image.py. Nothing in Django restricts you from adding logic other than that in the views or models modules. This is a good option if the image logic is a central component of your Django app (e.g. a Image processing app).

Create a separate Python project that provides the logic, then call it from your views. Make sure to install this project in your Django app's Python environment. This option is valid if the purpose of your Django app is to upload and view images, or to show the results of the image processing in direct response to a user's request, but where the image processing could be used by other projects too.

Create a separate app that processes requests asynchronously and is run separately from your Django app. This option is useful if you need to decouple the image processing from the request cycle of the app, process large number of images, or where each calculation takes too much time to solve within a request cycle's time (say within at most 500ms to 1s).

I feel it is intuitively not right since model should exclusively communicate with the back end.

There is nothing in Django that requires a model to communicate with the back end, or rather the database. I think you are mixing the semantics of what Django typically considers a model (namely, an abstraction of one or several tables in the database), v.s. the term model as a design construct (e.g. as in Domain Driven Design).

Title: where exactly should python business logic be placed in django

Body:
I have just begun to  learn Django/Python/Web Development. This problem has been troubling me for a while now.

I am creating an application with multiple templates in Django. I have a views.py which is basically just rendering the responses to the respective templates and I have a models.py where I have structured my DB. In one of my templates, I need to upload an image (which I am able to do) and  I need to run a logic which is based on the features of the uploaded image (not yet done). This logic involves a lot of heavy calculations. After performing the calculations, the logic should return some processed information (coordinates) to the template.

I have been able to do all this actions successfully in a standalone python desktop application calling python files one after the other. However, since I now  want to make this a web application I have begun using the Django framework.

I have done a lot of searching but I am still not able to figure out where exactly should I place this Python file containing all the logic. Should I have another class based file (logic.py) and call it from the view.py? I googled and found that many developers are placing their business logic in their models.py in Django. However, I feel it is intuitively not right  since model should exclusively communicate with the back end. Any help would be appreciated.Thanks in advance.


问:
What exactly is the build number in MAJOR.MINOR.BUILDNUMBER.REVISION
What I think about Build Numbers is that whenever a new nightly build is created, a new BUILDNUMBER is generated and assigned to that build. So for my 7.0 version application the nightly builds will be 7.0.1, 7.0.2 and so on. Is it so? Then what is the use of a REVISION after the build number? Or is the REVISION part being incremented after each nightly build? I am a little confused here... do we refer to each nightly build as a BUILD?

The format is mentioned here: AssemblyVersion - MSDN

答:
I've never seen it written out in that form.  Where I work, we are using the form MAJOR.MINOR.REVISION.BUILDNUMBER, where:

MAJOR is a major release (usually many new features or changes to the
UI or underlying OS)

MINOR is a minor release (perhaps some new
features) on a previous major release

REVISION is usually a fix for
a previous minor release (no new functionality)

BUILDNUMBER is
incremented for each latest build of a revision.

For example, a revision may be released to QA (quality control), and they come back with an issue which requires a change.  The bug would be fixed, and released back to QA with the same REVISION number, but an incremented BUILDNUMBER.

ContentLicense: CC BY-SA 2.5

ContentLicense: CC BY-SA 4.0


问:
Desktop to Web - How to deal with user-interactive workflows
I start a new project this summer, consisting in developing a web version of a proprietary desktop ERP.

The main goal of my company is to be able to propose a web version of its ERP, with all advantages it involves (mobility, possibility of selling SaaS versions, modern look and components ...), without losing any business feature.  By this, I mean that us developers can't rework the business side of the app. The main goal is to be able to translate same processes into web application.

Business layer of the older version is not directly reusable, since it's really GUI-dependent. Those business process were rewritten as UML diagrams, which will be used as support for us to develop the new app.

The problem I meet is that I don't know how to deal with process that need user interactions. For example :

On validation of a sale order, the validation process checks all products it contains, verifying if there is available stock, and then perform different operations. If there is no stock available, the user is asked if he wants to cancel the order, remove this product or select another one equivalent. It works like a Javascript alert or confirm : current "thread" (ie validation process) is on hold, waiting for user interaction. After user's choice, it finishes dealing with the current product, and then validates the next one, and so on.

How to deal with this kind of processes with a web application ? Is there some framework, design pattern or something else that permits to write this kind of business processes, able to start and hold like that ?

A solution could be to split those business processes into smaller ones. For my example, we would have 2 sub-processes : the first one checks all products and flags the problematic ones. Then the user has a screen to decide what to do on flagged products, and validates. At this moment we are sure all products are OK, we can start the second sub-process to perform the others operations.

The problem with it is that even if it's pretty simple on this example, it can be really more complicated. Some process have a lot of users interactions like this one, and then could be splitted into 10 subparts. Like I earlier precised, we don't want to modify or rethink business process, to be sure that we lose nothing or introduce new business bugs.

Does someone has an experience about it ? Do you know some way to deal with this kind of desktop-to-web developments ?

EDIT 15/07/14

There was some misunderstanding about this post, surely related to my poor english expression and vocabulary.

To summarize the problem :

I got a bunch of business workflows described into UML diagrams. They comes from a huge 30-year-old CAMM (production management ERP). The project is to redevelop this application under Java web environment.
The main point is that some of those workflows are user-dependent, since, in the middle of the processing, they need a user-interaction. Because web applications are based on a client-server architecture, I don't know how to port them.
Reworking/rethinking these workflows is not an option, because it would be too much time-consuming. I need a way to simulate a desktop application on a web app, like Wt, but for Java (i'm not talking about UI but about how to develop workflows ), or to define rules to make those user-dependent workflows web-compatibles.

答:
Disclaimer: I am not a super experienced web developer.

I believe that javascript/the client side of web apps are not usually written this way, as no matter what, in most browsers all js code is run in one thread. However, you can simulate this behavior, with something like this (I have never used it, it's just what I found), to pause a thread (pseudocode):

```<code>var stuffIsDone = false

doInAnotherThread(function () {
    // blah blah blah, do stuff, load purchase, talk to server, whatever

    // ...
    stuffIsDone = true
})

// DO NOT PUT THE BLOCKING WHILE LOOP IN THE MAIN THREAD, IT WILL FREEZE THE INTERFACE
doInAnotherThread(function () {
    while (!stuffIsDone) {} // Do nothing until stuff is done

    // stuff has been done, do whatever
})
</code>```

Body:
Disclaimer: I am not a super experienced web developer.

I believe that javascript/the client side of web apps are not usually written this way, as no matter what, in most browsers all js code is run in one thread. However, you can simulate this behavior, with something like this (I have never used it, it's just what I found), to pause a thread (pseudocode):

var stuffIsDone = false

doInAnotherThread(function () {
    // blah blah blah, do stuff, load purchase, talk to server, whatever

    // ...
    stuffIsDone = true
})

// DO NOT PUT THE BLOCKING WHILE LOOP IN THE MAIN THREAD, IT WILL FREEZE THE INTERFACE
doInAnotherThread(function () {
    while (!stuffIsDone) {} // Do nothing until stuff is done

    // stuff has been done, do whatever
})


答:
Every function or variable in a C program which is not declared static is required to have a unique name.  If two or more programmers writing different parts of a system each write a function called "fred", and both functions are declared static, then the fact that there are two "fred" functions will be completely irrelevant (and thus not pose a problem).  If all but one of the functions is static, things are still likely to be okay, but there could still be possible problems if a programmer adds an extern declaration somewhere intending it to refer to one function, but the intended function is static and the declaration actually binds to a non-static function declared elsewhere.  If there are two or more "fred" functions which aren't static, problems are almost guaranteed.  In most cases, the linker will reject the program; in some cases (e.g. if one of the method is tagged with a "weak" attribute) the linker won't squawk, but code which is supposed was intended to invoke one method might invoke the other.  If both methods happen to behave identically, that might not pose a problem, but if the methods are different, such substitution is likely to be disastrous.

If programmers default to making their methods non-static, name collisions are likely.  Making things static by default avoids that problem.

Title: Static vs. non-static? (with non-OOP functions)

Body:
Although this question has come up before, mine is different because it is not supposed to cover anything OOP but only plain (ANSI) C.

Especially in open-source software, I usually encounter a plethora of functions (please don't call them methods since we're not in OOP) with the static keyword preceding the data type.

But what effect does this actually have with plain C? In my own projects, I've never had an occasion where the static keyword was actually needed. (Although a so-called expert programmer would probably have given me the advice, "This function should be declared static" and I would probably have replied in my own sarcastic way: "Uh-huh. Well, it works as-is, after all". :)).

From reading the OSS code, I assumed it might just generate less overhead when compiling the project. However, CPU have advanced in performance so much that I've wondered many times why there is such an ongoing interest to declare functions static even though it might need some benchmark tool to measure the differences in execution speed.


答:
Read up on asynchronous programming

It sounds like your original desktop app was tightly coupled with the GUI with functions not continuing until user chooses decisions from popups.

The web, and many GUI frameworks, just don't work like this - all operations that may require user input have to provide a delegate/callback so that processing can continue.

It's really not that bad, but a massive change from your current design. IMO it's worth your time to break down your current design to support asynchronous programming, regardless of Web or GUI toolkit.

Title: Desktop to Web - How to deal with user-interactive workflows

Body:
I start a new project this summer, consisting in developing a web version of a proprietary desktop ERP.

The main goal of my company is to be able to propose a web version of its ERP, with all advantages it involves (mobility, possibility of selling SaaS versions, modern look and components ...), without losing any business feature.  By this, I mean that us developers can't rework the business side of the app. The main goal is to be able to translate same processes into web application.

Business layer of the older version is not directly reusable, since it's really GUI-dependent. Those business process were rewritten as UML diagrams, which will be used as support for us to develop the new app.

The problem I meet is that I don't know how to deal with process that need user interactions. For example :

On validation of a sale order, the validation process checks all products it contains, verifying if there is available stock, and then perform different operations. If there is no stock available, the user is asked if he wants to cancel the order, remove this product or select another one equivalent. It works like a Javascript alert or confirm : current "thread" (ie validation process) is on hold, waiting for user interaction. After user's choice, it finishes dealing with the current product, and then validates the next one, and so on.

How to deal with this kind of processes with a web application ? Is there some framework, design pattern or something else that permits to write this kind of business processes, able to start and hold like that ?

A solution could be to split those business processes into smaller ones. For my example, we would have 2 sub-processes : the first one checks all products and flags the problematic ones. Then the user has a screen to decide what to do on flagged products, and validates. At this moment we are sure all products are OK, we can start the second sub-process to perform the others operations.

The problem with it is that even if it's pretty simple on this example, it can be really more complicated. Some process have a lot of users interactions like this one, and then could be splitted into 10 subparts. Like I earlier precised, we don't want to modify or rethink business process, to be sure that we lose nothing or introduce new business bugs.

Does someone has an experience about it ? Do you know some way to deal with this kind of desktop-to-web developments ?

EDIT 15/07/14

There was some misunderstanding about this post, surely related to my poor english expression and vocabulary.

To summarize the problem :

I got a bunch of business workflows described into UML diagrams. They comes from a huge 30-year-old CAMM (production management ERP). The project is to redevelop this application under Java web environment.
The main point is that some of those workflows are user-dependent, since, in the middle of the processing, they need a user-interaction. Because web applications are based on a client-server architecture, I don't know how to port them.
Reworking/rethinking these workflows is not an option, because it would be too much time-consuming. I need a way to simulate a desktop application on a web app, like Wt, but for Java (i'm not talking about UI but about how to develop workflows ), or to define rules to make those user-dependent workflows web-compatibles.


问:
How big can the binary code be?
Where does binary go in a computer? When you turn the computer on it points to the bios and runs through it. I get that. Then it loads data off something ( disk, flash, etc. ). But where does it go? Does the binary go in ram? Does that mean if my program is 2mb and ram is 32mb I can only address 30mb? I mainly want to know so I can tell how big my bin can be.

I'm just a little confused on this issue. I know it's platform specific. But in general where would it go, and in general what document would I look at to check this information?

答:
The bios runs off of a rom, it initializes the dram, enumerates the pcie, and a number of other things.

The bios then finds your or some program on the boot device, copies that to ram and runs it there.

the basic answer is yes if you have 32mb and your program is 2mb then there is 30mb left for heap and stack.

Virtual memory solutions first have to be set up and managed, but assuming that is being done it is possible to access the limits of the virtual memory space, or the media that is used behind the virtual memory space (hard disk, etc).  If your program is running off of the disk loaded by the bootloader, then you dont have virtual memory unless you implement it yourself so you are limited to the 32mb in your example.

Depending on how you write your code, globals vs locals, heap usage or not determines how much of that 32mb you can dig into with your actual binary, you will need some stack but the more local variables you use and the smaller and more nested your functions are the amount of stack usage can go way up.  That can be offset with globals but that can also chew up your ram quickly as well (these would likely be counted in your "binary" and be a known quantity vs stack which is fairly dynamic although can be somewhat computed).

Title: How big can the binary code be?


问:
What popular "best practices" are not always best, and why?
"Best practices" are everywhere in our industry.  A Google search on "coding best practices" turns up nearly 1.5 million results.  The idea seems to bring comfort to many; just follow the instructions, and everything will turn out fine.

When I read about a best practice - for example, I just read through several in Clean Code recently - I get nervous.  Does this mean that I should always use this practice?  Are there conditions attached?  Are there situations where it might not be a good practice?  How can I know for sure until I've learned more about the problem?

Several of the practices mentioned in Clean Code did not sit right with me, but I'm honestly not sure if that's because they're potentially bad, or if that's just my personal bias talking.  I do know that many prominent people in the tech industry seem to think that there are no best practices, so at least my nagging doubts place me in good company.

The number of best practices I've read about are simply too numerous to list here or ask individual questions about, so I would like to phrase this as a general question:

Which coding practices that are popularly labeled as "best practices" can be sub-optimal or even harmful under certain circumstances?  What are those circumstances and why do they make the practice a poor one?

I would prefer to hear about specific examples and experiences.

答:
Using const-keyword in c++

How hard is it to understand that functions starting with "Get..." are normally "const". Also has anyone seen evidence that compiler optimizes const-riddled code better? At least when comparing the following two later one performs faster (when optimization is enabled):

```<code>__forceinline void test(const int a);
test(1);
test(2);
test(3);

template<int a>
void test();
test<1>();
test<2>();
test<3>();
</code>```

Body:
Using const-keyword in c++

How hard is it to understand that functions starting with "Get..." are normally "const". Also has anyone seen evidence that compiler optimizes const-riddled code better? At least when comparing the following two later one performs faster (when optimization is enabled):

__forceinline void test(const int a);
test(1);
test(2);
test(3);

template<int a>
void test();
test<1>();
test<2>();
test<3>();


问:
Have there been studies on the effectiveness of OOP in managing software complexity?
OOP is often regarded as an effective strategy of managing complexity in software, as opposed to non-OOP procedural programming.

Have there been any studies testing this notion? Is it proven that OOP often helps manage complexity in large projects?

答:
I am not aware of any study with quantifiable measurements. As others have mentioned in comments to your question, it is practically impossible to achieve that. However there somewhat philosophical papers which try to answer that.

My favorite paper on that topic is Out of the Tar Pit by Ben Moseley & Peter Marks. It reasons with various statements from respectable sources about complex system design to quite interesting results.

Out of the Tar Pit concludes that function programming is actually the best paradigm to support solutions they are proposing. Which makes sense, because in my experience, complex OOP systems become very close to procedural over time and procedural start to look like OOP (they don’t have a syntax and other attributes, but an execution flow might become quite similar). The real difference comes with different paradigm or by combining it with OOP. At the moment, such paradigm is functional programming which is finally becoming usable in common business applications by common programmers (still getting there).


问:
Minimizability or readability?
I am authoring a lot of plugins for the content management system that I am writing. I believe it to be of utmost importance that script files (especially if they're plugins) should load quickly, which leads to me to the question that I've asked today?

What's more important for plugins, minimizability or readability?

Let's imagine that we live in an ideal world where code is always perfect. Should a plugin (which being perfect, the author doesn't expect the end user to read) be designed so that it takes up as little space as possible, or so that it readable by the end user.

For example, I'm writing a piece of code that spits out HTML and appends it to the body. I have replaced every instance of the tag 'div' with '!' and then used String[replace](/\!/g, 'div') to save four characters (therefore bytes?) for each declaration of a div element.

NB, [replace] is also a declared variable so that when it is minified it will read something to the effect of String[r](/\!/g,'div')

Am I caring too much about download speed or should care a bit more about readability. (IMO, most minifying techniques are easily reverse-engineered, but is it bad practice?)

Edit

Thanks for all the answers, you guys are great!

答:
By doing this, you actually are reducing both the readability and the extent to which the plugin can be minified.

Let's take your example of your HTML string by getting a HTML file with some
 tags. Running some sample code through a minifier, we get 380 bytes before gzip for the first one:174

```<code>var a="<div>a</div><br><div>bc</div><br><div>def</div><br><div>ghij</div><br><div>klmno</div><br><div>pqrsjt</div><br><div>uvwxyzA</div><br><div>BCDEFGHI</div><br><div>JKLMNOPQR</div><br><div>S</div>",b="<div>T</div><br><div>UV</div><br><div>WXY</div><br><div>Z`12</div><br><div>34567</div><br><div>890-=`</div><br><div>!@#$%^*</div><br><div>()_+[]{</div><br><div>}|;':,./</div>";
</code>```

For the second one, we get 347 bytes before gzip, a slight improvement:

```<code>var c='replace',a="<!>a</!><br><!>bc</!><br><!>def</!><br><!>ghij</!><br><!>klmno</!><br><!>pqrsjt</!><br><!>uvwxyzA</!><br><!>BCDEFGHI</!><br><!>JKLMNOPQR</!><br><!>S</!>"[c](/\!/g,"div"),b="<!>T</!><br><!>UV</!><br><!>WXY</!><br><!>Z`12</!><br><!>34567</!><br><!>890-=`</!><br><!>!@#$%^*</!><br><!>()_+[]{</!><br><!>}|;':,./?</!>"[c](/\!/g,"div");
</code>```

However, what you have to understand is that what's important most of the time important is the size of the file after being gzipped, not before. This is because most servers and browsers support sending files which have been compressed in this manner, reducing bandwidth usage.

When compressed, the DEFLATE algorithm (what gzip uses to compress files) already does what you would do manually, however you would have to have the additional size and loss of performance associated with the replacement code. As well, it's able to recognise string patterns which aren't easy to see with regular code without making your code completely unreadable.

With this example, what we end up finding is that after running compression on it (I used Zopfli to test this), the first script actually compresses down to 172 bytes, while the second can only be compressed down to 199 bytes, which is worse. The declaration for var c="replace" and [c](/\!/g,"div") takes up bytes in itself, and since gzip already places backreferences in the compressed file, it actually increases the size of the code.

Not only that, the performance is slightly worse because you'd have to replace each of that during runtime, which is worse than the time needed to unpack the gzipped file natively.

In fact, most minifiers actually do the opposite of what you've done, so that the gzipped size is reduced. See this discussion on the Closure Compiler Discuss group.

An FAQ for the Closure Compiler also covers this:

Closure Compiler inlined all my strings, which made my code size bigger. Why did it do that?

Most people compare code size by looking at two uncompressed
  JavaScript
  files. But that's a misleading way to look at code size, because your
  JavaScript
  files should not be served uncompressed. It should be served with gzip
  compression.

Closure Compiler assumes that you are using gzip compression. If you
  do not, you should. Configuring your server to gzip your
  code
  is one of the most effective and easiest optimizations that you can
  possibly do. The gzip algorithm
  works by trying to alias sequences of bytes in an optimal way.
  Aliasing strings manually almost always makes the compressed code size
  bigger, because it subverts gzip's own algorithm for aliasing. So
  Closure Compiler will (almost) always inline your strings when it can,
  because that will make your compressed code smaller.

If you know your client doesn't support gzip, the Java API has an
  aliasAllStrings option on the
  CompilerOptions
  class. Turning this on will make the compiler alias all your strings
  in the global scope.

Title: Minimizability or readability?

Body:
By doing this, you actually are reducing both the readability and the extent to which the plugin can be minified.

Let's take your example of your HTML string by getting a HTML file with some <div> tags. Running some sample code through a minifier, we get 380 bytes before gzip for the first one:174

var a="<div>a</div><br><div>bc</div><br><div>def</div><br><div>ghij</div><br><div>klmno</div><br><div>pqrsjt</div><br><div>uvwxyzA</div><br><div>BCDEFGHI</div><br><div>JKLMNOPQR</div><br><div>S</div>",b="<div>T</div><br><div>UV</div><br><div>WXY</div><br><div>Z`12</div><br><div>34567</div><br><div>890-=`</div><br><div>!@#$%^*</div><br><div>()_+[]{</div><br><div>}|;':,./</div>";

For the second one, we get 347 bytes before gzip, a slight improvement:

var c='replace',a="<!>a</!><br><!>bc</!><br><!>def</!><br><!>ghij</!><br><!>klmno</!><br><!>pqrsjt</!><br><!>uvwxyzA</!><br><!>BCDEFGHI</!><br><!>JKLMNOPQR</!><br><!>S</!>"[c](/\!/g,"div"),b="<!>T</!><br><!>UV</!><br><!>WXY</!><br><!>Z`12</!><br><!>34567</!><br><!>890-=`</!><br><!>!@#$%^*</!><br><!>()_+[]{</!><br><!>}|;':,./?</!>"[c](/\!/g,"div");

However, what you have to understand is that what's important most of the time important is the size of the file after being gzipped, not before. This is because most servers and browsers support sending files which have been compressed in this manner, reducing bandwidth usage.

When compressed, the DEFLATE algorithm (what gzip uses to compress files) already does what you would do manually, however you would have to have the additional size and loss of performance associated with the replacement code. As well, it's able to recognise string patterns which aren't easy to see with regular code without making your code completely unreadable.

With this example, what we end up finding is that after running compression on it (I used Zopfli to test this), the first script actually compresses down to 172 bytes, while the second can only be compressed down to 199 bytes, which is worse. The declaration for var c="replace" and [c](/\!/g,"div") takes up bytes in itself, and since gzip already places backreferences in the compressed file, it actually increases the size of the code.

Not only that, the performance is slightly worse because you'd have to replace each of that during runtime, which is worse than the time needed to unpack the gzipped file natively.

In fact, most minifiers actually do the opposite of what you've done, so that the gzipped size is reduced. See this discussion on the Closure Compiler Discuss group.

An FAQ for the Closure Compiler also covers this:

Closure Compiler inlined all my strings, which made my code size bigger. Why did it do that?

Most people compare code size by looking at two uncompressed
  JavaScript
  files. But that's a misleading way to look at code size, because your
  JavaScript
  files should not be served uncompressed. It should be served with gzip
  compression.

Closure Compiler assumes that you are using gzip compression. If you
  do not, you should. Configuring your server to gzip your
  code
  is one of the most effective and easiest optimizations that you can
  possibly do. The gzip algorithm
  works by trying to alias sequences of bytes in an optimal way.
  Aliasing strings manually almost always makes the compressed code size
  bigger, because it subverts gzip's own algorithm for aliasing. So
  Closure Compiler will (almost) always inline your strings when it can,
  because that will make your compressed code smaller.

If you know your client doesn't support gzip, the Java API has an
  aliasAllStrings option on the
  CompilerOptions
  class. Turning this on will make the compiler alias all your strings
  in the global scope.


问:
OpenGL's relationship to OpenGL ES (3.0)
I'm beginning my journey into graphics programming and want to learn OpenGL. Because I'm green to graphics programming but not to C and C++, a familiar question came up when I looked at OpenGL and ES... Is OpenGL a superset of OpenGL ES? I read in an ES 3.0 guide that it uses shader-based implementations that exist as part of OpenGL's embedded libraries, and that ES avoids using similar/redundant libraries provided by big 'ol OpenGL due to mobile hardware limitations... Are shader-based implementations which are a huge part of OpenGL ES less efficient solutions when programming on the desktop? OR should I look at the two APIs as different beasts altogether? thx in advance. </p>

答:
Desktop OpenGL and OpenGL ES share a lot of similarities. The older OpenGL, prior to programable shaders, is somewhat similar to ES v1, in which both relied on a fixed-function rendering pipeline (i.e.: just the C-API). GL ES 2 and above is a lot more like the modern desktop GL, since it requires the use of shaders and other modern rendering practices like the use of Vertex Buffers. In fact, there are two extensions to the desktop GL that aim at reducing the work of porting code from desktop to GL ES devices, by providing to the desktop version all the specific functions of GL ES. ARB_ES2_compatibility, ARB_ES3_compatibility

So I think it is fair to say that OpenGL ES is a subset of desktop GL. Both are converging to a unified API, and the overall "feel" of the library is pretty much the same for both.

If you are looking for a more detailed comparison of existing GL versions, I think your best bet is looking at the wiki History of OpenGL and the OpenGL ES wiki. There is also this SO thread that you might find worth reading.


问:
Can someone help me understand MVC?
I've read a few articles on the MVC pattern and tried to understand what it exactly is. But till now, what I get is a plain diagram showing 3 modules of Model, View and Controller. Some say that it helps increase code reuse (DRY), while I think it does the opposite.

I currently separate my application code into different directories, one for Viewing part (presentation: Html/Css/Js + client side req) and the other one for Core related functions. I haven't found any disadvantage to this approach yet. Maybe because I haven't developed big applications yet, just small hobby ones.

So, apart from this separation, what I find in MVC is some sort of url rewriting, which I think can be achieved if necessary. Is there something I am missing? There must be a reason developers are so inclined towards the MVC pattern.

答:
Models are essentially objects that wrap databases, and instances of those models are essentially objects that wrap rows in the database. Model instances have functions that allow them to change their internal state and interact with other model instances of a different type. This is where most of your business logic should live.

Controllers are essentially urls/routes that capture POST/GET data and perform LIMITED logic depending on the state of the application, such as redirection or displaying different views. They provide a shared scope for views and models to pull/store data. Controllers can be as simple as just passing the GET/POST data straight to the model and having the model figure out what to do from there (such as when saving data), and then telling the application which view to display. The model should not be allowed to determine what what parts of the view are displayed directly (models should not generate HTML directly, but should be passed to the view and the view can determine which attributes of the model to display).

Views are your simple HTML/CSS/JS templates with placeholders for certain variables. Most of the point of MVC is to make sure people stop putting logic in their views. Logic within the view should be minimal, mostly "if" statements and loops to display arrays of data.

Controllers help views by ensuring that logic in the views are minimized. For instance, if you have 10 different sidebars depending on the user type, it should be the controller that checks this and tells the view which one to display.

Models help controllers by ensuring that all business logic is contained. This way, logic dictating interactions between model instances is contained within the definition of the model. It helps ensure that the instance's current state is maintained by variables within the scope of that instance, instead of spread out over a bunch of global variables or variables that belong to other instances.

Title: Can someone help me understand MVC?


答:
Using unsigned int as iterator

When will they learn that using signed int is much safer and less bug-prone. Why is it sooo important that array index can only be positive number, that everyone is glad to overlook the the fact that 4 - 5 is 4294967295?

Title: What popular "best practices" are not always best, and why?

Body:
"Best practices" are everywhere in our industry.  A Google search on "coding best practices" turns up nearly 1.5 million results.  The idea seems to bring comfort to many; just follow the instructions, and everything will turn out fine.

When I read about a best practice - for example, I just read through several in Clean Code recently - I get nervous.  Does this mean that I should always use this practice?  Are there conditions attached?  Are there situations where it might not be a good practice?  How can I know for sure until I've learned more about the problem?

Several of the practices mentioned in Clean Code did not sit right with me, but I'm honestly not sure if that's because they're potentially bad, or if that's just my personal bias talking.  I do know that many prominent people in the tech industry seem to think that there are no best practices, so at least my nagging doubts place me in good company.

The number of best practices I've read about are simply too numerous to list here or ask individual questions about, so I would like to phrase this as a general question:

Which coding practices that are popularly labeled as "best practices" can be sub-optimal or even harmful under certain circumstances?  What are those circumstances and why do they make the practice a poor one?

I would prefer to hear about specific examples and experiences.


问:
Is the Fork/Join framework a bad match for the Java 8 Streams API?
Today I found an article about Java8's Fork/Join-Framework and its usage for the parallel streams implementation. While I do understand the article, I'm not entirely sure what I should think of it.

Basically what it says it that F/J in conjunction with streams is next to useless, and especially so in the context of JEE applications. Quite a few specific  arguments are listed, such as:

it needs a massive volume of easily separable data (aggregate),

creates copious threads without regard for others,

has a high potential for stack overflows,

has a high potential for massive memory usage,

has a very, very narrow performance window,

is only designed for one request at a time.

Moreover, it gives these arguments against F/J's recursive decompostion approach:

Recursive decomposition has an even narrower performance window. In addition to the above dynamic decomposition, recursive decomposition optimized for dyadic recursive division only works well:

on balanced tree structures (Directed Acyclic Graphs)

where there are no cyclic dependencies

where the computation duration is neither too short nor too long

where there is no blocking.

Since this is the only source I could find which complains about FJ, I'm not sure if this can be taken seriously. Are the above-cited, or other similar points a valid concern?

More specifically, does Oracle have an official position regarding the limitations of the F/J Framework as applied to the parallelization of streams processing? If so, does it have plans to do something about them?

答:
This is the gist of the problems with the application of F/J in the implementation of the Streams API:

F/J is good for the parallelization of in-memory, random-access structures: it wants to be able to divide the full problem top-down, by recursively halving it into two subproblems of equal size;

the stream paradigm is primarily about the processing of lazily materialized, sequential data sources, which can only be divided into a sequence of chunks, and the number of chunks is usually not known in advance.

While F/J can be bent somewhat to support sequential chunking, this is perceived by it as "anomalous" and "lopsided", eventually giving rise to insurmountable issues when combined with the unpredictable I/O latency in reading those chunks1.

Streams API excels at the parallelization of in-memory structures and is usually helpful with the processing of lazy, I/O-backed streams, but it fails when you try to combine these two features in a single use case.

If you have a loop in your code which introduces a CPU-bound bottleneck, it is fairly likely that this loop is iterating over the contents of some file, network request, or rows of an SQL result set. None of these targets for parallelization get support from the Streams API.

The official position is that this use case is not supported because the Streams API has a different, equally legitimate focus. In the department of lazy parallel streams, this focus amounts to stream sources which are calculated from data existing within working memory, with the additional constraint that these sources must be unordered—that each member can be calculated independently, without the need to first calculate any other. An example of such a stream is a range of integers, but a stream of random numbers from an LCG is already outside of the area being focused on by the API, because these random numbers can only be generated sequentially.

1Keep in mind that this is the official statement. I have personally not yet hit this issue, having instead successfully parallelized the processing of my I/O sources.

OwnerDisplayName: Marko Topolnik


问:
Business Logic vs Presentation/View Logic
I often question myself of where to put the logic that organize the data to a view that is not necessarily a business logic in a 3-layered architecture (DAO, Business, View).

I'll put an example to be clearer:

I have a UI in my aplication that shows pending tickets and answered tickets in two different tabs. To get the data from the database, I make a single query. Since there is no business logic, I'm returning the whole list to the Controller (View) and separating it in two lists to pass to the view template.

Should I be separating this in the business layer? Or is it correct to separate in the controller, since the logic is attached to that single UI?

答:
If I have a model definition called Tickets, then I would put class level function on that class to give me a collection of Ticket instances.

example:

```<code>class Ticket
    # these are class level function, you call them like this
    # array_of_pending_tickets = Ticket.pending_tickets(2)
    def self.pending_tickets(category_id)
        # do the query to get pending tickets here
        # and return an array of new Ticket instances
    end
    def self.answered_tickets(category_id)
        # do the query to get only answered tickets here
        # and return an array of new Ticket instances
    end
    # this is an instance level function, you call it like this
    # ticket_im_working_on = array_of_pending_tickets[0]
    # ticket_im_working_on.mark_as_answered('hello world')
    def mark_as_answered('comment')
        # the instance of the Ticket class should have some
        # kind of internal instance variable like @id that
        # you can use to modify the database
    end
end
</code>```

Once your model is defined like this, then you use your controller to execute the proper model function (say, if you have /pending/category_1 as your url, parse that in the controller and then get the variable), and then once you have the data you need use the view to display it (using a loop on the array from Ticket.pending_tickets(1)).

Body:
If I have a model definition called Tickets, then I would put class level function on that class to give me a collection of Ticket instances.

example:

class Ticket
    # these are class level function, you call them like this
    # array_of_pending_tickets = Ticket.pending_tickets(2)
    def self.pending_tickets(category_id)
        # do the query to get pending tickets here
        # and return an array of new Ticket instances
    end
    def self.answered_tickets(category_id)
        # do the query to get only answered tickets here
        # and return an array of new Ticket instances
    end
    # this is an instance level function, you call it like this
    # ticket_im_working_on = array_of_pending_tickets[0]
    # ticket_im_working_on.mark_as_answered('hello world')
    def mark_as_answered('comment')
        # the instance of the Ticket class should have some
        # kind of internal instance variable like @id that
        # you can use to modify the database
    end
end

Once your model is defined like this, then you use your controller to execute the proper model function (say, if you have /pending/category_1 as your url, parse that in the controller and then get the variable), and then once you have the data you need use the view to display it (using a loop on the array from Ticket.pending_tickets(1)).


答:
I'm going to try to explain this with an example.

Lets say you want to build a website that shows people a list of friends. So it starts with a list of your friends (A,B,C..). When you select one, it shows a list of their friends (A1, A2, etc) and so on.

The "View" is an implementation of what the user can see. In this case, we need only one view i.e. a table to show a list of people. The view does not care who these people are, where they came from or how they are related. It just displays a list of people and relays any user actions (clicks, etc) to the controller.

The Model has a list of people and their relationships. It doesn't know what to do with them or how an action on the view affects them. It simply has a list of people.

It is the Controller's job to "take a list of people and give it to the view for display". When a user clicks on a person, the view will relay that action to the controller, the controller will look into the model for relationships for this person and extract a new list of people, which it will then give to the view for display, and so on.

I hope you can see how this sort of architecture would be beneficial in large projects. It greatly simplifies code, promotes reusability (I can use the same View to display a list of any "people" objects) and makes it easier to change one aspect of the project (data or UI) without affecting the other.

Title: Can someone help me understand MVC?

Body:
I've read a few articles on the MVC pattern and tried to understand what it exactly is. But till now, what I get is a plain diagram showing 3 modules of Model, View and Controller. Some say that it helps increase code reuse (DRY), while I think it does the opposite.

I currently separate my application code into different directories, one for Viewing part (presentation: Html/Css/Js + client side req) and the other one for Core related functions. I haven't found any disadvantage to this approach yet. Maybe because I haven't developed big applications yet, just small hobby ones.

So, apart from this separation, what I find in MVC is some sort of url rewriting, which I think can be achieved if necessary. Is there something I am missing? There must be a reason developers are so inclined towards the MVC pattern.


答:
It's perfectly safe to do it this way, especially since, as Doval pointed out, all the instances of Show and Read that you're using are in the standard library, and are thus guaranteed to cooperate with each other without any difficulty.

However, it's not the generally recommended way to do it, simply because saving to human-readable (and Haskell-readable) text is nowhere near as efficient as a tag-based binary format.  For this, you can use the binary package, which already includes instances for all of the datatypes that you're using in the question.

More to the point, though, using the binary package to serialize to and deserialize from disk is even easier then using Show and Read!  (Just use the functions encodeFile and decodeFile(OrFail) from the Data.Binary module.)  In general, you will have to get used to things in Haskell being much simpler, at least in the common cases, then they typically are in most imperative languages.  :)

Title: Is it safe in Haskell to save a data structure to a file using "show", and retrieve it using "read"?

Body:
Say I have the following types:

```<code>type EndsTup = (Int,Int)
    -- (0-based index from start or end, Frequency)
type FreqTup = (Char, [EndsTup], [EndsTup])
    -- (Character, Freqs from start, Freqs from end)
type FreqData = [FreqTup]
    -- 1 entry in the list for each letter
</code>```

Which I'm using to store data regarding the frequency of a character's position in a word. If I want to then save this to file, is it safe (as in guaranteed not to corrupt if it's written without error) to convert the structure to a string using show, and then read it using something like:

```<code>readData <- readFile filePath
let reconstructed = read readData :: FreqData
</code>```

I'm just asking because that seems "too easy". Is this how it's typically done?


答:
The revision can be used for patches of the builds. Lets say that 2 teams work on a product.

Team 1 is the major development team and produces nightly build with the following version schema 1.0.X.0, where X is incremented. Now they are at build 1.0.50.0
Team 2 is taking a build from time to time. Let's say they take the build from last week which is 1.0.43.0 and start using it. Team 1 advances to 1.0.51.0 when team 2 finds an issue in 1.0.43.0.

Now team 1 will take that build (43), fix the issue and provide team 2 with the build 1.0.43.1. The fix might be also propagated in the main build, so the change will appear in 1.0.52.0.

Hope this is clear and helpful.

*Revision is useful when not everyone involved in the project uses the same build and you need to patch specific builds.

Title: What exactly is the build number in MAJOR.MINOR.BUILDNUMBER.REVISION

Body:
What I think about Build Numbers is that whenever a new nightly build is created, a new BUILDNUMBER is generated and assigned to that build. So for my 7.0 version application the nightly builds will be 7.0.1, 7.0.2 and so on. Is it so? Then what is the use of a REVISION after the build number? Or is the REVISION part being incremented after each nightly build? I am a little confused here... do we refer to each nightly build as a BUILD?

The format is mentioned here: AssemblyVersion - MSDN


问:
Is there a specific reason that dingbat fonts are supported or ever even created?
I have known about the weird dingbat fonts since the first time I tried to change the font on MS word and stumbled upon them. Since then I never questioned them, I just thought hey cool. Now I have some questions.

What is the purpose behind creating dingbat fonts?

Is there anyone/entity that actually uses/needs these types of fonts?

答: I've used fonts like these in Crystal Reports to generate ticked/unticked check boxes and bullets.  Using them is a lot better than say, loading up an image of a smiley face and embedding it in  your application.  But, these fonts were created long ago.  Wingdings has been around since before I was ever introduced to Microsoft Windows.</p>


问:
Where to put format validation in a CQRS “stylish” domain model?
It feels right to put format validation inside the domain objects (VOs or entities) because it is the natural place for high cohesion and the domain knows best what every domain description/attribute/property means. Many DDD practitioners and books authors (Vaugh Vernon, Dan Bergh - and even Eric Evans suggest , but on a different aspect: authorization, to model the domain to reflect these matters) suggest to design the domain model in a way to reflect and enforce a proper state of the business.

I agree that format validation (ie.: address property in EmailAddress VO should be max ~250 chars and should match a regex) should be implemented inside the domain objects. But these validation checks work best with a domain model that will be used for both state changes and state queries.

What about CQRS where the command side (where the domain model is) has little or no knowledge about the read side. Should one reimplement the same input format checks in the query side of the application? In CQRS there are some common responsibilities for both command and query side (like input format validation), so the usual format validation implementations that most of DDD practitioners suggest will be duplicated.

How should one deal with this, w/o making the domain model (from the command side) to be anemic and w/o making unaware of the state of the attributes it will hold .

An example : there might be a feature that would let a conference owner to schedule a conference and change the number of available seats. But because the conference room is not big enough, the maximum allowed number of seats would be 100. So a business rule would be that : a conference owner cannot add more than 100 seats for a scheduled conference (also minimum 1 seat needed for the conference to be in a valid state). So a method would be on a ConferenceAR :

```<code>changeNumberOfAvailableSeats(numberOfAvailableSeats) {
    if(!isNumber(numberOfAvailableSeats) || numberOfAvailableSeats > 100 ||
            numberOfAvailableSeats < 1) {
        throw new DomainException ...
    }

    // Change the number of available seats ...
}
</code>```

On the query side there might be an UI page where you can find all the scheduled conferences that have a certain number of available seats. So again , on the server's query side of the application, there must be a format validation that will check if the query for scheduled conferences with a number of seats available is a number and is in the range 1-100. This query might be needed by someone who wants to reserve a certain number of seats for a conference . Also conferences might be on the same topic so one could see a conference with the same topic many times and choose the one cheaper or with more seats available.

So again, should one reimplement the format validation on both query and command sides or there is another solution?

P.S. : there are many format validation duplicates (on both command and query side) like the email format validation , or a currency format validation (if the currency is : USD || CAD || AUD etc ...)

P.P.S. : Another question that popped up : Does the query side of the application require any input format validation ? If the input is not a valid format it will return nothing , query found no data related to the request. I see that format validation on the query side is purely a security measure (ie. for buffer overflows). So is the input format validation really required on the query side ?

答:
If you're using events to transfer data, you can probably treat many of those concerns as simply another kind of data the read-model needs to store and arrange in a convenient way. For example,

You'll already want a listener for events like RoomCreated and RoomDisabled from the domain, because you're keeping some sort of fast-to-query representation of what rooms are available, right? Why not also maintain a biggestActiveRoomSize variable at the same time?

See a ContactCreated or ContactEmailUpdated event? Check the length and update a stored maxEmailCharacters.

See a PricingPosted event? Make sure the currency inside the event is present/added to your own knownCurrencies list. That means shortly after it gets used, it'll become an option people can search with.

In other words, whatever comes from the domain is automatically valid, and everything you see expands the envelope of what you're willing to allow the user to enter.

Granted, this does not work for certain complex things like regular expressions or if/then logic. For those cases, perhaps:

As part of your build process, compiling the domain-model emits a configuration file that the query-side can load and use.

Outright duplication of logic. Not ideal, but workable as long as the query-side is very clear about where the authoritative source is and you have a procedure around updating the values that humans will follow.

Crazier idea: Have the domain model store/broadcast an event whenever it starts up, containing that kind of information. Multiple read-models could decide what (if anything) they want to do with it.

I think you should plan for some duplication (there's always something) but when it comes to "what values or ranges are actually being used", I'd try making it just another part of the read-model.

OwnerDisplayName: Tudor


问:
Sanity check for design pattern used with an intricate calculation model
I am working on a project that generates technical brochures in batch. The 3rd party API that is being used expects POCOs with property names that match field names used in each of the brochure templates. The task I am seeking advice on is with the data source that will be used to populate these POCOs. The data is based on cascading calculations against a Domain Model. I originally entertained the idea of having the Domain be self-calculating, but there are so many calcs required that it seemed obvious to me this needed to be abstracted away.

I created some hypothetical code that closely mimics the design pattern in question, and I am open to any suggestions or reaffirmations as to whether I am approaching this correctly.

My primary concerns:

The constructor for the "AirplaneResultsContext" class, which injects itself to calculation classes which are also publicly exposed properties. Does this create recursive paths?

The possible occurrance of circular references with cascading calculation calls to various properties/methods in various other classes. Note that I am re-using most of the calculation logic (as was requested) but I can propose the need for it to be refactored if need be.

I noticed I used the word "Intricate", which is usually a telltale warning for code that needs to be abstracted out, but I am struggling to see how I can make this better.

The entity being calculated against. Picture this as an aggregate root for a larger domain model.

```<code>class Airplane : Entity<int>
{
    public double WingLength { get; set; }
    public double FuselageCircumference { get; set; }
    public double FuselageLength { get; set; }
    public double SeatWidth { get; set; }
    public double SeatDepth { get; set; }
    public double SeatHeight { get; set; }
    public double IsleWidth { get; set; }
    public double LegRoomArea { get; set; }
}
</code>```

The calculation context. The intent is for this object to be passed along as part of a batch process -- an abstract factory which consumes an interface represented by this context class and generates the POCO objects. Note that I also omitted the interfaces and abstract classes that would be used for different calculation strategies for brevity.

```<code>class AirplaneResultsContext
{
    public AirplaneResultsContext(Airplane airplane)
    {
        Airplane = airplane;
        Fuselage = new FuselageCalculator(this);
        Seating = new SeatingCalculator(this);
    }

    public Airplane Airplane { get; private set; }
    public FuselageCalculator Fuselage { get; private set; }
    public SeatingCalculator Seating { get; private set; }

    public double ComputeWidth()
    {
        return Airplane.WingLength*2 + Fuselage.ComputeDiameter();
    }
}
</code>```

Calculators. In my non-hypothetical project, these methods are private/protected, cached on the first call, and read back by read-only properties, but I only wanted to show a basic representation of some of the calculation complexity.

```<code>class SeatingCalculator
{
    private readonly AirplaneResultsContext _context;

    public SeatingCalculator(AirplaneResultsContext context)
    {
        _context = context;
    }

    public int ComputeNumberOfSeats()
    {
        double isleArea = _context.Airplane.IsleWidth* _context.Airplane.FuselageLength;
        double availableArea = (_context.Fuselage.ComputeDiameter()*_context.ComputeWidth()) - isleArea;
        double seatArea = _context.Airplane.SeatDepth * _context.Airplane.SeatWidth + _context.Airplane.LegRoomArea;

        return (int) Math.Floor(availableArea/seatArea);
    }
}
</code>```

```<code>class FuselageCalculator
{
    private readonly AirplaneResultsContext _context;

    public FuselageCalculator(AirplaneResultsContext context)
    {
        _context = context;
    }

    public double ComputeDiameter()
    {
        return Math.PI / _context.Airplane.FuselageCircumference;
    }
}
</code>```

答:
It sounds as though your calculation algorithm consists of the following:

Some large pile of raw data.

A bunch of (sealed or sealable) classes that calculate various results, that are singletons in the context of each specific calculation.  E.g. there's one FuselageCalculator, one SeatingCalculator, and so on, for each brochure to be generated.

If that's the case, you can combine the abstract factory pattern with a simple graph coloring algorithm into a calculation manager that will catch any circular references.  As long as each calculation stage performs all its calculations in its constructor and demands all preceding results unconditionally, ideally at the beginning of the constructor, the manager can keep track of calculations that are being constructed and throw an exception whenever somebody tries to nest creation of the same type of calculation.  Thus each calculation stage becomes an implicit graph node with three possible states: not calculated, calculating, and done calculating.

Here's a quick prototype implementation:

```<code>public interface IRawData
{
}

public interface IResult<TRawData> where TRawData : class, IRawData
{
}

public interface IResultFactory<TRawData> where TRawData : class, IRawData
{
    Type ResultType { get; }
    IResult<TRawData> CreateResult(CalculationManager<TRawData> manager, TRawData rawData);
}

public class CalculationManagerException : Exception
{
}

public class CircularReferenceException : CalculationManagerException
{
    readonly Type type;
    public CircularReferenceException(Type type)
        : base()
    {
        this.type = type;
    }

    public override string Message
    {
        get
        {
            return GetType().Name + ": Circular reference calculating " + type.Name;
        }
    }
}

public class UnknownResultTypeException : CalculationManagerException
{
}

public class CalculationManager<TRawData> where TRawData : class, IRawData
{
    class DummyResult : IResult<TRawData>
    {
        internal DummyResult() { }
    }

    readonly TRawData rawData;

    readonly Dictionary<Type, IResult<TRawData>> results = new Dictionary<Type, IResult<TRawData>>();
    readonly Dictionary<Type, IResultFactory<TRawData>> resultFactory;
    readonly DummyResult calculatingFlag = new DummyResult();

    public CalculationManager(TRawData rawData, IEnumerable<IResultFactory<TRawData>> factories)
    {
        this.resultFactory = factories.ToDictionary(x => x.ResultType, x => x );
        this.rawData = rawData;
    }

    public TResult DemandResult<TResult>() where TResult : class, IResult<TRawData>
    {
        IResult<TRawData> iResult;
        if (!results.TryGetValue(typeof(TResult), out iResult))
        {
            IResultFactory<TRawData> factory;
            if (!resultFactory.TryGetValue(typeof(TResult), out factory))
                throw new UnknownResultTypeException();
            Debug.Assert(typeof(TResult).IsSealed);
            results[typeof(TResult)] = calculatingFlag; // Synthetic flag that we are in the middle of calculating results.
            iResult = factory.CreateResult(this, rawData);
            if (iResult.GetType() != typeof(TResult))
            {
                Debug.Assert(iResult.GetType() == typeof(TResult));
                throw new UnknownResultTypeException();
            }
            results[typeof(TResult)] = iResult;
        }
        else
        {
            if (iResult == calculatingFlag)
                throw new CircularReferenceException(typeof(TResult));
        }
        return (TResult)iResult;
    }
}
</code>```

(Maybe there's a cleaner way to do the abstract factory pattern in c# 4.5 using covariance?  For various reasons I'm stuck at c# 3.0.  Maybe Activator.CreateInstance would be prettier, skipping the factory classes entirely?)

Now let's test it.  Here are some classes with no circular reference.  Result2 depends on Result1 which depends on TestData:

```<code>public sealed class TestData : IRawData
{
    public double Field0 { get { return 0; } }
}

public sealed class Result1 : IResult<TestData>
{
    readonly double field1;
    public Result1(CalculationManager<TestData> manager, TestData rawData)
    {
        field1 = rawData.Field0 + 1;
    }

    public double Field1 { get { return field1; } }
}

public sealed class Result1Factory : IResultFactory<TestData>
{
    #region IResultFactory<FirstResult> Members

    public Type ResultType { get { return typeof(Result1); } }

    public IResult<TestData> CreateResult(CalculationManager<TestData> manager, TestData rawData)
    {
        return new Result1(manager, rawData);
    }

    #endregion
}

public sealed class Result2 : IResult<TestData>
{
    readonly double field2;
    public Result2(CalculationManager<TestData> manager, TestData rawData)
    {
        var res1 = manager.DemandResult<Result1>();
        field2 = res1.Field1 + 1;
    }

    public double Field2 { get { return field2; } }
}

public sealed class Result2Factory : IResultFactory<TestData>
{
    #region IResultFactory<FirstResult> Members

    public Type ResultType { get { return typeof(Result2); } }

    public IResult<TestData> CreateResult(CalculationManager<TestData> manager, TestData rawData)
    {
        return new Result2(manager, rawData);
    }

    #endregion
}
</code>```

Now let's add some classes with circular references (omitting the boring factories):

```<code>public sealed class Result3 : IResult<TestData>
{
    readonly double field3;
    public Result3(CalculationManager<TestData> manager, TestData rawData)
    {
        var res1 = manager.DemandResult<Result1>();
        var res4 = manager.DemandResult<Result4>();

        field3 = res1.Field1 + res4.Field4;
    }

    public double Field3 { get { return field3; } }
}

public sealed class Result4 : IResult<TestData>
{
    readonly double field4;
    public Result4(CalculationManager<TestData> manager, TestData rawData)
    {
        var res1 = manager.DemandResult<Result1>();
        var res2 = manager.DemandResult<Result2>();
        var res3 = manager.DemandResult<Result3>();

        if (res1.Field1 > 2)
            field4 = res2.Field2 + res3.Field3;
        else
            field4 = res2.Field2;
    }

    public double Field4 { get { return field4; } }
}
</code>```

And now, let's test:

```<code>public static class TestResult {
    public static void Test()
    {
        try
        {
            TestData data = new TestData();
            CalculationManager<TestData> manager = new CalculationManager<TestData>(data, new IResultFactory<TestData>[] { new Result1Factory(), new Result2Factory(), new Result3Factory(), new Result4Factory() });

            var field2 = manager.DemandResult<Result2>().Field2; // Get two as expected.
            var field4 = manager.DemandResult<Result4>().Field4; // No result -- exception thrown.
        }
        catch (CalculationManagerException e)
        {
            Debug.WriteLine(e.GetType().Name + " " + e.ToString()); // Exception caught: CircularReferenceException: Circular reference calculating Result4
        }
    }
}
</code>```

Sure enough, Result2 is calculated successfully (and, indirectly, Result1), but calculating Result4 throws the exception.

Is that what you wanted?

Update - I added the coding style constraint that preceding results should be demanded at the beginning of each constructor, and updated my test case to show this style.

BTW, you design may be vulnerable to another type of error: unit mismatch errors.  I notice some of your results are linear, some are areas, and perhaps some are dimensionless.  It's quite possible that somewhere in the calculation chain a mistaken assumption will get made about the units of a previous calculation.  I'd suggest wrapping each numerical result in some sort of unit structure.

Body:
It sounds as though your calculation algorithm consists of the following:

Some large pile of raw data.

A bunch of (sealed or sealable) classes that calculate various results, that are singletons in the context of each specific calculation.  E.g. there's one FuselageCalculator, one SeatingCalculator, and so on, for each brochure to be generated.

If that's the case, you can combine the abstract factory pattern with a simple graph coloring algorithm into a calculation manager that will catch any circular references.  As long as each calculation stage performs all its calculations in its constructor and demands all preceding results unconditionally, ideally at the beginning of the constructor, the manager can keep track of calculations that are being constructed and throw an exception whenever somebody tries to nest creation of the same type of calculation.  Thus each calculation stage becomes an implicit graph node with three possible states: not calculated, calculating, and done calculating.

Here's a quick prototype implementation:

public interface IRawData
{
}

public interface IResult<TRawData> where TRawData : class, IRawData
{
}

public interface IResultFactory<TRawData> where TRawData : class, IRawData
{
    Type ResultType { get; }
    IResult<TRawData> CreateResult(CalculationManager<TRawData> manager, TRawData rawData);
}

public class CalculationManagerException : Exception
{
}

public class CircularReferenceException : CalculationManagerException
{
    readonly Type type;
    public CircularReferenceException(Type type)
        : base()
    {
        this.type = type;
    }

    public override string Message
    {
        get
        {
            return GetType().Name + ": Circular reference calculating " + type.Name;
        }
    }
}

public class UnknownResultTypeException : CalculationManagerException
{
}

public class CalculationManager<TRawData> where TRawData : class, IRawData
{
    class DummyResult : IResult<TRawData>
    {
        internal DummyResult() { }
    }

    readonly TRawData rawData;

    readonly Dictionary<Type, IResult<TRawData>> results = new Dictionary<Type, IResult<TRawData>>();
    readonly Dictionary<Type, IResultFactory<TRawData>> resultFactory;
    readonly DummyResult calculatingFlag = new DummyResult();

    public CalculationManager(TRawData rawData, IEnumerable<IResultFactory<TRawData>> factories)
    {
        this.resultFactory = factories.ToDictionary(x => x.ResultType, x => x );
        this.rawData = rawData;
    }

    public TResult DemandResult<TResult>() where TResult : class, IResult<TRawData>
    {
        IResult<TRawData> iResult;
        if (!results.TryGetValue(typeof(TResult), out iResult))
        {
            IResultFactory<TRawData> factory;
            if (!resultFactory.TryGetValue(typeof(TResult), out factory))
                throw new UnknownResultTypeException();
            Debug.Assert(typeof(TResult).IsSealed);
            results[typeof(TResult)] = calculatingFlag; // Synthetic flag that we are in the middle of calculating results.
            iResult = factory.CreateResult(this, rawData);
            if (iResult.GetType() != typeof(TResult))
            {
                Debug.Assert(iResult.GetType() == typeof(TResult));
                throw new UnknownResultTypeException();
            }
            results[typeof(TResult)] = iResult;
        }
        else
        {
            if (iResult == calculatingFlag)
                throw new CircularReferenceException(typeof(TResult));
        }
        return (TResult)iResult;
    }
}

(Maybe there's a cleaner way to do the abstract factory pattern in c# 4.5 using covariance?  For various reasons I'm stuck at c# 3.0.  Maybe Activator.CreateInstance would be prettier, skipping the factory classes entirely?)

Now let's test it.  Here are some classes with no circular reference.  Result2 depends on Result1 which depends on TestData:

public sealed class TestData : IRawData
{
    public double Field0 { get { return 0; } }
}

public sealed class Result1 : IResult<TestData>
{
    readonly double field1;
    public Result1(CalculationManager<TestData> manager, TestData rawData)
    {
        field1 = rawData.Field0 + 1;
    }

    public double Field1 { get { return field1; } }
}

public sealed class Result1Factory : IResultFactory<TestData>
{
    #region IResultFactory<FirstResult> Members

    public Type ResultType { get { return typeof(Result1); } }

    public IResult<TestData> CreateResult(CalculationManager<TestData> manager, TestData rawData)
    {
        return new Result1(manager, rawData);
    }

    #endregion
}

public sealed class Result2 : IResult<TestData>
{
    readonly double field2;
    public Result2(CalculationManager<TestData> manager, TestData rawData)
    {
        var res1 = manager.DemandResult<Result1>();
        field2 = res1.Field1 + 1;
    }

    public double Field2 { get { return field2; } }
}

public sealed class Result2Factory : IResultFactory<TestData>
{
    #region IResultFactory<FirstResult> Members

    public Type ResultType { get { return typeof(Result2); } }

    public IResult<TestData> CreateResult(CalculationManager<TestData> manager, TestData rawData)
    {
        return new Result2(manager, rawData);
    }

    #endregion
}

Now let's add some classes with circular references (omitting the boring factories):

public sealed class Result3 : IResult<TestData>
{
    readonly double field3;
    public Result3(CalculationManager<TestData> manager, TestData rawData)
    {
        var res1 = manager.DemandResult<Result1>();
        var res4 = manager.DemandResult<Result4>();

        field3 = res1.Field1 + res4.Field4;
    }

    public double Field3 { get { return field3; } }
}

public sealed class Result4 : IResult<TestData>
{
    readonly double field4;
    public Result4(CalculationManager<TestData> manager, TestData rawData)
    {
        var res1 = manager.DemandResult<Result1>();
        var res2 = manager.DemandResult<Result2>();
        var res3 = manager.DemandResult<Result3>();

        if (res1.Field1 > 2)
            field4 = res2.Field2 + res3.Field3;
        else
            field4 = res2.Field2;
    }

    public double Field4 { get { return field4; } }
}

And now, let's test:

public static class TestResult {
    public static void Test()
    {
        try
        {
            TestData data = new TestData();
            CalculationManager<TestData> manager = new CalculationManager<TestData>(data, new IResultFactory<TestData>[] { new Result1Factory(), new Result2Factory(), new Result3Factory(), new Result4Factory() });

            var field2 = manager.DemandResult<Result2>().Field2; // Get two as expected.
            var field4 = manager.DemandResult<Result4>().Field4; // No result -- exception thrown.
        }
        catch (CalculationManagerException e)
        {
            Debug.WriteLine(e.GetType().Name + " " + e.ToString()); // Exception caught: CircularReferenceException: Circular reference calculating Result4
        }
    }
}

Sure enough, Result2 is calculated successfully (and, indirectly, Result1), but calculating Result4 throws the exception.

Is that what you wanted?

Update - I added the coding style constraint that preceding results should be demanded at the beginning of each constructor, and updated my test case to show this style.

BTW, you design may be vulnerable to another type of error: unit mismatch errors.  I notice some of your results are linear, some are areas, and perhaps some are dimensionless.  It's quite possible that somewhere in the calculation chain a mistaken assumption will get made about the units of a previous calculation.  I'd suggest wrapping each numerical result in some sort of unit structure.


答:
The MVC design pattern was originally formulated in the old days when MS-DOS was still a dominant OS. In those days there was very little support from the OS for graphical user interfaces, so you had to do most of it yourself. In the original MVC, the job of the Controller was to figure out which text-entry field was active and what it meant if the user presses a key.

In the modern desktop OSes with display managers and feature-full widgets, that Controller role has effectively been merged into the View components and the MVC Controller has been given a more high-level coordinating role.

The logic in the Views should indeed be limited, but it should be limited to UI-related logic. For a View as complex as yours, even the UI-related logic can be quite significant, so I don't see any problems with your architecture.

Title: MVC/P in Desktop Application

Body:
I am developping a desktop application in C#, and have separated different layers in an MVC-ish architecture.

As I have switched from GTK# to XWT, only views had to be adjusted, so the seperation of layers was done quite OK.

As XWT does not have a layout designer, everything has to be set up in code, which in turn led to an architectural problem:

I have one controller for displaying outlets, inlets and connections.

This controller sends data to one view (outlined in red). This view in turn has subviews (green and blue), that only communicate with the view in red.

On scrolling / collapsing / expanding the treeviews, the green view send events, which are received by the red view, which in turn trigger redrawing in the blue view.

Controller does not see the green or blue views, every change in connections / outlets / inlets are only sent to the red view.

My problem: As I understand MVC, views should not have much logic. But the green views is a class of 300 lines, the red view's class has 200 lines, which is too many.

What architectural problem can arise from this? Am I overlooking a fault in my MVC logic?


问:
Project is nearly done, but procedural spaghetti code. Do I rewrite or just keep trying to ship it?
I'm a beginner web developer (one year of experience).

A couple of weeks after graduating, I got offered a job to build a web application for a company whose owner is not much of a tech guy. He recruited me to avoid theft of his idea, the high cost of development charged by a service company, and to have someone young he can trust onboard to maintain the project for the long run (I came to these conclusions by myself long after being hired).

Cocky as I was back then, with a diploma in computer science, I accepted the offer thinking I can build anything.

I was calling the shots. After some research I settled on PHP, and started with plain PHP, no objects, just ugly procedural code. Two months later, everything was getting messy, and it was hard to make any progress. The web application is huge. So I decided to check out an MVC framework that would make my life easier. That's where I stumbled upon the cool kid in the PHP community: Laravel. I loved it, it was easy to learn, and I started coding right away. My code looked cleaner, more organized. It looked very good.

But again the web application was huge. The company was pressuring me to deliver the first version, which they wanted to deploy, obviously, and start seeking customers.

Because Laravel was fun to work with, it made me remember why I chose this industry in the first place - something I forgot while stuck in the shitty education system.

So I started working on small projects at night, reading about methodologies and best practice. I revisited OOP, moved on to object-oriented design and analysis, and read Uncle Bob's book Clean Code.

This helped me realize that I really knew nothing. I did not know how to build software THE RIGHT WAY. But at this point it was too late, and now I'm almost done. My code is not clean at all, just spaghetti code, a real pain to fix a bug, all the logic is in the controllers, and there is little object oriented design.

I'm having this persistent thought that I have to rewrite the whole project. However, I can't do it... They keep asking when is it going to be all done.

I can not imagine this code deployed on a server. Plus I still know nothing about code efficiency and the web application's performance.

On one hand, the company is waiting for the product and can not wait anymore. On the other hand I can't see myself going any further with the actual code. I could finish up, wrap it up and deploy, but god only knows what might happen when people start using it.

Do I rewrite, or just keep trying to ship, or is there another option that I've missed?

答:
This is what I would do personally:

Quit, make an excuse and give up (you can even give back part of your salary so you don't look bad)

Clean your code as much as possible

Make documentation on all the good parts of your work like your good design, good ideas, etc...

Why do I suggest all of these to you?

Because think about the future. There will be time in the future when certain people will get a hold of this code. They will make all sorts of assumption and judgments about you and your ability. They don't care when you wrote it, they don't care the circumstance. They only want to see in it what they want to see to confirm whatever they want to confirm.

You will be branded as whatever bad name, term they can come up with to negatively impact you. And even though the you in the future might very well be totally different in term of technical ability, skills, knowledge, style and the situation will be so different, this code will be used against you in every possible way. It is like a court where they can say all the bad things about you and your code and design and you are not even aware of it so you can explain and defend yourselves. (and you might learn very often that they are deeply wrong, repeatedly) So don't do it. Give up.

Trust me, there are people who made lot of assumptions about you because you did something for whatever purpose at whatever moment. To them, if you did like this in situation A, you will do it in situation B. They think very simple.


问:
Outsourcing functionality from Django view to C/C++
I'm developing a Django project that basically boils down to:

A user submits a form.

The Django view parses the form and compiles a representation of that form which is readable by some other 'function'. By 'function', I mean some kind of executable/callable where the Django view may be agnostic about what language that 'function' was written in, or even what hardware it runs on.

The Django view passes the compiled form into the 'function'.

The 'function' performs its business on the input, then outputs some data in a format readable by the Django view.

The Django view reads the output of the 'function' and renders the data to a format that is consumable by the user.

In my specific case, the 'function' is a large numerical computation not suitable for plain-vanilla Python. Furthermore, this 'function' has already been developed in C++11 and Python can talk to the compiled binary via os.system and file IO.

My question then is: why should I not just use os.system or subprocess from the Django view rather than

a) redevelop the 'function' using one of ctypes | swig | Boost.Python | pyrex | cython;

b) learn how to write Python extensions and re-write the 'function' accordingly?

I have also considered turning the 'function' into a daemon, but I am not experienced enough with daemons to be able to gauge what the consequences of such a design would be.

Are there undesirable/undefined behaviours that would arise from using os.system/subprocess as described above for a Django project that was operating under load?

Is there something else I am missing that is super obvious to everyone else?

There is also this related question. But with the scarcity of details in both the OP's use case and in the answers, I am cautious not to fall for my own fallacious confirmation bias.

答:
There is nothing wring with calling a library routine written in one language from an application written in another. It happens all the time. A good example is SQL code embedded in most other languages.

The issues you face with doing this is simply skillset, to maintain this external function you'll need to know C++ as well as python.

As you say, you have plenty of options for interfacing to this. I would recommend a ctypes mechanism as it will be the lowest overhead, that's almost the only consideration unless you cannot rebuild the function into a shared library. Making system calls to an external process works, its just a lot slower to get data to and from a process than it is to pass it to a shared library loaded in-process. You could convert the function into a web service and call it using SOAP or REST calls for example.

A daemon is just a process running that is running constantly. Its faster than simply running the function on-demand as the OS doesn't have to take all the time to start the process every time you want to call a function. To convert it into a daemon you might have to alter the code to run when several applications call the function simultaneously but otherwise its not any different.

So: if the speed of calling the function in a process is not important (eg its an intermittent, or long-running function) then go right ahead and call it using system calls. But, if you need speed, and this function returns quickly, or is called many time, then I think you should learn how C/C++ programs are written and built. Then you will have the skills to turn this into a library and call it using ctypes.


答:
```<code>  > Reworking/rethinking these workflows is not an option
</code>```

I am afraid you have to add additional states in your workflow, every time the old workflow asks for a user-decision without changing the base workflow.

example in old system:

```
customer adds products to basket
...
checkout: customer decides to buy the content of the basket
system does the verifification
    order article is out of stock
        messagebox: "do you want to (a) cancel the order, (b) remove this product or (c) select another one equivalent"?
            (a) ...
            (b) ...
            (c) ...
```

so instead of showing the messagebox the intermediate-workflowstate: "One or more articles are out of stock is reached."

alternatively you can introduce the intermediate-workflowstate "order can not be processed" with additional infos for those items that have problems.

in a classical web app the customer is redirected to basket-overview-page where errormessages are displayed next to the order-item that has problems.

Body:
  > Reworking/rethinking these workflows is not an option

I am afraid you have to add additional states in your workflow, every time the old workflow asks for a user-decision without changing the base workflow.

example in old system:

customer adds products to basket
...
checkout: customer decides to buy the content of the basket
system does the verifification
    order article is out of stock
        messagebox: "do you want to (a) cancel the order, (b) remove this product or (c) select another one equivalent"?
            (a) ...
            (b) ...
            (c) ...

so instead of showing the messagebox the intermediate-workflowstate: "One or more articles are out of stock is reached."

alternatively you can introduce the intermediate-workflowstate "order can not be processed" with additional infos for those items that have problems.

in a classical web app the customer is redirected to basket-overview-page where errormessages are displayed next to the order-item that has problems.


答:
@JBRWilkinson is right, basically.

Having a web client front end and a web server backend is a highly asynchronously thing by definition. Especially when callbacks come into play to dynamically load data or verify things, etc.

But you don't have to rewrite the whole app. You don't need to rewrite the workflow either. You "only" have to work on those parts that deal with the UI in any way. I write "only", because this can be still painful enough, especially when all the logic is tied into the GUI forms. Been there, done that.

We have made good experiences through this process by pulling out UI code into shared code parts, abstracting the UI away. Thos code parts are used from both the Desktop GUI and the web backend. While the GUI still uses controls etc. as usual, the web backend dynamically renders pages or delivers JSON to the client based on those information. The client consists of a good portion of script code to control the web UI.

Was quite a bit of work and took some serious refactoring to do that transition, but it was worth it. And you learn a lot about good and bad software design along the way, I can tell you that.