答:
I'm just gonna answer your reasons:

I don't understand how you come to that conclusion. Different languages have different features. Depends on scope, architecture of language, sometimes preferences of creators and many more reasons. Some features of a language may be bad, but your generalization is plain wrong IMHO.

Writing C++ just like Java may lead to worse code. E.g. nowadays with C++11 I avoid using new/delete, but use shared pointers. In your scenario I would rely only on new/delete. If your programmers understand only Java, train them or hire better ones.

Is that likely gonna happen? Why don't you write in Java in the first place? I think rewriting programs from scratch in a new language is generally a bad idea and you would need a really good justification for such a risk.

This is just an assumption.

Depends IMHO highly on your scenario or use case.

Title: Should we avoid language features that C++ has but Java doesn't?

Body:
Suppose I am limited to use C++ by the environment in the project. Is it good to prevent the use of some language features that C++ has but Java doesn't have (e.g.: multiple inheritance, operator overloading)?

I think the reasons are:

As Java is newer than C++, if Java doesn't provide a feature that C++ has, it means that the feature is not good, so we should avoid using it.

C++ code with C++ specific features (e.g.: friend functions, multiple inheritance) can only be maintained or reviewed by C++ programmers, but if we just write C++ like Java (without C++ language specific feature), the code can be maintained or reviewed by both C++ and Java programmers.

You may be asked to convert the code to Java some day

Code without C++ specific features is usually more maintainable

Every C++ language specific feature (e.g.: multiple inheritance) should have alternatives to be implemented in Java. If it doesn't, that means the design pattern or code architecture is problematic.

Is that true?


问:
Is it acceptable to copy and paste long but straightforward code instead of wrapping them into a class or function?
Suppose I have a segment of code to connect to internet and show connection results like it:

```<code>HttpRequest* httpRequest=new HttpRequest();
httpRequest->setUrl("(some domain .com)");
httpRequest->setRequestType(HttpRequest::Type::POST);
httpRequest->setRequestData("(something like name=?&age=30&...)");
httpRequest->setResponseCallback([=](HttpClient* client, HttpResponse* response){
    string responseString=response->getResponseDataString();
        if(response->getErrorCode()!=200){
            if(response->getErrorCode()==404){
                Alert* alert=new Alert();
                alert->setFontSize(30);
                alert->setFontColor(255,255,255);
                alert->setPosition(Screen.MIDDLE);
                alert->show("Connection Error","Not Found");
            }else if((some other different cases)){
                (some other alert)
            }else
                Alert* alert=new Alert();
                alert->setFontSize(30);
                alert->setPosition(Screen.MIDDLE);
                alert->setFontColor(255,255,255);
                alert->show("Connection Error","unknown error");
            }
        }else{
            (other handle methods depend on different URL)
        }
}
</code>```

the code is long, and it is commonly used, but the code above does not require any extra things such as custom function and class (HttpRequest and Alert are both provided by framework by default), and although the code segment is long, it is straightforward and not complex (it is long just because there are bundles of settings such as url, font size...), and the code segment has little variations among class (e.g.: url,request data, error code handle cases, normal handle cases...)

My question is, is it acceptable to copy and paste long but straightforward code instead of wrapping them in a function to reduce the dependency of code?

答:
This doesn't really have anything to do with copy and paste. If you take code from elsewhere, at the second you take the code it's your code and your responsibility, so whether it's copied or written completely by yourself doesn't make a difference.

In your alerts you make some design decisions. Most likely similar design decisions should be made for all alerts. So it's likely that you should have a method somewhere "ShowAlertInAStyleSuitableForMyApplication" or maybe a bit shorter, and that should be called.

You will have lots of http requests with similar error handling. You should likely not duplicate the error handling again and again and again but extract common error handling. Especially if your error handling gets a bit more elaborate (what about timeout errors, 401, and so on).

ContentLicense: CC BY-SA 3.0


问:
Should we avoid language features that C++ has but Java doesn't?
Suppose I am limited to use C++ by the environment in the project. Is it good to prevent the use of some language features that C++ has but Java doesn't have (e.g.: multiple inheritance, operator overloading)?

I think the reasons are:

As Java is newer than C++, if Java doesn't provide a feature that C++ has, it means that the feature is not good, so we should avoid using it.

C++ code with C++ specific features (e.g.: friend functions, multiple inheritance) can only be maintained or reviewed by C++ programmers, but if we just write C++ like Java (without C++ language specific feature), the code can be maintained or reviewed by both C++ and Java programmers.

You may be asked to convert the code to Java some day

Code without C++ specific features is usually more maintainable

Every C++ language specific feature (e.g.: multiple inheritance) should have alternatives to be implemented in Java. If it doesn't, that means the design pattern or code architecture is problematic.

Is that true?

答:
Just because the syntax seems similar on the surface doesn't mean that the two languages are compatible.

1, 4 and 5 are really the same question:

Now, I'm no fan of C++, but saying "Code without C++ specific features is usually more maintainable" is just ridiculous - do you really believe that Java got everything right, and took all the good features while ignoring all the bad ones? Do you really believe there is something that's universaly a "bad" or "good" feature? If there is, why don't we have one language that is purely good? And no, Java certainly isn't that language. Does that mean that Java and C++ are useless? Of course not.

What if your leaders decide that you're going to port to C#, rather than Java? Not only does C# support overriding operators, but it's also the default - if you're going to require people to use e.g. obj.Equals(obj2) instead of obj == obj2, people are going to make mistakes all the time. Even if you keep only to the common features of the two languages, there are different expectations, a different culture. If you do something like if (myField == null) in C++, people are going to see you're a novice immediately. If you use if (null == myField) in C#, people are going to see you're not really C# native yet - the reasons C developers learned to use the "flipped" variant no longer exists in C#.

Using your logic, we should have stuck with machine code or assembly or COBOL, because why ever change to something like Pascal, when it just adds new features that your programmers will have to learn? Why would we ever use something like SQL, when it doesn't even have loops? Why would we ever use something else than SQL, when SQL doesn't have loops and X does?

C++ code certainly cannot be maintained by Java programmers. I can't understand where you got this idea - what exactly remains when you limit C++ to only the features that work exactly the same as in Java? You're not even going to get method calls - not even function calls. Again, just because both langauges use curly braces, doesn't mean that the languages are in any way interchangeable.

Converting Java-like C++ code is going to be extremely error prone no matter what you do. There's just too many differences. If you care about having to rewrite your application in a different language, think about reasonable ways to modularize everything, so that you can replace the parts without breaking the whole. But in the end, YAGNI - no matter what you do, there's going to be a significant cost to making your code "ready to convert to Java". That's time that's very likely better spent on adding or improving your features.

We use different languages because they give us a different set of tools to solve problems. If you need executables that work "everywhere", go with Java. If you want code that compiles "everywhere", C++ works fine. If you want code that's easy to understand and parse, go with LISP or whatever. But I can tell you one thing - writing code in one language as if you were writing it in another is always a mistake, and you will suffer. Not to mention that when you actually hire a C++ guy, he's going to run the second he sees that "Java-ish compatible" code. And... the Java guy is going to do the same. You know, even "knowing" both C++ and Java, I'd run like hell :)

I actually had to work on (plain) C code written by a Pascal developer who seemed to think like you do. He used #defines to redefine C to look and feel more like Pascal, complete with things like "BEGIN translates to {". The result was rather predictable - code that neither C nor Pascal developers can understand, and full of bugs that were a result of the leaking "abstraction" of Pascal on top of C. And Pascal and C are almost identical from today's point of view. Even going C <-> C++ is much more of a difference, and that's still peanuts to something like C++ <-> Java.


问:
in dynamic language like javascript how do you know what the argument is?
In Java or Scala if I have an argument configuration: Conf, I can look for Conf class/trait/case class and see its construct so I know which arguments to pass.

Recently I started dealing with JavaScript, I see function like this:

```<code>function init(conf) {
  some body // as external developer to init I should not mess
            // with the internals here I just use init, proper design.
 }
</code>```

What I'm curious to know, how is it possible for me to know what to send exactly in conf? documentation? examples? sniff around init implementation? all look like bad alternatives for me, not well formed, depending on developer writing or not documentation providing or not examples.  isn't there a more formal strict way for me to know what conf means?

I must say that on my day to day work with statically typed languages I don't need almost no documentation I just look at the types functions receive and I know what I need to pass in most cases.

答:
Trial amd error.

Actually, I doubt there's a resource without a proper documentation in it.
If you really can't find what goes where, then you could  type the function's name without parentheses in the chrome live console, and then, if the functiom is not a native function, then it prints out the source of the function.:


问:
Methods of debugging code (Nightmare situation)
I am frequently tasked with debugging an application at my job. It is a BI Application that we deploy to businesses, which includes a test environment, and a production environment. I am wondering if there are any apps/tools/methods that people can suggest, based on these constraints:

Debugger cannot be used on client site or locally, because the software depends on custom third party applications that we don't have test environments for. (EDIT: to be fair, it is possible to debug locally in some cases. If we use nothing but the core code. Much of the problematic code resides in a dll that encapsulates third party specific communication: sockets, process pipes, soap calls, custom logic that changes the behavior of core code. Typically during an implementation or enhancement for a client, we would be writing new code to this area.)

There is virtually no logging done in our apps. There are no unit tests.

Version control only has 1 version of the full solution (using source safe 2005). So it's not possible to get a previous version of the entire solution, only individual files. (Unless someone knows ways around this).

Cannot reproduce locally, often times cannot reproduce on test environment (High chance that test and production are not the same version).

There is a high chance that the version the client is using is different from the one on source safe. This is because individual files are updated, which have embedded custom logic for that specific client. Often what happens is an update is made to a binary, which requires changes to several other binaries, but when a commit is done, no one has any record or knowledge of this. A somewhat common error I see is the 'Function/Method not found' or 'Method call has too many/too few parameters specified' on a clients environment.

This is a .net VB solution

Cannot install any software on client sites, but can locally

Our application is extremely customizable, but unfortunately the customization logic is spread out across all the classes and files, from the front end all the way to the data layer, including custom changes made to the database on a per client basis.

There are virtually no comments in the code. There is no documentation about the architecture. No documentation about the api. The only thing we have are hundreds upon hundreds of email chains that somewhat explain what's going on. The only people that know the code are the ones that originally wrote it, but they're no longer developers per say so they don't get involved that much.

And before you say it... yes I know; I want to shoot myself as well. It doesn't help that there's spaghetti code, hundreds of compiler warnings, and broken polymorphism that REALLY should be fixed, but I don't have a say in it.

Most common sort of errors I run into are null reference errors, invalid casts, and missing functions/function signature mismatches. Sometimes I am lucky and event viewer will log the class, method, and exception message. It's not the most helpful, but it's still something. The worst are the errors that have no trace, no repro steps besides a screenshot, and are generic error messages like the ones mentioned above. Sometimes it's not possible to find out why they occurred, only to pray that the environment is not properly configured, and that it will go away later.

I know this comes off as a bit of a rant, and to some extent it is. But I'm desperate for options. Are there other methods / tools I can use?

答:
Ignoring the issues you have in your team, it seem that the first one to address is to debug the code matching what is in production. Otherwise you might be chasing a bug that was already fixed in the code you have in your "Source control".
As this is .NET you could easily "decompile" the production binaries to compare the code with what you have. It's not an easy task but if you succeed this is a strong argument for a better source control tool that can tag released versions.</p>


问:
Why are semantics and type systems are so important?
I heard that semantics and type systems are very important for all programmers! But I why are they so important? I don't understand. Maybe they are imortant only for theoreticians and compiler developers?

In my practice I never think about semantics and type theory. As for me it is enough to know that the semantics defines the meaning of syntax. When I write + I just know that it is the addition operation. And it is enough for me.

Then, I want to describe my thoughts about type systems. Also, when I write int i;, I know that int is an integer and it is enough for me.

Another case - it is important to know what the difference beetwen static and dynamic, weak and strong type systems.

Tell me please, are there any practical benefits from the knowledge of semantics and type systems?

答:
Sublte semantic differences

Consider this simple program:

```<code>i = 1000'000'000
j = i * i
</code>```

This operation can behave very differently depending on the semantics of integers in your language:

Some languages will seamlessly switch to big integers producing the correct result (1000'000'000'000'000'000), but degrading performance (e.g. python)

Some languages will seamlessly switch to floats, producing an approximate result (e.g. javascript and php)

Some languages will raise an error because the result doesn't fit a 32 bit integer (e.g. C# with checked arithmetic enabled)

Some languages will wrap around (e.g. C# with checked arithmetic disabled, returns -1486618624). The precise wrap around behaviour can differ depending on the size of the integer type and the representation of the sign (C# uses two's complement)

Some languages will invoke undefined behavior (e.g. C and C++)

Some languages will consider the literal signed, others as unsigned

Pretty big differences for something as simple as multiplying two integers.

Or consider the case where you write 1 + "1a".

Some languages will produce a compiletime error, asking you to clarify what you meant.

Some languages will produce a runtime error because you can't add integers and strings

Some languages will attempt to parse the string as number, and raise an error because "1a" is no valid decimal number

Some languages will successfully parse the string, e.g. because they stop parsing at the first non digit

Some languages will treat both as string and concatenate them.

C will treat "1a" as a pointer to char and perform pointer arithmetic, returning "a".

Expressiveness of the type system

Things get more interesting once you consider complex types.

Different type systems allow you to express different ideas elegantly. They catch different errors at compile or runtime. They restrict you in different ways. They require different amounts of effort to learn.

Since each programmer and language designer weights those goals differently (or isn't even familiar with the advantages of some of them) we get a lot of different languages.

C has no convenient way to write a container that works with different types of elements. C++ has very powerful templates, but they add a lot of complexity to the language.

Go and Java both support interfaces. In java the class needs to explicitly implement an interface, in Go a type implicitly implements all interfaces matching its members. The Go approach allows a consumer to define the interfaces that fit its requirements, but it can produce false matches when a member has the same name, but different meaning.

Immutability simplifies reasoning about the code and enables sharing instances, but can make it inconvenient to manipulate your data.

Static typing catches many errors at compile time. But catching more errors increases the effort required to satisfy the compiler. Depending on how you express those compile time constraints you catch different errors. We're always looking for new type systems that find more errors or require less effort.

Rust has a type system that can prove that no two threads will unsafely modify a mutable object at the same time. But in exchange it requires meticulous ownership tracking, which many programmers will consider too inconvenient.

There are many features a language can offer, such as objects, multiple inheritance, deterministic destruction, memory safety, a GC, discriminating unions, higher order functions, generic containers/algorithms, operator overloading.

Each is useful in some situations, but you need to weight them against the complexity of the language and thus the effort to learn it. Some features are even incompatible or at least interact badly with each other.

Body:
Sublte semantic differences

Consider this simple program:

i = 1000'000'000
j = i * i

This operation can behave very differently depending on the semantics of integers in your language:

Some languages will seamlessly switch to big integers producing the correct result (1000'000'000'000'000'000), but degrading performance (e.g. python)

Some languages will seamlessly switch to floats, producing an approximate result (e.g. javascript and php)

Some languages will raise an error because the result doesn't fit a 32 bit integer (e.g. C# with checked arithmetic enabled)

Some languages will wrap around (e.g. C# with checked arithmetic disabled, returns -1486618624). The precise wrap around behaviour can differ depending on the size of the integer type and the representation of the sign (C# uses two's complement)

Some languages will invoke undefined behavior (e.g. C and C++)

Some languages will consider the literal signed, others as unsigned

Pretty big differences for something as simple as multiplying two integers.

Or consider the case where you write 1 + "1a".

Some languages will produce a compiletime error, asking you to clarify what you meant.

Some languages will produce a runtime error because you can't add integers and strings

Some languages will attempt to parse the string as number, and raise an error because "1a" is no valid decimal number

Some languages will successfully parse the string, e.g. because they stop parsing at the first non digit

Some languages will treat both as string and concatenate them.

C will treat "1a" as a pointer to char and perform pointer arithmetic, returning "a".

Expressiveness of the type system

Things get more interesting once you consider complex types.

Different type systems allow you to express different ideas elegantly. They catch different errors at compile or runtime. They restrict you in different ways. They require different amounts of effort to learn.

Since each programmer and language designer weights those goals differently (or isn't even familiar with the advantages of some of them) we get a lot of different languages.

C has no convenient way to write a container that works with different types of elements. C++ has very powerful templates, but they add a lot of complexity to the language.

Go and Java both support interfaces. In java the class needs to explicitly implement an interface, in Go a type implicitly implements all interfaces matching its members. The Go approach allows a consumer to define the interfaces that fit its requirements, but it can produce false matches when a member has the same name, but different meaning.

Immutability simplifies reasoning about the code and enables sharing instances, but can make it inconvenient to manipulate your data.

Static typing catches many errors at compile time. But catching more errors increases the effort required to satisfy the compiler. Depending on how you express those compile time constraints you catch different errors. We're always looking for new type systems that find more errors or require less effort.

Rust has a type system that can prove that no two threads will unsafely modify a mutable object at the same time. But in exchange it requires meticulous ownership tracking, which many programmers will consider too inconvenient.

There are many features a language can offer, such as objects, multiple inheritance, deterministic destruction, memory safety, a GC, discriminating unions, higher order functions, generic containers/algorithms, operator overloading.

Each is useful in some situations, but you need to weight them against the complexity of the language and thus the effort to learn it. Some features are even incompatible or at least interact badly with each other.


答:
Java has features that C++ doesn't, like a built-in, fast, reliable garbage collector, a single-root object hierarchy, and powerful introspection.

Java's other features are designed to work together with the Java-exclusive features, and many of Java's omissions of C++ features are possible because the new features make up for the lack. For example, Java doesn't have stack-allocated objects with deterministic destructors, but has finally blocks (and try-with-resources since Java 7) and the garbage collector to make up for this lack.

C++ doesn't have finally blocks or garbage collection. If you don't use destructors because they don't exist in Java (I don't count finalizers), you're on the C level of resource management (i.e. all manual), except that you can't even group your cleanup into a cleanup block that you goto to, because Java doesn't have goto either. Do you really think that improves maintainability?

Java has an overarching object hierarchy where every class ultimately derives from Object, and the few primitive types can be auto-boxed into such classes too. This enables writing containers of objects once, to hold pointers to Object. Java 5 introduced generics, which get rid of the casts such containers necessitate, but still compile down to pretty much the same code.

C++ doesn't have such a hierarchy. To facilitate the writing of containers that work for multiple types, you use templates, which are blueprints that are instantiated by the compiler as necessary for different types. Will you forbid the use of templates (and macros) and go the C route of either writing the same container code over and over for different types, or using void pointers? (Wait, Java doesn't have void pointers!) Are you sure this would increase maintainability?

A decent language has a multitude of features that are designed to work together. By forbidding features from language A because language B doesn't have them, you are crippling language A, because you are not at the same time adding features from B that make B a coherent whole.

That's not to say that you must not restrict the allowed features of C++. C++ is a big, historically grown language that emphasizes enabling the programmer to do what he wants over safety and ease-of-use, and not all of its features in all their flexibility are necessary to build good programs. There are many coding standards that restrict the use of some features; for example Google's guidelines mostly forbid multiple inheritance, complex templates, and exceptions (though that last one is for historical reasons). But no feature is forbidden "because Java doesn't have it"; the features are considered within the framework of C++ alone.


答:
When I write + I just know that it is the addition operation.

And how do you know that? Because the semantics of the language say so!

By the way, that isn't even universally true. For example, for Strings in Java, + is not addition, but concatenation!

when I write int i;, I know that int is an integer and it is enough for me.

And how do you know what an integer is? The type system tells you!

By the way, that also isn't universally true. For example, in Java, int is not an integer but rather a member of the modulo ring ℤ232!

it is important to know what the difference beetwen static and dynamic, weak and strong type systems.

So, you say type systems are important, but then ask whether they are important?

Title: Why are semantics and type systems are so important?

Body:
I heard that semantics and type systems are very important for all programmers! But I why are they so important? I don't understand. Maybe they are imortant only for theoreticians and compiler developers?

In my practice I never think about semantics and type theory. As for me it is enough to know that the semantics defines the meaning of syntax. When I write + I just know that it is the addition operation. And it is enough for me.

Then, I want to describe my thoughts about type systems. Also, when I write int i;, I know that int is an integer and it is enough for me.

Another case - it is important to know what the difference beetwen static and dynamic, weak and strong type systems.

Tell me please, are there any practical benefits from the knowledge of semantics and type systems?


问:
Can the "level 256 bug" in the game of Pacman be considered an unhandled segfault?
I am trying to explain segmentation faults to someone, and I was thinking about the level 256 kill-screen in Pacman, and how it's triggered by integer overflow, and how similar the behavior is to the "unknown state" oft-described in a segmentation fault.

I want to say this is a good example of what I call an "unhandled segfault", but I would rather get a second opinion before I potentially spread misinformation.

I tried looking it up, but all I'm getting are documents on the bug itself, as well as that collab between Hipster Whale and Namco.

So, would you consider the behavior in level 256 of Pacman to be an example of unhandled segmentation violation?

答:
Definitely not.

Accessing a memory address you didn't allocate is always a programming error. And acting on the information you get out of it produces undefined behavior, that much is accurate. I have no idea what platform the original Pac-man was written for, but I'm pretty sure it exhibited this behavior just like any other von Neumann machine.

However, "segmentation fault" is a technical term for a much more specific condition. It happens when the computer automatically detects that this happened and terminates the process rather than allow undefined behavior to occur. This requires a specific (segmented) memory model with sophisticated ownership tagging. I don't think 1980 arcade games had that, and in fact the behavior of the game suggests that the error was not detected, and the undefined behavior did occur.


答:
It looks like you're confusing "undefined behaviour" and "segmentation fault".

There is no such thing as an unhandled segfault. A segmentation fault is error handling, by definition.

If you don't have an OS that detected the bad memory access and terminated the process for safety, then you don't have a segmentation fault.

If anything, then, this is a pretty good example of how UB doesn't always result in a segfault.

Title: Can the "level 256 bug" in the game of Pacman be considered an unhandled segfault?

Body:
I am trying to explain segmentation faults to someone, and I was thinking about the level 256 kill-screen in Pacman, and how it's triggered by integer overflow, and how similar the behavior is to the "unknown state" oft-described in a segmentation fault.

I want to say this is a good example of what I call an "unhandled segfault", but I would rather get a second opinion before I potentially spread misinformation.

I tried looking it up, but all I'm getting are documents on the bug itself, as well as that collab between Hipster Whale and Namco.

So, would you consider the behavior in level 256 of Pacman to be an example of unhandled segmentation violation?


答:
A class and/or a function is better, at least in my opinion. For once, it makes the file smaller which is a very heavy gain if you deal with web applications or applications for devices with little storage (IoT, older phones, etc.)

And obviously the best point is that if you have something to change due to new protocols, etc. you just change the content of the function and not countless of times you put this function somewhere which might even be in different files making them even harder to find and change.

I wrote a whole SQL interpreter so I could switch better from MySQL to MySQLi in PHP, because I just have to change my interpreter and everyting is working, although that is an a bit of an extreme example.

Title: Is it acceptable to copy and paste long but straightforward code instead of wrapping them into a class or function?

Body:
Suppose I have a segment of code to connect to internet and show connection results like it:

```<code>HttpRequest* httpRequest=new HttpRequest();
httpRequest->setUrl("(some domain .com)");
httpRequest->setRequestType(HttpRequest::Type::POST);
httpRequest->setRequestData("(something like name=?&age=30&...)");
httpRequest->setResponseCallback([=](HttpClient* client, HttpResponse* response){
    string responseString=response->getResponseDataString();
        if(response->getErrorCode()!=200){
            if(response->getErrorCode()==404){
                Alert* alert=new Alert();
                alert->setFontSize(30);
                alert->setFontColor(255,255,255);
                alert->setPosition(Screen.MIDDLE);
                alert->show("Connection Error","Not Found");
            }else if((some other different cases)){
                (some other alert)
            }else
                Alert* alert=new Alert();
                alert->setFontSize(30);
                alert->setPosition(Screen.MIDDLE);
                alert->setFontColor(255,255,255);
                alert->show("Connection Error","unknown error");
            }
        }else{
            (other handle methods depend on different URL)
        }
}
</code>```

the code is long, and it is commonly used, but the code above does not require any extra things such as custom function and class (HttpRequest and Alert are both provided by framework by default), and although the code segment is long, it is straightforward and not complex (it is long just because there are bundles of settings such as url, font size...), and the code segment has little variations among class (e.g.: url,request data, error code handle cases, normal handle cases...)

My question is, is it acceptable to copy and paste long but straightforward code instead of wrapping them in a function to reduce the dependency of code?


答:
is it acceptable to copy and paste ...

No.

For me, the deciding argument is this one:

... it is commonly used ...

If you use a piece of code in more than one place then, when it changes, you have to change it in more than one place or you start to get inconsistencies - "odd things" start to happen (i.e. you introduce Bugs).

it is straightforward and not complex ...

And so should be all the easier to refactor into a function.

... there are bundles of settings such as url, font size ...

And what do users love to change?  Fonts, font sizes, colours, etc., etc.

Now; in how many places will you have to change that same piece of code to get them all the same colour/font/size again?  (Recommended answer: just one).

... the code segment has little variations among class (e.g.: url,request data, error code handle cases, normal handle cases...)

Variation => function parameter(s).


答:
Suppose I am limited to use C++ by the environment in the project. Is it good to prevent the use of some language features that C++ has but Java doesn't have (e.g.: multiple inheritance, operator overriding)?

No.

If "by the environment of the project" you are limited to using C++, then there is little, if any, point in even thinking about any other technology, no matter how much you might personally prefer/hope to use/evangelise it.

Whether "Technology X" or "Y" supports any given feature should have no bearing whatever on the way in which you build your C++ application.

It's a C++ application, presumably for some "Good Reason" (now or in the past) so you should write it as a C++ application, using whatever that particular "toolbox" provides.

If and when there's a Requirement to port the application to some other technology then (and only then) you might consider features on other platforms.  There is no point "cutting off your nose to spite your face" on the off-chance that something might happen.  Remember, though, that wholesale re-writing is an expensive, risky operation that Management are unlikely to take on without a very Good Reason to do so.

There was a similar ("to use or not to use") debate some years back in the Visual Basic [.Net] World, where Someone had the bright idea that you should write Visual Basic applications without using any of the [core language] functionality provided by the Microsoft.VisualBasic namespace.  It'd be like trying to write a C++ application without the std:: namespace; OK, it's possible but why on Earth would anyone in their right mind bother to do so?


答:
This isn't a problem unique to JavaScript, or even just dynamic languages. For example, you might have the equivalent Java code:

```<code>void init(Configuration conf) {
    ...
}
</code>```

and then discover that Configuration is an final class with no public constructors and you're left searching around for how to obtain an instance of that class.

Typically, looking at the code is your first course of action, assuming the source is available. The source is the only official, up-to-date, guaranteed-to-be-right documentation for what the function does. If it's a small, well written function, working out what conf needs to be should be an easy task.

If the library/framework in question has accompanying documentation, you may be able to use that to understand how to use the function.

Finally, specific to JavaScript, if you want static typing, use TypeScript, which is a free, open-source statically typed extension to JavaScript.

Title: in dynamic language like javascript how do you know what the argument is?

Body:
In Java or Scala if I have an argument configuration: Conf, I can look for Conf class/trait/case class and see its construct so I know which arguments to pass.

Recently I started dealing with JavaScript, I see function like this:

```<code>function init(conf) {
  some body // as external developer to init I should not mess
            // with the internals here I just use init, proper design.
 }
</code>```

What I'm curious to know, how is it possible for me to know what to send exactly in conf? documentation? examples? sniff around init implementation? all look like bad alternatives for me, not well formed, depending on developer writing or not documentation providing or not examples.  isn't there a more formal strict way for me to know what conf means?

I must say that on my day to day work with statically typed languages I don't need almost no documentation I just look at the types functions receive and I know what I need to pass in most cases.

Body:
This isn't a problem unique to JavaScript, or even just dynamic languages. For example, you might have the equivalent Java code:

void init(Configuration conf) {
    ...
}

and then discover that Configuration is an final class with no public constructors and you're left searching around for how to obtain an instance of that class.

Typically, looking at the code is your first course of action, assuming the source is available. The source is the only official, up-to-date, guaranteed-to-be-right documentation for what the function does. If it's a small, well written function, working out what conf needs to be should be an easy task.

If the library/framework in question has accompanying documentation, you may be able to use that to understand how to use the function.

Finally, specific to JavaScript, if you want static typing, use TypeScript, which is a free, open-source statically typed extension to JavaScript.


问:
Architecture: API with slightly different behavior depending on the logged-in user roles
How should I structure a piece of code that executes an operation, but may have slightly different behavior depending on, let's say, user roles?

Example:
My app has a 'manager' and a 'employee' roles. There are many managers in my app, and each of them have many employees. I have a dashboard where managers and their employees can add/edit/delete products.

Both can edit the products the have created themselves, but managers can edit products belonging to his employees. If a manager edits a product created by an employee, the employee will get an email notification about the edit.

The issue I have, is that I´m creating if/else or switch/case statements for checking the user roles, and I feel once I add new roles my code will need to check for them too and my code will become harder to read.

For example:

```<code>// What I currently have:
public function updateProductForUser(Product $product, UserInterface $user)
{
    $userWhoCreatedProduct = $product->getCreatedByUser();

    if ($userWhoCreatedProduct === $user) {
        // If the user who created the product is the same one trying to update it,
        // then go ahead and execute the update.
        $this->_doUpdateProductForUser($product, $user);
        return;

    } elseif ($user instanceof Manager) {
        $allManagerEmployees = $this->someService->findAllEmployeesOfManager($user);

        if (in_array($userWhoCreatedProduct, $allManagerEmployees)) {
            // If the user trying to update the product is a manager, and the product was
            // created by an employee of the manager, then execute the update but also
            // send an notification to the employee that the product he created got updated
            // by his manager.
            $this->_doUpdateProductForUser($product, $user);
            $this->notifyUserThatProductGotUpdated($product);
        }
    }
}
</code>```

How can I improve this? Is there a better way? What are the pitfalls of the implementation? Any advice is very welcomed. Thanks!

答:
You can make the code a little more maintainable if you

Put the product handling logic (without permission logic and without other side effects) into a separate service class ProductDomain. (See Separation of concerns for details)

Create a ProductHandlingService class that uses ProductDomain and applies permissions and other side effects

give the conditions a name (See Strategy pattern for details)

The ProductHandlingService  might look like this:

```<code>public function updateProductForUser(Product $product, UserInterface $userWhoWantsToModify)
{
  if ($strategy->userIsAllowedToModifyProduct($product, $userWhoWantsToModify) {
    $ProductDomain->_doUpdateProductForUser($product, $userWhoWantsToModify);
    if ($strategy->userNeedsInfoAboutProductUpdate($product, $product->getCreatedByUser(),
          $userWhoWantsToModify) {
      $this->notifyUserThatProductGotUpdated($product);
    }
  }
}
</code>```

Advantages over the original design:

core-ProductDomain, Permission-detection and special-handling can be tested independently.

During software lifetime it is likely that Permission-detection and special-handling will be change often due to political reasons.

core-ProductDomain is likely to change not very often and mostly because of technical reasons.

Body:
You can make the code a little more maintainable if you

Put the product handling logic (without permission logic and without other side effects) into a separate service class ProductDomain. (See Separation of concerns for details)

Create a ProductHandlingService class that uses ProductDomain and applies permissions and other side effects

give the conditions a name (See Strategy pattern for details)

The ProductHandlingService  might look like this:

public function updateProductForUser(Product $product, UserInterface $userWhoWantsToModify)
{
  if ($strategy->userIsAllowedToModifyProduct($product, $userWhoWantsToModify) {
    $ProductDomain->_doUpdateProductForUser($product, $userWhoWantsToModify);
    if ($strategy->userNeedsInfoAboutProductUpdate($product, $product->getCreatedByUser(),
          $userWhoWantsToModify) {
      $this->notifyUserThatProductGotUpdated($product);
    }
  }
}

Advantages over the original design:

core-ProductDomain, Permission-detection and special-handling can be tested independently.

During software lifetime it is likely that Permission-detection and special-handling will be change often due to political reasons.

core-ProductDomain is likely to change not very often and mostly because of technical reasons.


问:
Does this class design violate the single responsibility principle?
Today I had an argument with someone.

I was explaining the benefits of having a rich domain model as opposed to an anemic domain model. And I demoed my point with a simple class looking like that:

```<code>public class Employee
{
    public Employee(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastname;
    }

    public string FirstName { get private set; }
    public string LastName { get; private set;}
    public int CountPaidDaysOffGranted { get; private set;}

    public void AddPaidDaysOffGranted(int numberOfdays)
    {
        // Do stuff
    }
}
</code>```

As he defended his anemic model approach, one of his arguments was: "I am a believer in SOLID. You are violating the single responsibility principle (SRP) as you are both representing data and performing logic in the same class."

I found this claim really surprising, as following this reasoning, any class having one property and one method violates the SRP, and therefore OOP in general is not SOLID, and functional programming is the only way to heaven.

I decided not to reply to his many arguments, but I am curious what the community thinks on this question.

If I had replied, I would have started by pointing to the paradox mentioned above, and then indicate that the SRP is highly dependent on the level of granularity you want to consider and that if you take it far enough, any class containing more than one property or one method violates it.

What would you have said?

Update: The example has been generously updated by guntbert to make the method more realistic and help us focus on the underlying discussion.

答:
You are violating the single responsibility principle (SRP) as you
  are both representing data and performing logic in the same class.

It sounds very reasonable for me. Model might not have public properties if exposes actions. It is basically a Command-Query Separation idea. Please note that Command will have private state for sure.


问:
Are there more or less straightforward guidelines for adopting one or another approach to reporting in DDD?
Vernon and Millett describe several patterns of getting data for ui (reporting in general) needs.

Though some pros and cons of each approach are discussed, I could not get a robust understanding of which to use when.

Consider ad hoc queries. Vernon calls them Use Case Optimal Query, but does not say too much. Millett just warns about performance vs dry violation tradeoff. Some blogs discuss it as the step towards CQRS.

And all this seems to be more a matter of personal preferences rather than a well-grounded choice. And as soon as subjectivity appears while discussing architectural decisions conflicts occur.

Update I'd add more details, I suppose...

Preface

First, we do not really do DDD. Absolutely. In no way.

We use (sad but true) TransactionScript with AnemicModels.

Yes, we do have complex Domain, where DDD won't be an overkill.

Now I hear you say: "DDD is about Strategic Patterns!". I know, they are also not with us. =)

Nonetheless, all patterns are useful. if applied reasonably.

Nobody prohibits making converging steps from both sides. I have already stressed in comments that Tactical Patterns worry team the most, and can bring dividends relatively fast.

The case
In our business rules we extensively use DTOs which contain all data sufficient for performing command processing. However, we use same DTOs for assembling data for UI/Reporting. It introduces very unpleasant coupling. Practice shows that these DTOs are often bended towards UI needs. But it is UI what changes frequently for several iterations. Users understand they'd like to have more data differently structured and organized.

Contrary to UI, Commands are much more stable, and when structure of command needs to change UI gets almost inevitably changed as well.

Thus 'breathing' UI 'shakes' the layers used by business logic which processes commands. We often find ourselves aligning interfaces and fixing broken tests.

With all said above I found it reasonable to TRY to decouple queries from command processing in absolutely new functionality.

IBlaBlaQuery is the exact implementation of Use Case Optimal Repository Query. Client receives specific view data + data for building commands. It is covered with unit and integration tests. Code works, some teammates like the solution.
Yet exist those who

- a) insist on violated DRY principle,

- b) complain about new unaccustomed design.

You probably ask here: "Why didn't you discuss this design prior putting it into life?" And that is the place for my question.

They keep pushing on defending DRY, you offer them to face the facts and agree on fragility of design, they declare they don't see it or it is not such a big problem as a radically new approach. Other developers prefer to stay neutral and do not explicitly express their opinions.

Cannot you give us unequivocal solid arguments? - Then we do not accept and even consider a trial of your design.

After several such iterations you just recall sayings "Practice is the criterion of truth" and "It's better ask for forgiveness than permission" and voluntary give it a go instantly becoming a jackass. (Can admit I really am, but simply do not notice it.)

That's why I try to avoid subjectivity and ask for formal objective criteria.

答:
Is it possible to just directly query ORM to get UI/Report data? It is usually the most efficient way. If you do need some sophisticated business logic to be involved in reporting because of current big gap between db and required data set - well, you might consider saving some redundant stuff when your command results persist or even run report data preparation commands as a dedicated service. I would say you are never wrong when you have db (the same or dedicated extra one) matching your reporting needs.

The worst thing ever for me personally is mixing command and query logic in the same aggregate, so it is a big deal to be able report by some plain SQL without much DDD stuff involved.


问:
How to approach hours forecasting
I need to forecast budgeted hours for 2 departments to help them schedule staff as currently the best they can do is just wing it. When we receive a job proposal I'll have the person submitting the form input that job's budgeted hours into each department as float field.

Jobs can have hours budgeted for Dept. A, Dept. B, or both.  Jobs have start and end dates. It's been decided by my supervisors that simply dividing the job hours evenly across all days will be a useful gauge.  What I want to do is sum [all jobs] daily totals for Dept A and Dept B. Here's where it get's complex...

Dept. A works 7 days a week and Dept. B works regular business days.

Both departments need the flexibility to mark a day as closed and take the hours allocated to that day and push them to the remaining days.

But I also want to be able to put holidays in or events where we know far in advance we won't be open and instead of pushing the hours forward it distributes them back and forward. For example, Dept. A will never work on the day of a Superbowl.

I am looking for recommendations about how to approach this problem, specifically the days closed.  I was thinking I might have a table in the database simply tracking closed days?

I'm not looking for help writing the code but rather help understanding how to design this process more generally.

答:
I'd model a calendar (ie an array of 365 elements).

the difficulty using this system is that a block of days gets allocated as many individual days rather than a single entry, however I expect you'll be assigning a tag or some label to each logical entry that can be used to identify each block of days so that you can edit a single (logical) entry.

The advantage to storing everything daily is that you can pre-allocate weekends, holidays, team-meetings as you like, but also individual members holidays (or other absences from working) even if that means simply reducing the total hours available for a particular day.

Its also easy to understand, and reporting/searching on the model is easy too.

Title: How to approach hours forecasting


答:
You're going to need a list of days closed and possibly even make it group specific. Writing an algorithm to predict the date of the Superbowl next year is just not worth it.

This allows you to create a list of all the days in a given time range in your code to exclude. Some database-centric solutions have a table with all the days already in it for a reasonable length of time: since the company started to 5 years in the future.), and then flag any days (weekends, holidays, other/Super Bowl) because it's easier to read/join data than create it.

The biggest hurdle may be getting someone to populate this table. Weekends and holidays that are always on the same day of the year, can be generated. You could flag individual groups/teams that always or never work weekends, but the exceptions will just make this more complicated. There will be exception.

Title: How to approach hours forecasting

Body:
I need to forecast budgeted hours for 2 departments to help them schedule staff as currently the best they can do is just wing it. When we receive a job proposal I'll have the person submitting the form input that job's budgeted hours into each department as float field.

Jobs can have hours budgeted for Dept. A, Dept. B, or both.  Jobs have start and end dates. It's been decided by my supervisors that simply dividing the job hours evenly across all days will be a useful gauge.  What I want to do is sum [all jobs] daily totals for Dept A and Dept B. Here's where it get's complex...

Dept. A works 7 days a week and Dept. B works regular business days.

Both departments need the flexibility to mark a day as closed and take the hours allocated to that day and push them to the remaining days.

But I also want to be able to put holidays in or events where we know far in advance we won't be open and instead of pushing the hours forward it distributes them back and forward. For example, Dept. A will never work on the day of a Superbowl.

I am looking for recommendations about how to approach this problem, specifically the days closed.  I was thinking I might have a table in the database simply tracking closed days?

I'm not looking for help writing the code but rather help understanding how to design this process more generally.


答:
I will answer your questions in order.

If Java doesn't provide a feature that C++ has, it means that the feature is not good, so we should prevent using it.

Yes, any feature not present in Java is anathema on the hard drive.  It must be burned from your code base.  Those who do not obey will be scrounged, their souls used to placate the RAID gods.

C++ code with C++ specific features (e.g.: friend functions, multiple inheritance) can only be maintained or reviewed by C++ programmers, but if we just write C++ like Java (without C++ language specific feature), the code can be maintained or reviewed by both C++ and Java programmers.

When in doubt, write code for the least competent member of your team.  Code is read far more often than it is written, and code that is as clever as you can write is too clever to read.  Code reviews that your front desk staff won't understand should be rejected.  To help, teach them how to program in visual basic 2.0 over the weekend, then emulate their coding style in whatever language you are using.

You may be asked to convert the code to Java some day

True!  But why stop at Java?  You may be asked to convert the code to basic, assembler and/or perl one day.  As there are perl interpreters in every language out there, simply write your program as a long perl string, and marshal arguments into it in the language of choice.

Now when you need to change languages, simply rewrite the code wrapping the perl string.

Code without C++ specific features is usually more maintainable

It is true that code that uses less features is easier to maintain.  And as all languages are equivalent to a Turing Machine, and a Turing Machine has the fewest features of any programming language, have the above perl interpreter actually run a Turing Machine (tape and all) that solves your problem.

Every C++ language specific feature (e.g.: multiple inheritance) should have alternatives to be implemented in Java. If it doesn't, that means the design pattern or code architecture is problematic.

The C++ language specific features actually have a valuable use.  As they are not Java, they are anathema, and those who use it can be branded heretics.  If C++ did not have those language features, you would not be able to find those you need to sacrifice.  C++ language features solve problems!

Look, C++ and Java have a different set of capabilities.  Programming in the intersection of C++ and Java results in code that has thrown away most of the advantages of both languages.

Java was developed partially as a reaction to some abuse of C++ features.  This doesn't mean that the reaction was justified, especially years afterwards when the features have matured.

You can do horrible things with operator overloading; but no language can prevent horrible code from being written in the language, unless it stops all code from being written in the language.

And you can also do very elegant things with operator overloading.  Simple things, like a complex number or matrix class that works like complex number or a matrix.

Caution about using C++ features not available in Java should be viewed with caution.  Just because your current set of developers at their current skill level don't understand a feature doesn't mean it should never be used; at the same time, just because you can use a feature, doesn't mean you should.  However, in a Java-heavy shop, odds are resistance will be stronger than it should be against non-Java-esque features.

Conversion of code between languages is best done with a rewrite, no matter how structurally similar they are.  Any attempt to do so without such a rewrite is going to fail miserably.

Many C++ specific features are wonders for maintenance.  Type erasure (like std::function) lets you decouple hierarchies, which reduces dependencies.  Smart pointers and deterministic lifetimes and RAII reduce runtime surprises, and move resource boilerplate out of the way.  Heavy static type-checks mean that code fails to compile, instead of failing to work.  Mix-ins reduce code duplication.  ADL allows ad-hoc independent extension of interfaces between type hierarchies.  Lambda lets you write code next to where it is used.  Forwarding and moving reduce copies, and make functional style (side-effect-free) programming efficient.  Operator overloading reduces line noise, and makes code look more like the math it is modelling.

Beware the Turing Tar pit.  You can implement everything in any language (including a raw Turing Machine with Tape), but that doesn't mean you should.  Emulating C++ features using Java-esque constructs in C++ is a horrible idea; it will result in unmaintainable code that nobody can read or understand.

You can take inspiration from Java designs and port them over to C++.  I am a great fan of taking Python language features and implementing them in C++, because I like the syntax.  But that doesn't mean I write my class methods as static methods taking an explicit self, then write a wrapper that forwards the non-static method call to it.

Modern C++ is not all that much like the language Java emulated and rejected.  Don't get locked down by one language's features; there is no "one true language".  Learn about new languages and their features, and absorb their distinctiveness.


答:
No one should be writing any code that other coders don't understand. If you think language lock is a problem, wait until you have developer lock. One is more likely to hold you hostage than the other.

There really are no technical reasons. What you've created is a scenario where a language was used for whatever reason, but many current and possibly future developers don't really understand it.

My guess is, Java developers are likely to write C++ the way they write in Java, so why make it a rule. You may discover some C++ specific features that are easier to implement and maintain with a little C++ instruction/documentation for your Java developers than the big ball of Java mess they would otherwise be stuck with.

This has been an argument about the problems of BASIC programmers moving to object-oriented languages. It's not that they implement OOP practices at the detriment of new devs who don't understand it, but that they don't implement it at all. If they do, they usually get it wrong. If something is done poorly, it needs to be removed regardless of the reason.

Other than someone just blindly copying and pasting code, they're going to do it in many areas they don't understand anyway.


答:
All of your reasons can be disproved:

If Java doesn't provide a feature that C++ has, it means that the feature is not good, so we should prevent using it.

It doesn't mean the the feature is not good (no feature can be inherently bad). It only means that the feature was frequently misused (or impossible to implement due to fundamental concepts, like direct pointers vs garbage collection). Java by definition is aimed to be easier and more programmer-friendly, hence the removal of features that proven themselves to be easily abusable.

C++ code with C++ specific features (e.g.: friend functions, multiple inheritance) can only be maintained or reviewed by C++ programmers, but if we just write C++ like Java (without C++ language specific feature), the code can be maintained or reviewed by both C++ and Java programmers.

Oh can it be? Let's see simplest C++ code:

```<code>int len = mystring->size();
</code>```

Oops, no "language-specific" features used, yet it's already unmaintainable by Java devs! Because in Java you dereference with "." while here it's "->.

You may be asked to convert the code to Java some day

Or C#. Or Haskell. Or Python. Or Ruby. Or COBOL (yes, you can!). How can you tell the future?

Code without C++ specific features is usually more maintainable.

Exactly opposite. Every feature was introduced in order to make programming easier hence more maintainable. Eg: take a program operating on floats. Now upgrade it to handle complex numbers. Operator overloading to the rescue!

Every C++ language specific feature (e.g.: multiple inheritance) should have alternatives to be implemented in Java. If it doesn't, that means the design pattern or code architecture is problematic.

But Java DOES have multiple inheritance! It's called "interface". Java implementation is a problematic workaround to avoid the dreaded diamond caused by having everything derive from Object. It's done by introducing interface which sole purpose is to be something that does not derive from Object. C++ never had this problem - there is no mandatory common base so every class can function as an interface without the dreaded diamond.

Side note: Java recently introduced ... concrete methods in interfaces. Added a feature C++ always had to solve a problem that was never there.

You've also only mentioned very few "things that C++ has but Java does not". One of the biggest differences between C++ and Java is the control over memory layout. You can create array of pointers to objects (just like in Java) OR you can create contiguous memory block. Now, if I was to worry about a C++ feature that may mislead Java devs, something as hidden and subtle as this one would rank on my list much higher than obvious and recognizable on first sight things like multiple inheritance or overloaded operators.

Bottom line: Clean code is clean code. Java or C++ - same difference. Just keep it simple. Unnecessary complications are the leading cause of bad code.

Body:
All of your reasons can be disproved:

If Java doesn't provide a feature that C++ has, it means that the feature is not good, so we should prevent using it.

It doesn't mean the the feature is not good (no feature can be inherently bad). It only means that the feature was frequently misused (or impossible to implement due to fundamental concepts, like direct pointers vs garbage collection). Java by definition is aimed to be easier and more programmer-friendly, hence the removal of features that proven themselves to be easily abusable.

C++ code with C++ specific features (e.g.: friend functions, multiple inheritance) can only be maintained or reviewed by C++ programmers, but if we just write C++ like Java (without C++ language specific feature), the code can be maintained or reviewed by both C++ and Java programmers.

Oh can it be? Let's see simplest C++ code:

int len = mystring->size();

Oops, no "language-specific" features used, yet it's already unmaintainable by Java devs! Because in Java you dereference with "." while here it's "->.

You may be asked to convert the code to Java some day

Or C#. Or Haskell. Or Python. Or Ruby. Or COBOL (yes, you can!). How can you tell the future?

Code without C++ specific features is usually more maintainable.

Exactly opposite. Every feature was introduced in order to make programming easier hence more maintainable. Eg: take a program operating on floats. Now upgrade it to handle complex numbers. Operator overloading to the rescue!

Every C++ language specific feature (e.g.: multiple inheritance) should have alternatives to be implemented in Java. If it doesn't, that means the design pattern or code architecture is problematic.

But Java DOES have multiple inheritance! It's called "interface". Java implementation is a problematic workaround to avoid the dreaded diamond caused by having everything derive from Object. It's done by introducing interface which sole purpose is to be something that does not derive from Object. C++ never had this problem - there is no mandatory common base so every class can function as an interface without the dreaded diamond.

Side note: Java recently introduced ... concrete methods in interfaces. Added a feature C++ always had to solve a problem that was never there.

You've also only mentioned very few "things that C++ has but Java does not". One of the biggest differences between C++ and Java is the control over memory layout. You can create array of pointers to objects (just like in Java) OR you can create contiguous memory block. Now, if I was to worry about a C++ feature that may mislead Java devs, something as hidden and subtle as this one would rank on my list much higher than obvious and recognizable on first sight things like multiple inheritance or overloaded operators.

Bottom line: Clean code is clean code. Java or C++ - same difference. Just keep it simple. Unnecessary complications are the leading cause of bad code.


答:
In a project of any size/complexity, I want to be able to find code when I need it for the following purposes:

Fix it when it's broke

Change the functionality

Reuse it.

Wouldn't it be lovely, to either join a project in progress or continue to work on  a project for several years and when a new request to "connect to internet and show connection results" was in some easy to find location due to having a good design instead of relying on doing a search throughout the code for an httprequest? It's probably easier to find with Google anyway.

Don't worry, I'm the new guy and I'll refactor this block of code because I'm so upset for joining this clueless team with the awful code base or I'm now under a lot of pressure like the rest of you and will just copy and paste it. At least it will keep the boss off my back. Then when the project is truly identified as a disaster, I'll be the first to recommend we rewrite it by copying and pasting the version in the latest and greatest framework that none of us understand.


答: You cannot violate the Single Responsibility Principle because it is just an esthetic criterion, not a rule of Nature. Don't be misled by the scientifically sounding name and the uppercase letters.

Title: Does this class design violate the single responsibility principle?

Body:
Today I had an argument with someone.

I was explaining the benefits of having a rich domain model as opposed to an anemic domain model. And I demoed my point with a simple class looking like that:

```<code>public class Employee
{
    public Employee(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastname;
    }

    public string FirstName { get private set; }
    public string LastName { get; private set;}
    public int CountPaidDaysOffGranted { get; private set;}

    public void AddPaidDaysOffGranted(int numberOfdays)
    {
        // Do stuff
    }
}
</code>```

As he defended his anemic model approach, one of his arguments was: "I am a believer in SOLID. You are violating the single responsibility principle (SRP) as you are both representing data and performing logic in the same class."

I found this claim really surprising, as following this reasoning, any class having one property and one method violates the SRP, and therefore OOP in general is not SOLID, and functional programming is the only way to heaven.

I decided not to reply to his many arguments, but I am curious what the community thinks on this question.

If I had replied, I would have started by pointing to the paradox mentioned above, and then indicate that the SRP is highly dependent on the level of granularity you want to consider and that if you take it far enough, any class containing more than one property or one method violates it.

What would you have said?

Update: The example has been generously updated by guntbert to make the method more realistic and help us focus on the underlying discussion.


答:
If you're going to write code in language X, spend the time to properly learn the language and use all the features it offers to help you solve the problem.  Bad things happen when you try to do a "word for word" translation from one language to another, whether that's Japanese to English or Java to C++.  It's far better to start with a good understanding of the problem and express the solution in the way that is the most natural for the language being used.

Years ago I saw a C program that had no indentation and every statement started in column 7, because the author of the code was a Fortran programmer that happened to be using C.  Other Fortran programmers were nervous about these newfangled things called pointers.  I didn't have the heart to mention pointers to pointers, I think they would have fainted on the spot.

Imagine hiring somebody to maintain this code in the future.  If it's good C++ code, you'll be able to hire a competent C++ developer and they should be able to find their way around.  If it's "Java in C++", then neither C++ nor Java developers will have an easy time understanding the code.


答:
Duplication is OK in some circumstances. But not in this one. That method is too complex. There is a lower limit, when duplication is easier than "factoring out" a method.

For example:

```<code>def add(a, b)
    return a + b
end
</code>```

is stupid, just do a + b.

But when you get just a little, tiny bit more complex, then you're usually way over the line.

```<code>foo.a + foo.b
</code>```

should become

```<code>foo.total
def foo
    ...
    def total
        return self.a + self.b
    end
end
</code>```

In your case, I see four "methods". Probably in different classes. One to make the request, one to get the response, one to display errors, and some kind of call back to be called after the response returns to process the response. I personally would likely add a "wrapper" of sorts on top of that as well to make the calls easier.

In the end, to make a web request I would want a call to look something like:

```<code>Web.Post(URI, Params, ResponseHandler);
</code>```

That line is what I would have all over my code. Then when I needed to make changes to "how I get stuff" I could quickly do so, with much less effort.

This also keeps the code DRY and helps with SRP.

Body:
Duplication is OK in some circumstances. But not in this one. That method is too complex. There is a lower limit, when duplication is easier than "factoring out" a method.

For example:

def add(a, b)
    return a + b
end

is stupid, just do a + b.

But when you get just a little, tiny bit more complex, then you're usually way over the line.

foo.a + foo.b

should become

foo.total
def foo
    ...
    def total
        return self.a + self.b
    end
end

In your case, I see four "methods". Probably in different classes. One to make the request, one to get the response, one to display errors, and some kind of call back to be called after the response returns to process the response. I personally would likely add a "wrapper" of sorts on top of that as well to make the calls easier.

In the end, to make a web request I would want a call to look something like:

Web.Post(URI, Params, ResponseHandler);

That line is what I would have all over my code. Then when I needed to make changes to "how I get stuff" I could quickly do so, with much less effort.

This also keeps the code DRY and helps with SRP.


答:
Dynamically typed or not, it's best to consult documentation and/or examples.

Even if you know what type a parameter is, it's often quicker and safer to base your code off of an example, with more detailed documentation on hand, than it is to assume you know what you're doing based on the parameter type.

Otherwise, you're just making assumptions and experimenting anyway. And if that's your preference -- well, good luck, first of all. But, if you really want to work off of assumptions (or perhaps are working with an undocumented, minified, black box library), you may as well start with the fewest assumptions possible: Give it a null and see what error(s) you get back.


答:
Neither of these terms is appropriate for a bug in an arcade game that was programmed in assembly language and runs without benefit of memory-protection hardware or operating system.

"Undefined behaviour" is a term-of-art in C and related languages, coined by the C standards committee back in 1989.  Code has undefined behavior when the language specification doesn't define what it will do.  There is no such thing in Z80 assembly language: the effect of every opcode with every possible input is well-defined.  The conventional English meaning of "undefined behavior" can be read to apply -- the kill screen is behavior not defined by the people who wrote the game -- but I wouldn't use it in this context because it's too likely to give the wrong impression.

"Segmentation fault" is a term-of-art in POSIX, derived ultimately from PDP system programming jargon.  Segmentation faults happen when a program attempts to access a memory address that isn't "mapped" to anything: the hardware and operating system detect this and shut down the malfunctioning program, in a carefully-defined way that allows the program a chance to recover.  Something like this could have happened as a result of a bug in the Pac-Man game program, because the Pac-Man circuit board only populates a little less than half of the Z80's 64kB address space with ROM, RAM, and peripherals, but I haven't been able to find out what the real hardware would do if the software attempted to access unmapped memory.  Whatever it would do, though, it would be inappropriate to describe as a "segmentation fault", because the "operating system" for Pac-Man (to the extent it even has one) is not an implementation of Unix and, again, it would give the wrong impression.

The level 256 bug, meanwhile, does not access unmapped memory, so it's moot.

It is accurate to say that the game has a bug which manifests upon advancing to level 256.  It is also accurate to say that the root cause of the bug is an integer overflow, and that its consequences are memory corruption (or, equivalently, violations of memory and type safety).  These are all general-purpose CS terms defined without reference to any particular language or OS environment.

It's also accurate to observe that the effects of the bug are similar to the effects, within a modern environment, of memory-corruption bugs that don't provoke segmentation faults.  If you read any of the Project Zero exploit writeups, you will see a remarkable similarity to Don Hodges' analysis of the Pac-Man kill screen.

Note that an emulator that doesn't faithfully reproduce the kill screen when fed the Pac-Man ROMs is not emulating the game hardware correctly.


答:
The current answers all say this is a bad thing to do, as you should take advantage of the language you are using and also explain why a C++ feature is not “bad” just because it is not in jave.   I will answer this from a different angle.

It is one thing to avoid complex C++ feature like multiple inheritance, operator overloading and defining your own template.

But any problem that does more than the  most simple task:

allocates memory,

connects that money together with points

so build data structures

then allows the memory to be reused when safe to do so

There is not a common subset of Java and C++ that allows the above, therefore what you are asking is impossible to do.
(If you were asking about  Java and C# you would have a lot better chance, as they both use garbage collectors.)

However you could require that the code be written so that a Java developer could understand what is does (but not the detailed "how") and this would be sensible.

You could also design your own language that you implemented in both C++ and JAVA.....


问:
How to use a strong type system to model business constraints?
Following up on my ambiguous question, here's a question that is probably more focused.

Consider the following code snippet form a Haskell program:

```<code>data NightWatchCommand = InvalidCommand | DownloadCommand { url :: String } | PauseCommand { gid :: String } | UnpauseCommand { gid :: String } | StatusCommand { gid :: String } deriving (Show, Eq)
data AuthNightwatchCommand = AuthNightwatchCommand {
  command :: NightWatchCommand,
  user :: User
}
</code>```

Now, the business constraint I want to enforce via the type-system is this: it should not be possible to instantiate an unauthenticated NightwatchCommand. And the only way to instantiate an AuthNightwatchCommand should be via a special function, say:

```<code>fromIncomingMsg :: String -> AuthNightwatchCommand
</code>```

Just to provide greater context, the string argument to this function could possibly be:

```<code>status <some-id> <auth-token>
</code>```

Now, to complicate matters further, fromIncomingMsg needs to validate the <auth-token> from the DB. Which means, it will do IO. A more appropriate function signature would be:

```<code>fromIncomingMsg :: String -> IO (AuthNightwatchCommand)
</code>```

Apart from shoving this into a module and hiding the data constructors, is there any other way to do this?

答:
How about something like this (testing this code is an exercise for the reader):

```<code>{-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving #-}

class Authorized a where
    fromIncomingMsg :: String -> IO (AuthNightwatchCommand)

instance Authroized AuthNightwatchCommand where
    fromIncomeMsg = error "Todo"

newtype Auth = Auth {unAuth :: forall a. Authorized a => a deriving (Authorized)}

--Please only use Auth
</code>```

unAuth can convert from Auth to AuthNightwatchCommand (and is safe for others to use).

Body:
How about something like this (testing this code is an exercise for the reader):

{-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving #-}

class Authorized a where
    fromIncomingMsg :: String -> IO (AuthNightwatchCommand)

instance Authroized AuthNightwatchCommand where
    fromIncomeMsg = error "Todo"

newtype Auth = Auth {unAuth :: forall a. Authorized a => a deriving (Authorized)}

--Please only use Auth

unAuth can convert from Auth to AuthNightwatchCommand (and is safe for others to use).


答:
To decide whether a code should be duplicated or moved to a function which is called twice, try to determine which is more probable:

It will be necessary to change both uses of the code in the same way.

It will be necessary to change at least one use of the code so that they differ.

In the first case, it will likely be better to have one function handle both usages; in the latter case, it will be likely be better to have separate code for the two usages.

In deciding whether a piece of code which will be used once should be written in-line or pulled out into another function, figure out how one would fully describe the function's required behavior.  If a complete and accurate description of the function's required behavior would be as long or longer than the code itself, moving the code into a separate function may make things harder to understand rather than easier.  It may still be worth doing if there's a high likelihood that a second caller will need to use the same function, and any future changes to the function will need to affect both callers, but in the absence of such consideration, readability would favor splitting things to the level where the code and a description of its required behavior would be about equally long.


答:
Now, the business constraint I want to enforce via the type-system is this: it should not be possible to instantiate an unauthenticated NightwatchCommand.

Now, maybe I'm missing some piece of context here, but this has me very puzzled for the following reason: why would a "business constraint" care about what NightWatchCommands get instantiated or not?  It sounds to me like the constraint should be something more like this:

It should be impossible for an unauthenticated user to execute a night watch command.

And to my mind this suggests an organization like the following:

```<code>module NightWatch (NightWatchCommand, execute) where

import Something.Auth

data NightWatchCommand = ...
data Result = ...

execute
  :: Auth
  -> NightWatchCommand
  -> IO (Either InsufficientPermissions Result)
execute auth cmd = do
  allowed <- checkAuth auth cmd
  if allowed
  then fmap Right (reallyExecute cmd)
  else Left (InsufficientPermissions $ "insufficient auth: " ++ (cmd, auth))

reallyExecute :: NightWatchCommand -> IO Result
reallyExecute cmd = ...
</code>```

Basically, what I'm arguing here is that security is not part of the NightWatchCommand's set of concerns—the core concerns for that type are just what the commands are.  Security is a concern for the interpreter that executes the commands.  If the only interpreter you provide demands and checks authentication, and you disallow other modules from writing their own interpreters (by not exporting the constructors for the NightWatchCommand type), then all callers have to go through your interpreter.

Title: How to use a strong type system to model business constraints?

Body:
Following up on my ambiguous question, here's a question that is probably more focused.

Consider the following code snippet form a Haskell program:

```<code>data NightWatchCommand = InvalidCommand | DownloadCommand { url :: String } | PauseCommand { gid :: String } | UnpauseCommand { gid :: String } | StatusCommand { gid :: String } deriving (Show, Eq)
data AuthNightwatchCommand = AuthNightwatchCommand {
  command :: NightWatchCommand,
  user :: User
}
</code>```

Now, the business constraint I want to enforce via the type-system is this: it should not be possible to instantiate an unauthenticated NightwatchCommand. And the only way to instantiate an AuthNightwatchCommand should be via a special function, say:

```<code>fromIncomingMsg :: String -> AuthNightwatchCommand
</code>```

Just to provide greater context, the string argument to this function could possibly be:

```<code>status <some-id> <auth-token>
</code>```

Now, to complicate matters further, fromIncomingMsg needs to validate the <auth-token> from the DB. Which means, it will do IO. A more appropriate function signature would be:

```<code>fromIncomingMsg :: String -> IO (AuthNightwatchCommand)
</code>```

Apart from shoving this into a module and hiding the data constructors, is there any other way to do this?

Body:
Now, the business constraint I want to enforce via the type-system is this: it should not be possible to instantiate an unauthenticated NightwatchCommand.

Now, maybe I'm missing some piece of context here, but this has me very puzzled for the following reason: why would a "business constraint" care about what NightWatchCommands get instantiated or not?  It sounds to me like the constraint should be something more like this:

It should be impossible for an unauthenticated user to execute a night watch command.

And to my mind this suggests an organization like the following:

module NightWatch (NightWatchCommand, execute) where

import Something.Auth

data NightWatchCommand = ...
data Result = ...

execute
  :: Auth
  -> NightWatchCommand
  -> IO (Either InsufficientPermissions Result)
execute auth cmd = do
  allowed <- checkAuth auth cmd
  if allowed
  then fmap Right (reallyExecute cmd)
  else Left (InsufficientPermissions $ "insufficient auth: " ++ (cmd, auth))

reallyExecute :: NightWatchCommand -> IO Result
reallyExecute cmd = ...

Basically, what I'm arguing here is that security is not part of the NightWatchCommand's set of concerns—the core concerns for that type are just what the commands are.  Security is a concern for the interpreter that executes the commands.  If the only interpreter you provide demands and checks authentication, and you disallow other modules from writing their own interpreters (by not exporting the constructors for the NightWatchCommand type), then all callers have to go through your interpreter.


答:
The level-256 bug in Pac Man results in the program reading data which is beyond the end of the intended table, but is still readable storage, and writing to portions of the screen which are beyond those which the program intends to write, but are still well within the areas of the screen that the program is allowed to write.  No other areas of memory are affected.

The reason that the bug renders the game unplayable is that the machine determines when a player is eating dots by examining what's on the screen, and decides that a level is complete when the player has eaten 244 dots.  By overwriting part of the screen, the bug makes it impossible for the player to eat 244 dots; consequently, the game will never credit the player with completing the level and reload the screen with dots.


问:
What is the difference between Callable<T> and Java 8's Supplier<T>?
I've been switching over to Java from C# after some recommendations from some over at CodeReview. So, when I was looking into LWJGL, one thing I remembered was that every call to Display must be executed on the same thread that the Display.create() method was invoked on. Remembering this, I whipped up a class that looks a bit like this.

```<code>public class LwjglDisplayWindow implements DisplayWindow {
    private final static int TargetFramesPerSecond = 60;
    private final Scheduler _scheduler;

    public LwjglDisplayWindow(Scheduler displayScheduler, DisplayMode displayMode) throws LWJGLException {
        _scheduler = displayScheduler;
        Display.setDisplayMode(displayMode);
        Display.create();
    }

    public void dispose() {
        Display.destroy();
    }

    @Override
    public int getTargetFramesPerSecond() { return TargetFramesPerSecond; }

    @Override
    public Future<Boolean> isClosed() {
        return _scheduler.schedule(() -> Display.isCloseRequested());
    }
}
</code>```

While writing this class you'll notice that I created a method called isClosed() that returns a Future<Boolean>. This dispatches a function to my Scheduler interface (which is nothing more than a wrapper around an ScheduledExecutorService. While writing the schedule method on the Scheduler I noticed that I could either use a Supplier<T> argument or a Callable<T> argument to represent the function that is passed in. ScheduledExecutorService didn't contain an override for Supplier<T> but I noticed that the lambda expression () -> Display.isCloseRequested() is actually type compatible with both Callable<bool> and Supplier<bool>.

My question is, is there a difference between those two, semantically or otherwise - and if so, what is it, so I can adhere to it?

答:
As you note, in practice they do the same thing (provide some sort of value), however in principle they are intended to do different things:

A Callable is "A task that returns a result, while a Supplier is "a supplier of results". In other words a Callable is a way to reference a yet-unrun unit of work, while a Supplier is a way to reference a yet-unknown value.

It's possible that a Callable could do very little work and simply return a value. It's also possible a Supplier could do quite a lot of work (e.g. construct a large data structure). But generally speaking what you care about with either is their principle purpose. For example an ExecutorService works with Callables, because it's primary purpose is to execute units of work. A lazy-loaded data store would use a Supplier, because it cares about being supplied a value, without much concern about how much work that might take.

Another way of phrasing the distinction is that a Callable may have side-effects (e.g. writing to a file), while a Supplier should generally be side-effect free. The documentation doesn't explicitly mention this (since it's not a requirement), but I'd suggest thinking in those terms. If the work is idempotent use a Supplier, if not use a Callable.


问:
What does "packaging" refer to in the software Deployment process?
From what I understand the deployment process consists of these steps.

Compiling, linking/packaging, deploying.

What does the packaging refer to? is that just a reference to packaging the object files together?

答:
Yes.  For example with a nodejs application a developer will download the various dependencies and build them from source (the one command npm install will do that for all dependencies, as long as none are too weird).  However when deploying to the wild the developer will probably bundle up all the files he has downloaded into a tarball or something fancier.  That way the end user doesn't gets all the files and doesn't have to have git installed.

Node is a scripting language but the concepts are pretty much the same everywhere, as far as I have seen.


答:
Packaging means packaging.

Software development in a nutshell:

First, you plan your project. What does it need to do? How will it do it? Who will make it? And when?

Then you design the system. Lots of diagrams. And documentation!

Then you implement it. It's coding time, batman.

Now you can build it. In some languages/paradigms, that means compiling and linking. In others, this actually may be an empty step. For example, you may wish to deploy a Python script as-is.

Next, you take the distributables/executables/documentation/resources out of your build directory/staging area, and put them into whatever entity you're going to actually send to your users. Be that an archive file, or a self-extracting installer, or a CD image (ISO), or a Red Hat RPM, or a Debian package file, or a physical DVD, or a strand of specially-sequenced DNA spliced onto the genome of an unfortunate carrier pigeon, or… whatever. This is packaging. Again, this may be an empty step, if you only have a single executable, and you just need to get it to someone as-is.

Your packaged product is then deployed, either by digitally transmitting it, or by sending it in the post on floppy disks, or by sending it on a USB stick with your own engineer to perform a free on-site installation, or…

Title: What does "packaging" refer to in the software Deployment process?

Body:
From what I understand the deployment process consists of these steps.

Compiling, linking/packaging, deploying.

What does the packaging refer to? is that just a reference to packaging the object files together?


问:
Postgres roles for website users
I am setting up a PostgreSQL database with a very small number of tables for a simple website.  I am looking at ways to make it as solid and auditable as possible.  Is there any particular reason why I should or should not create a PostgreSQL role for each user account on the website?  The idea is that I could then use row level permissions on tables containing personal or private information and queries would look something like like this:

-- Service logs in with role mywebsite and runs:
BEGIN
SET LOCAL ROLE charlie; -- A user on the website
INSERT ...              -- DO STUFF
COMMIT;
```

Logging code would then know both the system account (mywebsite in the above example) used to log in to the database and also the user on whose behalf changes are being made (charlie).  The two are available in PostgreSQL as session_user (uid) and current_user (euid).

If you know of any precedents or any reasons why this would be a great or terrible idea I'd love to know.

答:
Roles are generally used to group users together. For example, we have several moderators on Programmers. Rather than creating a role for each user, we likely have one "moderator" role assigned to multiple users. This makes it easy to see who belongs to what group and to modify permissions for multiple users at once.

It sounds like you have a classic case of "my web site has multiple users, but the web site only uses one user account to log in to the database" common to most public web applications.

Using roles to identify web site users is not what that feature is designed to do, and may hamstring you in the future if you need roles for another purpose. It also duplicates functionality: if you can create roles, why not just create additional users?

I think one approach here would be to nix the roles-based approach and just modify the data directly. Rather than using built-in logging, maybe create a separate logging table where you can log the event. It might contain fields for the following:

PostgreSQL user

Application user

Table modified

Field modified

Notes (free-form text, whatever is relevant)

I would not advocate using this log for every modification, only the important ones that require an audit trail.

Another option I have seen is to include record state information on each table where you need accountability. It does not maintain a history, but may be good enough if you just need the most recent edit. Several open-source frameworks do this. You could add the following fields to important tables:

PostgreSQL user

Application user

Date modified

Title: Postgres roles for website users