问:
Naming choice in Java -- clone vs. copy
We have "copy constructor" but "clone method". This asymmetry in naming puzzles me -- does anyone know for what reason the method was not named "copy" (and interface per analogy "Copyable")?

This question is about historical process of Java language design, and the choice that was made, not current opinion which one is "better".

答:
As @Kilian Foth already pointed out in his comment, the term copy constructor is primarily if not exclusively used in C++. C++ had little to no impact on the design of Java, except in a "how not to do it" way.

The primary influence on Java is Objective-C, where this method is also called clone. Objective-C inherited this terminology from Smalltalk, where the method is again called clone. Objective-C is contemporary to C++, Smalltalk predates it. So, the question should rather be: why did C++ introduce this asymmetry in the first place?

Title: Naming choice in Java -- clone vs. copy


问:
Designing classes that depend on each other
How would one go about designing classes for a system in which two components depend on each other?

For a more concrete example, consider this scenario, you're designing a piece of software to manage students, teachers and classes in an educational facility. For convenience purposes, you'd like your Class object to be able to query for the Students that are enrolled within its instance. At the same time, you'd like to know what Classes a Student is enrolled in.

A simple design may have include a container that holds instances of type Class in the Student object, and a container that holds instances of Student in the Class object. It does the job but it introduces a cyclic dependency between both classes. Usually, this is looked down upon [citation needed], but it sounds like a valid design where this could be beneficial.
Is there a reason why it would be a bad idea to do so? And how could this situation be rectified without introducing significant performance overhead?

答:
Looking at the relationsship between classes and students it is not as simple as classes have a list of the students participating and students have a list of classes they are participating in.

You might have to model students that are no longer participating in a class, classes that have been cancelled, students on waiting lists etc.

The best solution would be a collection of enrollments. Each enrollment might be 'active', 'dropped out', 'class cancelled', 'waiting list' etc. You can add new enrollment types without ever changing the classes or student classes.

The enrollment collection then have methods to get a collection of either classes or students.

This could be something like enroll.Active(chem101) to get the active students for chemistry 101 or enroll.DroppedOut(bent) to get all the classes Bent has dropped out of due to spending too much time on stackexchange.

ContentLicense: CC BY-SA 3.0


问:
Why is it inappropriate to use UML diagrams to plan how your code will be organized?

So, yes, diagrams can be inappropriate at times. When are they inappropriate? When you create them
  without code to validate them, and then intend to follow them. There is nothing wrong with drawing a diagram to
  explore an idea.

Agile Software Development: Principles, Patterns, and Practices - Robert C. Martin

What exactly does he mean by this? Isn't UML designed to help plan out how to structure your code before "diving in"? What's the point of using it if you don't follow the diagrams you came up with?

Context: In this chapter, Uncle Bob makes a UML diagram for the Score Keeper of a Bowling game. Then he goes on to develop the program in a test driven manner, without consulting the UML diagram. The resulting program is nothing like the UML diagram, and Uncle Bob comes to the conclusion quoted above.

答:
To properly explain this, we need a short history lesson. In the early days of software engineering, an often used analogy was building a house. An architect and structural engineer discuss plans with a customer and come up with a design. Builders then follow that design to build the actual house. Writing code was seen as the equivalent to building the actual house. Thus, there was a perceived need for up front design before that build could take place. Various graphical design tools were created, with UML being one of them.

The idea originally with UML, was that one would fully design a system with UML, then hand it over to coders to translate that design into code. In reality, this just doesn't work, and led to years of programmers being seen as "implementers", rather than "designers", projects being late, the designs having to constantly change after they were supposed to be complete etc.

The reason is simple. Coding is design. With the house analogy, the code is the architect's drawings. The compiler is the builder who takes those designs and builds a program from them. This realisation then led to agile techniques, TDD etc being born: tools to help improve the quality of that code design.

Just as an architect might produce preliminary sketches to help her and her team visualise the overall design, so a developer might use UML, or other tools, to help visualise the design needed. Just as those sketches aren't blindly followed, so the UML should not be blindly followed. The code design should evolve out of agile iterations and using TDD. LIkewise, just as an architect might build a model of the house to help her and her team visualise the drawings, so UML can be used to help visualise the code structure.

As Uncle Bob says, you can't validate the UML, you can only validate the code. Therefore the code is the prime design documentation and UML, if used, is secondary documenation only.


答:
The primary reason why that might be bad idea, is to keep the two-way-relationship in sync. When you add class to a student, you also have to add student to a class. Another, minor, problem is that persistence of relationship will be only one side. So you would have to convert it if it was opposite in the model.

There are two steps to resolve this issue. First is to make the collections on Student and Class read-only. This is generally simple. Then, introduce a 3rd concept. It can be as simple as EnrollmentService, that allows to pair Students to Classes, and internally ensures the relationship is properly maintained. Or it can be it's own entity like Bent suggests.

Title: Designing classes that depend on each other

Body:
How would one go about designing classes for a system in which two components depend on each other?

For a more concrete example, consider this scenario, you're designing a piece of software to manage students, teachers and classes in an educational facility. For convenience purposes, you'd like your Class object to be able to query for the Students that are enrolled within its instance. At the same time, you'd like to know what Classes a Student is enrolled in.

A simple design may have include a container that holds instances of type Class in the Student object, and a container that holds instances of Student in the Class object. It does the job but it introduces a cyclic dependency between both classes. Usually, this is looked down upon [citation needed], but it sounds like a valid design where this could be beneficial.
Is there a reason why it would be a bad idea to do so? And how could this situation be rectified without introducing significant performance overhead?


问:
Is 4-5 years the “Midlife Crisis” for a programming career?
I’ve been programming C# professionally for a bit over 4 years now. For the past 4 years I’ve worked for a few small/medium companies ranging from “web/ads agencies”, small industry specific software shops to a small startup. I've been mainly doing "business apps" that involves using high-level programming languages (garbage collected) and my overall experience was that all of the works I’ve done could have been more professional. A lot of the things were done incorrectly (in a rush) mainly due to cost factor that people always wanted something “now” and with the smallest amount of spendable money. I kept on thinking maybe if I could work for a bigger companies or a company that’s better suited for programmers, or somewhere that's got the money and time to really build something longer term and more maintainable I may have enjoyed more in my career. I’ve never had a “mentor” that guided me through my 4 years career. I am pretty much blog / google / self taught programmer other than my bachelor IT degree.

I’ve also observed another issue that most so called “senior” programmer in “my working environment” are really not that senior skill wise. They are “senior” only because they’ve been a long time programmer, but the code they write or the decisions they make are absolutely rubbish! They don't want to learn, they don't want to be better they just want to get paid and do what they've told to do which make sense and most of us are like that. Maybe that’s why they are where they are now. But I don’t want to become like them I want to be better. I’ve run into a mental state that I no longer intend to be a programmer for my future career. I started to think maybe there are better things out there to work on. The more blogs I read, the more “best practices” I’ve tried the more I feel I am drifting away from “my reality”. But I am not a great programmer otherwise I don't think I am where I am now. I think 4-5 years is a stage that can be a step forward career wise or a step out of where you are.

I just wanted to hear what other have to say about what I’ve mentioned above and whether you’ve experienced similar situation in your past programming career and how you dealt with it. Thanks.

答:
I am in the same situation as a four year Java programmer in a big company. I can confirm that I too am facing the issues you mentioned.

My solution is to earn a PHD in computer science in order to find new challenges.

OwnerDisplayName: Jeff

ContentLicense: CC BY-SA 2.5

OwnerDisplayName: Manuel Selva


问:
Single Responsibility Principle : Proxy Pattern for refactoring

However, in cases where the tests did not force the separation, and the smells of Rigidity and Fragility become strong, the design should be refactored using
the Facade or Proxy patterns to separate the two responsibilities.

From : Agile Software Development: Principles, Patterns, and Practices

I understand how Facade can be used. I am not able to get how proxy would be helpful.

Can someone provide and example of how Proxy Pattern can be used for refactoring here. Thanks!

答:
Given the example where you want to unit test some code that does CORBA or other remote call.

During the test phase you don't have the proper environment online. Refactoring this concern and creating a proper testable code can be achieved with a Proxy pattern, where your concrete proxy implementation would delegate the calls to another concrete class. That enables the separation of concerns quoted on your question.

Then during a integration test you can actually test the remote behaviour.


问:
How viable is it to have a single webapp over several private small repositories?
We are a low budget team working on a web app. Due some complications we might need to work remotely from January and onward. After some consulting and googling, we concluded that several small repositories is the cheaper option.   We're thinking in:

Backend and services

Middleware

Front End

This way we can separate in relevant teams, each one working remotely in their repository. How viable is it to have our app in several private small repositories?

Additionally what considerations should we take if we were to work this way?

Note: I'm asking about a single, big project divided over several small repositories. This differs from the  related questions asked on this site, because they are asking for multiple projects in either one or several repositories.  Additionally, we chose to dived the project, mostly because we aren't willing to invest a single big private repository unless we are going to stick with it.

答:
In my eyes splitting the repository is highly dependent on your goals and the tools you're using.

For example, if you're writing a Ruby on Rails web app without any public (or private) API that your frontend is going to consume (by AJAX for example), then I actually don't see how you could split the repository without causing a massive headache for your team. The Rails framework really works best with a monolithic-type architecture in that case.

However, if you plan on writing an API in Rails or Node.js, but want your frontend written in Ember.js or something else, then it would make sense to split the repository. The same applies if your web app data will be shared in the future by other clients (like via an Android/iOS app). If you plan on writing an API to be consumed by multiple clients, split your repo. Some would argue that even splitting the API into a different application entirely is a bad idea, one that I wholeheartedly disagree with (and it seems so for good reason!

Splitting the repository if you already planned on breaking apart the web app as I described is the only logical option. However, keep in mind that because it will be harder for people to browse each other's code, you need to ensure that you have excellent communication, but even more importantly documentation. Without documenting the API, for example, your other two teams are going to be pissed off very quickly because the API team didn't document the architecture, and your API team will get pissed off because everybody keeps asking them questions. This is even more true for remote teams.

So, it all depends on how you wanted to structure the app in the first place. If you're building a monolithic web app (and you know or sure that it will just remain a web app), then have one repository. If you planned on creating things like microservices or a REST API consumed by multiple clients (or you are planning this for the future), split the repo.


问:
Merge bug fixes from trunk in old branches
We are now in the process of switching from svn to git (after a year spent on convincing people, yay!) in my company.

So far, this is all for the better but there is one little thing that we currently have in our workflow that I can't find a good equivalent too.

Currently, all our developers work in master. Once every quarter, we branch master into X.x branch, which will later on become our latest release. This means that our svn repo looks like this:

trunk

branches

3.8

4.1

4.2

...

We don't really use tags.

Once in a while, there is an urgent bug fix that is discovered.

The current way for us to do it is:

Fix it in master

SVN merge the relevant range of commits back into the relevant branches (Maybe our latest release, maybe more).

We are in the space industry, so our branches are long lived and the customer upgrade process is rather long, which is why we have worked like that so far.

Now, how would be a good equivalent in git?

So far, I have tried to fix the bug in a branch spawned from master, and then merge this branch back in master and in 4.3 (for example).
Thing is, the hotfix branch contains the master history, and all the commits between master and 4.3 get merged as well, which we don't  want to.

Things I could think of so far:

I have looked at the very successful Git Workflow method, and their solution is to fix the bug in the release branch and merge it back instead of the other way around. This could work in our case, but would be rather cumbersome because it would require us to already know the oldest branch we want to fix the bug in before actually fixing the bug.

Another solution is to fix in master, and then cherry pick the commits (as we do for the svn merge today). The annoying thing here is that in this case we lose history of what has been merged back where, since cherry picks look like new commits and we lose the relationship.

So what is the "good" way to do it? Should we fix commits in history, or cherry pick and manually keep track of what has been merged, or even something else?

If have little production experience with git, so I am sure I may have missed something.

答:
The Git Flow assumes you only have a single supported release, with the master branch always pointing to the latest release. Since you support multiple releases simultaneously, you cannot copy that workflow 1:1. Nvie's Git Flow is a very good example of a branching strategy, but you must adapt it to your needs. Most importantly, you will have multiple active release branches.

When you identify a bug, you will have to do some testing to determine all affected versions. It is not sufficient to write the fix first, then merge it back into the release branches as a hotfix. Usually, you'll end up with some continuous range of affected versions. Very old versions might not contain the bug, newer versions might have gotten that bug fixed accidentally. You will need to verify the bug on each version so that you can verify it is actually gone after the fix. If you can express the bug as an automated testcase, it's pretty straightforward to find the problematic commit via git bisect, or to run the test for each release:

for release in 3.8 4.1 4.2
do
  git checkout $release
  if ./testcase >release-$release.log
  then echo "$release ok"
  else echo "$release AFFECTED"
  fi
done
```

<p>Now, you used to write the fix on <code>trunk</code>/<code>master</code>. This is problematic because the buggy part may have changed between versions, so a patch will not usually apply to an older version. In particular, code in <code>master</code> might depend on any features available in master, which might not have been present in older versions. It therefore makes a lot of sense that a Git commit references its whole history, not just the change set. When merging back, it will pull in all the history it depends on.</p>

<p>Using <code>cherry-pick</code> or <code>rebase</code> ignores this history, and records a new commit with the same changeset, but a different history. As pointed out, this will not work if your codebase has diverged.</p>

<p>The “correct” solution is to write the fix as a hotfix on the oldest affected release. Then, you merge oldest release into the second-oldest release. Usually, a newer release would contain all commits of an older release, so this is OK. If things have changed, you now have a chance to manually resolve the merge conflict. Then you continue merging each release into the next-younger release until you are done. This maintains proper history and avoids a lot of unnecessary work, while only requiring effort that has to be expended anyway. In particular, this incremental merging gets you closer to the current development state in small steps.</p>

<p>As a diagram:</p>

```| o normal commit |
| x hotfix        |
| ⇘ merging       |

3.8 --o-----------------x
       \                 ⇘
4.1     o--o--o-----------x'
               \           ⇘
4.2             o--o--o-----x''
                       \     ⇘
develop                 o--o--x'''--o--o
```

Body:
The Git Flow assumes you only have a single supported release, with the master branch always pointing to the latest release. Since you support multiple releases simultaneously, you cannot copy that workflow 1:1. Nvie's Git Flow is a very good example of a branching strategy, but you must adapt it to your needs. Most importantly, you will have multiple active release branches.

When you identify a bug, you will have to do some testing to determine all affected versions. It is not sufficient to write the fix first, then merge it back into the release branches as a hotfix. Usually, you'll end up with some continuous range of affected versions. Very old versions might not contain the bug, newer versions might have gotten that bug fixed accidentally. You will need to verify the bug on each version so that you can verify it is actually gone after the fix. If you can express the bug as an automated testcase, it's pretty straightforward to find the problematic commit via git bisect, or to run the test for each release:

for release in 3.8 4.1 4.2
do
  git checkout $release
  if ./testcase >release-$release.log
  then echo "$release ok"
  else echo "$release AFFECTED"
  fi
done

Now, you used to write the fix on trunk/master. This is problematic because the buggy part may have changed between versions, so a patch will not usually apply to an older version. In particular, code in master might depend on any features available in master, which might not have been present in older versions. It therefore makes a lot of sense that a Git commit references its whole history, not just the change set. When merging back, it will pull in all the history it depends on.

Using cherry-pick or rebase ignores this history, and records a new commit with the same changeset, but a different history. As pointed out, this will not work if your codebase has diverged.

The “correct” solution is to write the fix as a hotfix on the oldest affected release. Then, you merge oldest release into the second-oldest release. Usually, a newer release would contain all commits of an older release, so this is OK. If things have changed, you now have a chance to manually resolve the merge conflict. Then you continue merging each release into the next-younger release until you are done. This maintains proper history and avoids a lot of unnecessary work, while only requiring effort that has to be expended anyway. In particular, this incremental merging gets you closer to the current development state in small steps.

As a diagram:

| o normal commit |
| x hotfix        |
| ⇘ merging       |

3.8 --o-----------------x
       \                 ⇘
4.1     o--o--o-----------x'
               \           ⇘
4.2             o--o--o-----x''
                       \     ⇘
develop                 o--o--x'''--o--o


问:
Best approach for realtime sync + shared todo?
I'm implementing an app that has among other things shared todo lists. I want it to sync in real time. This has to work for "normal" single user items (e.g. user has app opened in 2 devices, doing an update in one device shows immediately in the other device) as well as the shared lists, where all the participants have to receive the update in real time.

I'm not entirely sure which kind of structure is best in order to accomplish this. I was thinking about storing a dictionary of user uuid -> socket list. When users log in or open the app while being logged in, they'll initiate a connection. Here I add an entry or update to the dictionary. When they log out or close the app, the connection is closed and I update the map accordingly. Whenever the app does an update in the server, I look up the affected users, then look up in my dictionary for possible open websockets for these users, and send the updates to them.

Another idea I had, was to associate the connections rather than with the users, with items, like e.g. the todo lists. So again I have a dictionary, but this time the key is the todo list uuid and it has an array of connections ("observers") for this list, where I broadcast wherever the list is modified. This approach is not suitable for the "single user sync" though, here the elements don't necessarily have an own identity, rather associated with the user - so I'm back to the first approach with a dictionary user -> connections.

But before I dive into more details I'd like to confirm if this is the correct train of thought. How is this normally modelled? This is rather a theory question, but in case it's relevant for something, I'm using Play Framework 2.4 / Scala.

答: Ok I ended implementing publish / subscribe, using websockets. I implemented a set dictionaries for different categories (like todo lists or single-user events), where the keys are the subject (in my case uuid of list or users) and the values the list of subscribers. Concerning implementation details I did this using Play and Akka actors.</p>


问:
Why is UML not used in most free software (e.g. on Linux)?
I'm trying to understand why UML is not used in most free software projects. For example, my Debian/Linux system has probably more than ten thousand free software packages, and I cannot name even one which has been developed using explicit UML framework and methodology. For example, Qt, GCC, Linux kernel, bash, GNU make, Ocaml, Gnome, Unison, lighttpd, libonion, docker are free software projects which (AFAIK) don't mention UML at all.

(My guess is that UML is very well suited for formal subcontracting of development tasks, and that is not how free software is developed)

Notice that while I did read some material about UML, I don't claim to have a good understanding of it.

Actually, I cannot easily name a free software where UML has been used (except perhaps some UML tools implemented as free software). Perhaps openstack is an exception (something there mentions UML).

(even old free software projects might have adopted UML after they have been started, but they did not)

Some colleagues working on Papyrus mentioned that most free software projects did not have at their beginning any explicitly (and deep enough) formalized model. Also, UML looks much more related to Java than it claims (I am not entirely sure it would make sense for Ocaml or Common Lisp or Haskell or Javascript, and perhaps not even for C++11....). Perhaps agile software development is not very UML friendly.

See also this answer to a somehow related question. M.Fowler's blog Is Design Dead? is insightful.

PS. I don't think it is mainly a matter of opinion; there should be some objective reason, and some essential characteristic of free software, that explains why. I tend to guess that UML is only useful for formalized subcontracting, and is useful only when some part of the developed software is hidden, as in proprietary projects. If that is true, UML would be incompatible with free software development.

NB: I am not an UML fan myself. I don't define UML as paper documentation only, but also as a [meta-]data format for software tools

答:
There are different ways to use UML. Martin Fowler calls these UML modes and identifies four: UML as Notes, UML as Sketch, UML as Blueprint, and UML as a Programming Language.

UML as a Programming Language never really took off. There has been some work in this area under different names, like Model Driven Architecture or Model Based Software Engineering. In this approach, you create highly detailed models of your software system and generate the code from those models. There may be some use cases where this approach is useful, but not for general software and especially not outside of large companies that can afford the tools that power this approach. It's also a time-consuming process - I can type the code for a class faster than I can create all of the graphical models necessary to implement it.

UML as a Blueprint is often indicative of a "big design up front" project. It doesn't have to be, of course. The model can be fully described for a particular increment, as well. But the idea is that the time is spent creating a design in the form of UML models that are then handed off to someone to convert into code. All of the details are spelled out and the conversion to code tends to be more mechanical.

UML as Sketch and UML as Notes are similar in nature, but differ based on when they are used. Using UML as Sketch means that you will sketch out designs using UML notations, but the diagrams are likely to not be complete, but will focus on particular aspects of the design that you need to communicate with others. UML as Notes is similar, but the models are created after the code to aid in understanding the code base.

When you're considering this, I think everything above is true for any kind of modeling notation. You can apply it to entity-relationship diagrams, IDEF diagrams, business process modeling notation, and so on. Regardless of the modeling notation, you can choose when you apply it (before as a specification, after as an alternative representation) and how much detail (full detail to key aspects).

The other side of this is open source culture.

Often, open source projects start off to solve a problem that an individual (or, today, a company) is experiencing. If it's being launched by an individual, the number of developers is 1. In this case, the communication overhead is extremely low and there's little need to communicate about the requirements and design. In a company, there's likely to be a small team. In this instance, you'll likely need to communicate design possibilities and discuss trade-offs. However, once you have made your design decisions, you need to either maintain your models as your code base changes over time or throw them away. In Agile Modeling terms, "document continuously" and maintain a "single source of information".

As a brief aside, there is the idea that code is design and that models are just alternate views of the design. Jack Reeves wrote three essays on code as design, and there are discussions on C2 wiki as well, discussing the ideas that the source code is the design, the design is the source code, and source code and modeling. If you subscribe to this belief (which I do), then the source code is the reality and any diagrams should just exist to make understanding the code and, more importantly, the rationale behind why the code is what it is.

A successful open source project, like the ones that you mention, have contributors around the world. These contributors tend to be technically competent in the technologies that power the software and are likely also to be users of the software. Contributors are people who can read source code just as easily as models, and can use tools (IDEs and reverse engineering tools) to understand the code (including generating models, if they feel the need). They can also create sketches of the flow on their own.

Of the four modes that Fowler describes, I don't think you'll find an open source project, or very many projects anywhere, that are using modeling languages as programming languages or blueprints. This leaves notes and sketch as possible uses for UML. Notes would be created by the contributor for the contributor, so you probably wouldn't find them uploaded anywhere. Sketches diminish in value as the code becomes more complete and likely wouldn't be maintained as that would just take effort on the part of contributors.

Many open source projects don't have models made available because it doesn't add value. However, that doesn't mean that models weren't created by someone early in the project or that individuals haven't created their own models of the system. It's just more time effective to maintain one source of design information: the source code.

If you want to find people exchanging design information, I'd recommend looking at any kind of forums or mailing lists that are used by contributors. Often, these forums and mailing lists serve as the design documentation for projects. You may not find formal UML, but you may find some kind of graphical representation of design information and models there. You can also pop into chat rooms or other communication channels for the project - if you see people talking about design decisions, they may be communicating with the graphical models. But they likely won't become part of a repository since they aren't valuable once they have served their purpose in communication.


问:
Time elapsed between two 8-bit timestamps
So I have a sets of numbers representing some timings.
This is how they look like:

```<code>[sec]   [msec]

 100    75
 100    200
 101    60
 101    233
 102    255
 104    21
</code>```

First column contains the elapsed seconds, and the second one the elapsed milliseconds. Values are represented using 8bit (so if the ms number is bigger than 255, the sec one gets incremented).

Now what I want to do, is to calculate the elapsed time (in milliseconds) between two inteframing values.

What I managed to do is this:

```<code>First interframe:   200 - 75                = 125ms.
Second interframe:  (1 * 255 + 60) - 200    = 115ms.
Third interframe:   233 - 60                = 173ms.
Forth interframe:   (1 * 255 + 255) - 233   = 277ms.
Fifth interframe:   (2 * 255 + 21) - 255    = 276ms.
</code>```

But this method is kinda hard to implement...

Is there any other method to find the elapsed time (in milliseconds) using another method?

答:
Assuming we are talking about 1/256ths of a second  (let's humorously call them bittiseconds), and not milliseconds, you could simply convert two values to their bittisecond representation, and then do a straight subtraction.</p>

```<code>int ToBittiseconds(byte seconds, byte bittiseconds)
{
    return seconds * 256 + bittiseconds;
}

byte v1Seconds = 100;
byte v1Bittis = 200;

byte v2Seconds = 101;
byte v2Bittis = 60;

int difference = ToBittiseconds(v2Seconds, v2Bittis) - ToBittiseconds(v1Seconds, v1Bittis);
</code>```

Body:
Assuming we are talking about 1/256ths of a second  (let's humorously call them bittiseconds), and not milliseconds, you could simply convert two values to their bittisecond representation, and then do a straight subtraction.

int ToBittiseconds(byte seconds, byte bittiseconds)
{
    return seconds * 256 + bittiseconds;
}

byte v1Seconds = 100;
byte v1Bittis = 200;

byte v2Seconds = 101;
byte v2Bittis = 60;

int difference = ToBittiseconds(v2Seconds, v2Bittis) - ToBittiseconds(v1Seconds, v1Bittis);


答:
Lets use Linux as example,

It's not an Object Oriented project, some parts, like the VFS can be modelled in UML, but others can't be or not very effective, i.e. basically just a straight translation from struct into a class diagram with no relationships.

UML is good for documentation, to get some one new to a project gets up to speed. That is not something that really catered for by Linux, people are expected to learn it themselves.

Not sure what UML tool to use, people need to agree on something if it was going to be maintained. There was a free java application for that, but I don't think many would want to use it.

In the 90's GUI was still a challenge on Linux. Just go dig the mailing list archive, I bet you won't find any kind of graphics other than the logo for Linux itself in xpm format to be shown in boot up time. Plain text is the preferred format.

I don't think no one really cared for design. People care about features and if they are accepted then the code will be scrutinised. Use cases are still best described in words, just like how standards like POSIX and SUS are written.

A lot of objects in the domain of operating systems are well understood and standardised within the community. E.g. people would know how a struct in_addr looks like in memory, no diagrams could make it clearer.

UML doesn't help much in modelling algorithm, like the memory allocator, scheduler, interrupt handlers, etc. The source is probably easier to understand.

Those are the things that I can think of in Linux project settings. It's more about practicality, I guess. Curiously, I don't remember Tanenbaum used any UML in his OS text book in describing Minix.

Probably worth mentioning, I also don't use UML at work. Probably 20% of people I work with know some subset of UML.

Title: Why is UML not used in most free software (e.g. on Linux)?

Body:
I'm trying to understand why UML is not used in most free software projects. For example, my Debian/Linux system has probably more than ten thousand free software packages, and I cannot name even one which has been developed using explicit UML framework and methodology. For example, Qt, GCC, Linux kernel, bash, GNU make, Ocaml, Gnome, Unison, lighttpd, libonion, docker are free software projects which (AFAIK) don't mention UML at all.

(My guess is that UML is very well suited for formal subcontracting of development tasks, and that is not how free software is developed)

Notice that while I did read some material about UML, I don't claim to have a good understanding of it.

Actually, I cannot easily name a free software where UML has been used (except perhaps some UML tools implemented as free software). Perhaps openstack is an exception (something there mentions UML).

(even old free software projects might have adopted UML after they have been started, but they did not)

Some colleagues working on Papyrus mentioned that most free software projects did not have at their beginning any explicitly (and deep enough) formalized model. Also, UML looks much more related to Java than it claims (I am not entirely sure it would make sense for Ocaml or Common Lisp or Haskell or Javascript, and perhaps not even for C++11....). Perhaps agile software development is not very UML friendly.

See also this answer to a somehow related question. M.Fowler's blog Is Design Dead? is insightful.

PS. I don't think it is mainly a matter of opinion; there should be some objective reason, and some essential characteristic of free software, that explains why. I tend to guess that UML is only useful for formalized subcontracting, and is useful only when some part of the developed software is hidden, as in proprietary projects. If that is true, UML would be incompatible with free software development.

NB: I am not an UML fan myself. I don't define UML as paper documentation only, but also as a [meta-]data format for software tools


问:
Choosing between Dependency Inversion and Dependency "Delegation" to a third module
Suppose I have MasterPackage containing a Master class, and BlasterPackage containing Blaster class. Since Master needs a Blaster to work, the higher level MasterPackage depends directly on lower-level BlasterPackage.

Using classic Dependency Inversion, one would add IBlaster (or AbstractBlaster) to MasterPackage, thus inverting dependency between the packages.

But while facing this problem, I realized I could create a third package - let's name it MasterBlasterInterfaces - and put IBlaster there. That would "delegate" the dependency to that third, common package, and the original two packages would be now decoupled from one another.

But then, if I have a higer-level package called ThunderDome, it will have to deal directly with BlasterPackage, wouldn't it? I feel like it sort of violates encapsulation, while with direct dependency Master could possibly abstract away the very existence of Blaster.

So the question is:

Is there a good set of criteria to choose between inversion vs. delegation of dependencies? And how one vs. other impacts use of the packages by higher-level application layers?

答:
Inverting the dependency as you have described it is only OK if you control the other package, and if this direct dependency is acceptable. For a lot of software, that is entirely OK. But most obviously, this doesn't work if your BlasterPackage is an external library you rely on.

The magic of introducing an IBlaster interface is that MasterPackage and BlasterPackage can work together without having a direct dependency relationship, and without being written by the same person/team/organization. Usually, this is not done by putting IBlaster into a separate package that both modules depend on. Instead, IBlaster would be part of MasterPackage, and you would introduce an adapter module. The dependencies can be illustrated like this:

The adapter depends on both packages, but the Master only depends on IBlaster. Such adapters get extremely useful when writing unit tests, and wanting to mock out the BlasterPackage. Of course, the MasterPackage will require some conforming adapter to be provided, but there is no concrete dependency on the BlasterAdapter. Even when you make all dependencies explicit and configurable, at some point the interface consumers and interface providers will have to be connected (dependency injection).


问:
What is the purpose of a wrapper class that does nothing but delegate to the object it wraps?
The specific example I have in mind is javax.servlet.ServletResponseWrapper:

public class ServletResponseWrapper implements ServletResponse {
    private ServletResponse response;

    /**
     * The default behavior of this method is to call setCharacterEncoding(String charset)
     * on the wrapped response object.
     *
     * @since 2.4
     */
    public void setCharacterEncoding(String charset) {
    this.response.setCharacterEncoding(charset);
    }

    /**
     * The default behavior of this method is to return getCharacterEncoding()
     * on the wrapped response object.
     */
    public String getCharacterEncoding() {
    return this.response.getCharacterEncoding();
    }

     /**
     * The default behavior of this method is to return getOutputStream()
     * on the wrapped response object.
     */

    public ServletOutputStream getOutputStream() throws IOException {
    return this.response.getOutputStream();
    }

   /** and so on **/
}
```

ServletResponseWrapper does nothing. It only passes execution to the nested object. So ServletResponseWrapper cannot function unless there is some other class (let's say ServletResponseConcrete) which also implements ServletResponse and does the real work.

In what context would you be able to use ServletResponseWrapper that you couldn't just use ServletResponseConcrete directly? This make absolutely no sense to me. I don't see how it's useful for subclassing either. If I subclass ServletResponseWrapper, then I have to implement every function anyways, so why not just create a class that implements ServletResponse directly?

答:
If I subclass ServletResponseWrapper, then I have to implement every function anyways, so why not just create a class that implements ServletResponse directly?

This is not true. The whole idea of the class is, that one could use it as a base class to inherit from and just has to overwrite the method(s) that need to be changed. If you use the interface directly, you would have to implement all of the methods.

In what context would you be able to use ServletResponseWrapper that you couldn't just use ServletResponseConcrete directly?

One could provide a method that accepts a parameter of type ServletResponse or ServletResponseWrapper without knowing that there is a implementation called ServletResponseConcrete. Or maybe ServletResponseConcrete doesn't even exists yet. Still, you could later on implement ServletResponseConcrete or MyOtherServletResponse and hand it to that method.

This pattern is called "Delegation". Here is a simple example of an implementation that adds a System.out when setLocale is called:

import javax.servlet.ServletResponse;
import javax.servlet.ServletResponseWrapper;
import java.util.Locale;

public class TimsServletResponse extends ServletResponseWrapper {

    public TimsServletResponse(ServletResponse response) {
        super(response);
    }

    @Override
    public void setLocale(Locale locale) {
        super.setLocale(locale);
        System.out.printf("setLocale was called (locale: %s)", locale);
    }
}
```

<p>Create a Filter to make your application server use your wrapper like this:</p>

<pre class="lang-java prettyprint-override"><code>import javax.servlet.*;
import java.io.IOException;

public class TimsFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) { }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        TimsServletResponse responseWrapper = new TimsServletResponse(response);
        chain.doFilter(request, responseWrapper);
    }

    @Override
    public void destroy() { }
}
</code>```

Body:
If I subclass ServletResponseWrapper, then I have to implement every function anyways, so why not just create a class that implements ServletResponse directly?

This is not true. The whole idea of the class is, that one could use it as a base class to inherit from and just has to overwrite the method(s) that need to be changed. If you use the interface directly, you would have to implement all of the methods.

In what context would you be able to use ServletResponseWrapper that you couldn't just use ServletResponseConcrete directly?

One could provide a method that accepts a parameter of type ServletResponse or ServletResponseWrapper without knowing that there is a implementation called ServletResponseConcrete. Or maybe ServletResponseConcrete doesn't even exists yet. Still, you could later on implement ServletResponseConcrete or MyOtherServletResponse and hand it to that method.

This pattern is called "Delegation". Here is a simple example of an implementation that adds a System.out when setLocale is called:

import javax.servlet.ServletResponse;
import javax.servlet.ServletResponseWrapper;
import java.util.Locale;

public class TimsServletResponse extends ServletResponseWrapper {

    public TimsServletResponse(ServletResponse response) {
        super(response);
    }

    @Override
    public void setLocale(Locale locale) {
        super.setLocale(locale);
        System.out.printf("setLocale was called (locale: %s)", locale);
    }
}

Create a Filter to make your application server use your wrapper like this:

import javax.servlet.*;
import java.io.IOException;

public class TimsFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) { }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        TimsServletResponse responseWrapper = new TimsServletResponse(response);
        chain.doFilter(request, responseWrapper);
    }

    @Override
    public void destroy() { }
}


答:
UML is a representation, so it's a form of language, and for argument's sake let's assume its purpose is to communicate a mental model from one person to another.

What I look for in a language is its efficiency in capturing changes to one's mental model.
Suppose after writing the description of one's model, a small change needs to be made.
How big a change must be made to the representation?
In a textual language, a way to measure that is to run a diff between the code before and after, and count the differences.
In a graphical language, there should be a similar way to measure the difference.

IMHO, I call a language "domain specific" (DSL) to the degree that it minimizes the measure above, which has obvious benefits in reducing maintenance cost and bugs.
How to make a DSL? There are several ways.
One of the simplest is to just define data structures and methods in an existing programming language.
This adds nouns and verbs to the base language, making it easier to say what one wants.
(Note: I do not look for a DSL to have no learning curve.
It may be that the reader of a DSL must invest the one-time cost of learning it.)

The important point is:
In all cases, the DSL has to contain the terms that make expressing one's model, and changes to the model, convenient.
Since there is no obvious limit to the range of possible domains,
no single DSL can serve all of them.

My impression of UML is that is what it tried to to.


答:
The example provided in the documentation is, strictly speaking, useless by design. If you follow the example you should have successfully implemented a wrapper class that has basically no meaningful effect on the system whatsoever. It should pass all proper tests, throw no weird errors, and cause no bizarre bugs.

However, if you follow the documentation you learn to create a proper wrapper class, and to hide the private implementation details that are unique to your systems. The example also shows a minimal default implementation of the ServletResponse interface, which would be handy if you needed a class that implemented this interface.

So why use something that doesn't do anything? Well, there is an implied Step 2 - make it do something useful that is specific to your system requirements. Maybe you only support certain character sets, or you always inject something into the ServletResponse, or you have some special write-behind handling when reset() is called.

As to why have both a wrapper and a concrete implementation, the wrapper basically does the minimum required to wrap the underlying object, and that's it.  You then use the wrapper to code to the interface, while the concrete implementation is full of the system-specific implementation details that makes real world development messy and challenging.

The wrapper should be boring - the concrete implementation is where things get interesting. Yet if you need to swap out the implementation - such as as to support different platforms, architectures, environments, or particular applications - all you do is hand in a different Concrete class, and your wrapper won't complain or burden other systems to know about your classes at all.
So long as they implement the right interface (which your wrapper does), they'll be happy.

This is very common in educational/documentation settings - the example given is the most minimal application of the concept, and it usually seems absolutely pointless. But once you know the use for something and the principles, then later the documentation serves as an excellent reference to implement the simplest thing possible that lets you start working on the tough bits.

Title: What is the purpose of a wrapper class that does nothing but delegate to the object it wraps?

Body:
The specific example I have in mind is javax.servlet.ServletResponseWrapper:

public class ServletResponseWrapper implements ServletResponse {
    private ServletResponse response;

    /**
     * The default behavior of this method is to call setCharacterEncoding(String charset)
     * on the wrapped response object.
     *
     * @since 2.4
     */
    public void setCharacterEncoding(String charset) {
    this.response.setCharacterEncoding(charset);
    }

    /**
     * The default behavior of this method is to return getCharacterEncoding()
     * on the wrapped response object.
     */
    public String getCharacterEncoding() {
    return this.response.getCharacterEncoding();
    }

     /**
     * The default behavior of this method is to return getOutputStream()
     * on the wrapped response object.
     */

    public ServletOutputStream getOutputStream() throws IOException {
    return this.response.getOutputStream();
    }

   /** and so on **/
}
```

ServletResponseWrapper does nothing. It only passes execution to the nested object. So ServletResponseWrapper cannot function unless there is some other class (let's say ServletResponseConcrete) which also implements ServletResponse and does the real work.

In what context would you be able to use ServletResponseWrapper that you couldn't just use ServletResponseConcrete directly? This make absolutely no sense to me. I don't see how it's useful for subclassing either. If I subclass ServletResponseWrapper, then I have to implement every function anyways, so why not just create a class that implements ServletResponse directly?


问:
Does a C# event have to have an object type as its first parameter?
I have a TCPClient class. It has several ClientEvents. Originally it followed the standard pattern

public delegate void ClientEvent(object sender, ClientEventArgs e);

Only TCPCLient uses this event. But I am pretty determined to keep things as standard as possible (all event based things I've seen use object sender). However what I don't see the point of, is having to cast sender to TCPClient every time.

```<code> private static void Client_OnReconnect(object sender, ClientEventArgs e) {
            TCPClient client = (TCPClient)sender;
        }
</code>```

Is there any reason I shouldn't just use

public delegate void ClientEvent(TCPClient client, ClientEventArgs e);

as my event?

答:
I am pretty determined to keep things as standard as possible

Good. You are not doing so though. The standard guidelines can be found here:

MSDN - Event Design for .NET Framework

You have violated the guideline

use System.EventHandler<TEventArgs> instead of manually creating new delegates to be used as event handlers.

Of course guidelines are guidelines, not rules. The guidelines go on to note that if you for some reason decide to violate this guideline...

use object as the type of the first parameter of the event handler, and call it sender.

Your question is:

Is there any reason I shouldn't just use delegate void ClientEvent(TCPClient client, ClientEventArgs e) as my event?

That is, if it is the case that the sender will always be a TCPClient, why not encode that in the type system?

Well, that violates the design guidelines, but of course that is mere question-begging. Why have this guideline?  The reasoning is because your assertion that the sender of this event will always and forever be TCPClient is one that historically has often turned out to be violated. You think that yeah, I'm only ever going to want to handle click events on buttons, so the sender can be Button, and then next sprint some UX designer wants to change fully half of the buttons into clickable monkeys, and now the click event needs to apply to both buttons and monkeys, and blah blah blah, you see how this goes.

Again: guidelines are guidelines, not rules. If you have confidence that encoding this restriction into the type system is higher value than the risk of having some designer say "hey, can you change half the clients into TCPMonkey, how hard can it be?" then by all means go for it.


问:
Why would you store an enum in DB?
I've seen a number of questions, like this, asking for advice on how to store enums in DB. But I wonder why would you do that. So let's say that I have an entity Person with a gender field, and a Gender enum. Then, my person table has a column gender.

Besides the obvious reason of enforcing correctness, I don't see why I would create an extra table gender to map what I already have in my application. And I don't really like having that duplication.

答:
Which of these do you think is more likely to produce mistakes when reading the query?

select *
from Person
where Gender = 1
```

<p>Or</p>

<pre class="lang-sql prettyprint-override"><code>select *
from Person join Gender on Person.Gender = Gender.GenderId
where Gender.Label = "Female"
</code>```

People make enum tables in SQL because they find the latter to be more readable - leading to fewer errors writing and maintaining SQL.

You could make gender a string directly in Person, but then you would have to try and enforce case. You also may increase the storage hit for the table and the query time due to the difference between strings and integers depending on how awesome your DB is at optimizing things.

Title: Why would you store an enum in DB?

Body:
Which of these do you think is more likely to produce mistakes when reading the query?

select *
from Person
where Gender = 1

Or

select *
from Person join Gender on Person.Gender = Gender.GenderId
where Gender.Label = "Female"

People make enum tables in SQL because they find the latter to be more readable - leading to fewer errors writing and maintaining SQL.

You could make gender a string directly in Person, but then you would have to try and enforce case. You also may increase the storage hit for the table and the query time due to the difference between strings and integers depending on how awesome your DB is at optimizing things.


答:
Let's take another example that is less fraught with conceptions and expectations. I've got an enum here, and it is the set of priorities for a bug.

What value are you storing in the database?

So, I could be storing 'C', 'H', 'M', and 'L' in the database. Or 'HIGH' and so on. This has the problem of stringly-typed data. There's a known set of valid values, and if you aren't storing that set in the database, it can be difficult to work with.

Why are you storing the data in the code?

You've got List<String> priorities = {'CRITICAL', 'HIGH', 'MEDIUM', 'LOW'}; or something to that effect in the code. It means that you've got various mappings of this data to the proper format (you're inserting all caps into the database, but you're displaying it as Critical). Your code is now also difficult to localize.  You have bound the database representation of the idea to a string that is stored in the code.

Anywhere you need to access this list, you either need to have code duplication or a class with a bunch of constants. Neither of which are good options. One should also not forget that there are other applications that may use this data (which may be written in other languages - the Java web application has a Crystal Reports reporting system used and a Perl batch job feeding data into it). The reporting engine would need to know the valid list of data (what happens if there's nothing marked in 'LOW' priority and you need to know that that is a valid priority for the report?), and the batch job would have the information about what the valid values are.

Hypothetically, you might say "we're a single-language shop - everything is written in Java" and have a single .jar that contains this information - but now it means that your applications are tightly coupled to each other and that .jar containing the data. You'll need to release the reporting part and the batch update part along with the web application each time there is a change - and hope that that release goes smoothly for all parts.

What happens when your boss wants another priority?

Your boss came by today. There's a new priority - CEO. Now you have to go and change all the code and do a recompile and redeploy.

With an 'enum-in-the-table' approach, you update the enum list to have a new priority. All the code that gets the list pulls it from the database.

Data rarely stands alone

With priorities, the data keys into other tables that might contain information about workflows, or who can set this priority or whatnot.

Going back to the gender as mentioned in the question for a bit: Gender has a link to the pronouns in use: he/his/him and she/hers/her... and you want to avoid hard coding that into the code itself. And then your boss comes by and you need to add you've got the 'OTHER' gender (to keep it simple) and you need to relate this gender to they/their/them... and your boss sees what Facebook has and... well, yeah.

By restricting yourself to a stringly-typed bit of data rather than an enum table, you've now needed to replicate that string in a bunch of other tables to maintain this relationship between the data and its other bits.

What about other datastores?

No matter where you store this, the same principle exists.

You could have a file, priorities.prop, that has the list of priorities. You read this list in from a property file.

You could have a document store database (like CouchDB) that has an entry for enums (and then write a validation function in JavaScript):

```<code>  {
     "_id": "c18b0756c3c08d8fceb5bcddd60006f4",
     "_rev": "1-c89f76e36b740e9b899a4bffab44e1c2",
     "priorities": [ "critical", "high", "medium", "low" ],
     "severities": [ "blocker", "bad", "annoying", "cosmetic" ]
  }
</code>```

You could have an XML file with a bit of a schema:

```<code>  <xs:element name="priority" type="priorityType"/>

  <xs:simpleType name="priorityType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="critical"/>
      <xs:enumeration value="high"/>
      <xs:enumeration value="medium"/>
      <xs:enumeration value="low"/>
    </xs:restriction>
  </xs:simpleType>
</code>```

The core idea is the same. The data store itself is where the list of valid values needs to be stored and enforced. By placing it here, it is easier to reason about the code and the data. You don't have to worry about defensively checking what you have each time (is it upper case? or lower? Why is there a critical type in this column? etc...) because you know what you are getting back from the datastore is exactly what the datastore is expecting you to send otherwise - and you can query the datastore for a list of valid values.

The takeaway

The set of valid values is data, not code. You do need to strive for DRY code - but the issue of duplication is that you are duplicating the data in the code, rather than respecting its place as data and storing it in a database.

It makes writing multiple applications against the datastore easier and avoids having instances where you will need to deploy everything that is tightly coupled to the data itself - because you haven't coupled your code to the data.

It makes testing applications easier because you don't have to retest the entire application when the CEO priority is added - because you don't have any code that cares about the actual value of the priority.

Being able to reason about the code and the data independently from each other makes it easier to find and fix bugs when doing maintenance.

Title: Why would you store an enum in DB?

Body:
I've seen a number of questions, like this, asking for advice on how to store enums in DB. But I wonder why would you do that. So let's say that I have an entity Person with a gender field, and a Gender enum. Then, my person table has a column gender.

Besides the obvious reason of enforcing correctness, I don't see why I would create an extra table gender to map what I already have in my application. And I don't really like having that duplication.

Body:
Let's take another example that is less fraught with conceptions and expectations. I've got an enum here, and it is the set of priorities for a bug.

What value are you storing in the database?

So, I could be storing 'C', 'H', 'M', and 'L' in the database. Or 'HIGH' and so on. This has the problem of stringly-typed data. There's a known set of valid values, and if you aren't storing that set in the database, it can be difficult to work with.

Why are you storing the data in the code?

You've got List<String> priorities = {'CRITICAL', 'HIGH', 'MEDIUM', 'LOW'}; or something to that effect in the code. It means that you've got various mappings of this data to the proper format (you're inserting all caps into the database, but you're displaying it as Critical). Your code is now also difficult to localize.  You have bound the database representation of the idea to a string that is stored in the code.

Anywhere you need to access this list, you either need to have code duplication or a class with a bunch of constants. Neither of which are good options. One should also not forget that there are other applications that may use this data (which may be written in other languages - the Java web application has a Crystal Reports reporting system used and a Perl batch job feeding data into it). The reporting engine would need to know the valid list of data (what happens if there's nothing marked in 'LOW' priority and you need to know that that is a valid priority for the report?), and the batch job would have the information about what the valid values are.

Hypothetically, you might say "we're a single-language shop - everything is written in Java" and have a single .jar that contains this information - but now it means that your applications are tightly coupled to each other and that .jar containing the data. You'll need to release the reporting part and the batch update part along with the web application each time there is a change - and hope that that release goes smoothly for all parts.

What happens when your boss wants another priority?

Your boss came by today. There's a new priority - CEO. Now you have to go and change all the code and do a recompile and redeploy.

With an 'enum-in-the-table' approach, you update the enum list to have a new priority. All the code that gets the list pulls it from the database.

Data rarely stands alone

With priorities, the data keys into other tables that might contain information about workflows, or who can set this priority or whatnot.

Going back to the gender as mentioned in the question for a bit: Gender has a link to the pronouns in use: he/his/him and she/hers/her... and you want to avoid hard coding that into the code itself. And then your boss comes by and you need to add you've got the 'OTHER' gender (to keep it simple) and you need to relate this gender to they/their/them... and your boss sees what Facebook has and... well, yeah.

By restricting yourself to a stringly-typed bit of data rather than an enum table, you've now needed to replicate that string in a bunch of other tables to maintain this relationship between the data and its other bits.

What about other datastores?

No matter where you store this, the same principle exists.

You could have a file, priorities.prop, that has the list of priorities. You read this list in from a property file.

You could have a document store database (like CouchDB) that has an entry for enums (and then write a validation function in JavaScript):

  {
     "_id": "c18b0756c3c08d8fceb5bcddd60006f4",
     "_rev": "1-c89f76e36b740e9b899a4bffab44e1c2",
     "priorities": [ "critical", "high", "medium", "low" ],
     "severities": [ "blocker", "bad", "annoying", "cosmetic" ]
  }

You could have an XML file with a bit of a schema:

  <xs:element name="priority" type="priorityType"/>

  <xs:simpleType name="priorityType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="critical"/>
      <xs:enumeration value="high"/>
      <xs:enumeration value="medium"/>
      <xs:enumeration value="low"/>
    </xs:restriction>
  </xs:simpleType>

The core idea is the same. The data store itself is where the list of valid values needs to be stored and enforced. By placing it here, it is easier to reason about the code and the data. You don't have to worry about defensively checking what you have each time (is it upper case? or lower? Why is there a critical type in this column? etc...) because you know what you are getting back from the datastore is exactly what the datastore is expecting you to send otherwise - and you can query the datastore for a list of valid values.

The takeaway

The set of valid values is data, not code. You do need to strive for DRY code - but the issue of duplication is that you are duplicating the data in the code, rather than respecting its place as data and storing it in a database.

It makes writing multiple applications against the datastore easier and avoids having instances where you will need to deploy everything that is tightly coupled to the data itself - because you haven't coupled your code to the data.

It makes testing applications easier because you don't have to retest the entire application when the CEO priority is added - because you don't have any code that cares about the actual value of the priority.

Being able to reason about the code and the data independently from each other makes it easier to find and fix bugs when doing maintenance.

ContentLicense: CC BY-SA 4.0


问:
Should conditional logic be always coded via type system where possible?
I have a choice.

Option 1:

```<code>public class Sample
{
    bool IsRelevant { get; set; }
}
</code>```

Option 2:

```<code>public class Sample
{
}

public class RelevantSample : Sample
{
}
</code>```

Is there a clear well-known rule how to make this decision?

My research: I have heard about "Replace Conditional with Polymorphism" refactoring before, but it usually deals with large switch statements:

https://sourcemaking.com/refactoring/replace-conditional-with-polymorphism

https://stackoverflow.com/questions/234458/do-polymorphism-or-conditionals-promote-better-design

https://stackoverflow.com/questions/4866873/replace-conditional-with-polymorphism-nice-in-theory-but-not-practical

There is a somewhat related question that describes a different situation (flag as a method argument rather than part of a domain entity): Is it wrong to use a boolean parameter to determine behavior?

答:
You have two good answers already; a third reason to stick with the property is that the pattern you are describing is a "one shot" pattern. Everything goes pear shaped when you add a second Boolean. We begin with:

```<code>public class Sample
{
    public bool IsRelevant { get; protected set; }
}
</code>```

and we refactor this into:

```<code>public abstract class Sample {}
public class RelevantSample : Sample {}
public class IrrelevantSample : Sample {}
</code>```

And now we realize, oh, wait, samples can also be frobby or antifrobby:

```<code>public abstract class Sample
{
    public bool IsFrobby { get; protected set; }
}
public class RelevantSample : Sample {}
public class IrrelevantSample : Sample {}
</code>```

And now how do we move that into the type system?

```<code>public class RelevantFrobbySample : RelevantSample {}
public class RelevantAntifrobbySample : RelevantSample {}
public class IrrelevantFrobbySample : IrrelevantSample {}
public class IrrelevantAntifrobbySample : IrrelevantSample {}
</code>```

And now I want to make a method that takes only frobby samples. How do I do it?

Single inheritance languages require you to choose your "inheritance pivot" extremely carefully because you only get one shot at it.

Body:
You have two good answers already; a third reason to stick with the property is that the pattern you are describing is a "one shot" pattern. Everything goes pear shaped when you add a second Boolean. We begin with:

public class Sample
{
    public bool IsRelevant { get; protected set; }
}

and we refactor this into:

public abstract class Sample {}
public class RelevantSample : Sample {}
public class IrrelevantSample : Sample {}

And now we realize, oh, wait, samples can also be frobby or antifrobby:

public abstract class Sample
{
    public bool IsFrobby { get; protected set; }
}
public class RelevantSample : Sample {}
public class IrrelevantSample : Sample {}

And now how do we move that into the type system?

public class RelevantFrobbySample : RelevantSample {}
public class RelevantAntifrobbySample : RelevantSample {}
public class IrrelevantFrobbySample : IrrelevantSample {}
public class IrrelevantAntifrobbySample : IrrelevantSample {}

And now I want to make a method that takes only frobby samples. How do I do it?

Single inheritance languages require you to choose your "inheritance pivot" extremely carefully because you only get one shot at it.


答:
The key utility of this class has to do with how you use it.

Yes, as written the class is useless. But it isn't meant to be used directly - its just something to pass through values.  But what if you want to override one method there on top of the response you've got in your hand.

Well, you could create a new .java file that does everything you want it to.

Or, you could use an anonymous class.

Consider the code:

public ServletResponse filter() {
    ServletResponse resp = something();
    /* I don't care, I  always want it to be 'UTF-8' */
    return new ServletResponseWrapper(resp) {
        @override
        public String getCharacterEncoding() {
          return "UTF-8";
        }
    };
}
```

Granted, this is a trivial one that could have been done by calling a setter in the response itself, but you get the idea of what it could be used for.

And there you have a very nice and concise bit of code that uses the ServletResponseWrapper. While the wrapper is useless as is, it facilitates other code that is not useless.  The alternative code to this is significantly more verbose and the essential information about what it does may be lost in that verbosity.

Body:
The key utility of this class has to do with how you use it.

Yes, as written the class is useless. But it isn't meant to be used directly - its just something to pass through values.  But what if you want to override one method there on top of the response you've got in your hand.

Well, you could create a new .java file that does everything you want it to.

Or, you could use an anonymous class.

Consider the code:

public ServletResponse filter() {
    ServletResponse resp = something();
    /* I don't care, I  always want it to be 'UTF-8' */
    return new ServletResponseWrapper(resp) {
        @override
        public String getCharacterEncoding() {
          return "UTF-8";
        }
    };
}

Granted, this is a trivial one that could have been done by calling a setter in the response itself, but you get the idea of what it could be used for.

And there you have a very nice and concise bit of code that uses the ServletResponseWrapper. While the wrapper is useless as is, it facilitates other code that is not useless.  The alternative code to this is significantly more verbose and the essential information about what it does may be lost in that verbosity.


问:
A simple approach for data synchronisation
I want to synchronise the local database of mobile devices with the server's database. This synchronisation will happen for example when user comes online, to update the local as well as the remote database with possible changes.

I thought about 2 approaches and already implemented 1 of them, but it's quite complicated and I fear a bit about its performance and error-proneness.

Approach 1.

The approach I implemented does all the synchronisation in the server. I'll store in the client's database the last server update timestamp for each item and a flag for items that are marked for removal. I send all my items - with their timestamps and flags - to the server, and the server then decides which items have to be inserted, updated - only if the last update timestamp of the client is equal to the last update timestamp stored in the server (meaning the client has the latest version of the item) and what has to be deleted. Then I do a fresh query to the database and send everything back to the client. The client overwrites it's local database with the result. In detail:

Client sends all its items to server (this could be refined by filtering items that need create/update/delete, but for now it sends everything). Items have a server last update timestamp and flag if it's marked to be deleted.

Server queries all the items for the user

Programmatic algorithm that goes through all the items checking timestamps in order to determine if the item can be updated/deleted or not. If the last server update timestamp in the client's item is different than the one stored in the server (meaning, someone else updated the item in between) the update/delete is rejected. I build many lists here, one of items that have to be inserted (items are not in the server's query result), items that are to be updated, items that are to be deleted, items that can't be updated because the timestamp is different, items that can't be deleted because the timestamp is different.

Transaction for inserts/updates/deletes, for which I use lists constructed in 3.

Query to get again all the items for the user.

Send result of this query to client, together with the lists of items that couldn't be updated or deleted built in 3., so client knows what failed.

The problem with this approach is the multiple queries and programmatic processing, another client (some items can have multiple users) could update something in between these queries and updates can get lost. I assume I have to compact my queries (try to somehow do everything in a single transaction, maybe use stored procedures?) and lock rows to avoid synchronisation issues. My knowledge of SQL doesn't go much further than select...where and join so I may me missing a better way to do this.

Approach 2.

Because of these complications I was thinking if there's maybe a simpler way. The other idea I had, was to do the synchronisation in the client. So I'd do first query all my data and do an update (for which I still need the last update timestamp and delete flags - only this time the sync logic is in the client and I don't have to worry about multiple users here), and then send the sync result to the server which will just do an overwrite. In detail:

Download items for user

Do sync alhorithm in the client, similar to what I do in the server in 3. (Approach 1).

Upload items to the server, server overwrites user's items with this.

The problem here, of course, is that another client can update items in the server while this client is doing sync, and when it uploads the results, the updates of former client will be lost. I thought maybe I can work around this with a hash, so the downloaded data has a hash and when the database is to be overwritten with the sync result I do a query first and check it's the same hash, if not return an error. But then again I'm with multiple queries in the server and not sure this a recommended way.

I'd appreciate thoughts on this matter. Is my current approach the best? Or should I rather go with the client sync (this would also reduce workload in the server, which is good), but then how do I avoid possible overwrites, is the hash a good idea?  Note that my app doesn't have super strict requirements, it's something like shared todo lists with a few additional features, nothing generic (like a file sharing service) or for health, science etc. so if once in a (long) while an update is lost it's not the end of the world. I care a little more about performance and implementation easiness than 100% correctness. Of course the less error prone, the better.

P.S. would also appreciate reading recommendations about this (maybe as a comment), any good resource about sync strategies. I'm using Scala, Play 2.4 and Akka in some parts so a recommendation in this direction would also be very useful.

答:
Syncing between multiple clients is a very complext task.

Let's not call it syncing, let's call it bash transaction processing.

Let's get rid of "last server update timestamp", let's just every transaction be inserted into a pre-process table with a timestamp generated by the server.

Let's make it asyncronous. If data is processed fast enough, users shouldn't notice.

Client generates a job id (hash of userid plus timestamp plus some other randon data), and pushes it to the server.

Server saves the job id in a jobs table and assigns it a timestamp

Client sends transactions that will be in that job

ITEM ID is client generated using a hash function the same way job id was generated.

A process that runs, say every few seconds gets the more recent pending job, and proceeds to process all transactions.

Transactions that couldn't be done because the ITEM was previously erased are inserted in a rejects table

Current data after transaction is pushed to client including rejections (client data is deleted and new data is inserted, client perceives it as a refresh)

A jobs can be transanction-less, meaning it's only a refresh request.

Overwrites cannot be avoided but you can opt to duplicate entries when a conflict arises instead of overwriting the older version of an item.


问:
What is Domain Driven Development in practical terms?
I heard about Domain Driven Development from a developer in the area.  He talked it up like it was just about the silver bullet to changing requirements.

I read the wiki.  Still not too clear.  What is "3D" in practical terms?  Is it really that amazing that now UML class diagramming is just obsolete?

答:
DISCLAIMER: I've added this answer after this question has been marked as duplicate. I disagree, but here we are. :-)

Domain-Driven Design aims to design software in high-value/high complexity domains.

This turns into a different approach for building enterprise software: there's too much learning involved, and the most important consequence is that you won't get to the right solution at first shot.

Because you'll learn along the way.

Because stakeholders won't tell all the truth in a single shot.

Because the domain will evolve along the way.

Or the combination of both.

Both ways you'll need good software foundations for frequently rewrite software. That's the reason why the book stressed on a given set of patterns around the Domain Model pattern: they were the most reasonable combination in 2004.

However, OOP and the tactical pattern are not the most important thing. Technical mastery is necessary in order to build great software in an evolutionary way. But it's only one ingredient of the recipe. The others?

Obsession with the language as a way to discover hidden nuances.

Focus on the big picture view to be able to deliver great stuff.

Cohabitation of many simpler models instead of a larger one.

Emphasis on Collaborative modelling with the domain experts and inside the development team.


问:
Factories, vectors and smart pointers - Design Question
So, my Business Code needs some Objects.

It does not know how much objects it needs and it does not know the exact types (because polymorphism is involved).

For me, that sounds for a good reason to go factory pattern.

My code now looks like:

```<code>std::vector<AbstractBaseClass*> objectList;
Factory f;
objectList = f.create("path/to/config.txt");
</code>```

The prototype of the factory's create-method looks like:

```<code>std::vector<AbstractBaseClass*> Factory ::create(std::string configFile)
</code>```

Good news, its working!

The Factory reads the config, and then decides how many objects to create and which concrete types they have.

Well, I did a lot of searching but I couldn't find an example of a factory returning not a single object but a container. Thus, my question: is this good style?

I think yes because this way the whole parsing/creation process is hidden from the business logic. The logic only knows it has some container with a bunch of objects. But maybe you have other opinions?

Please note: this project is all about learning good OOP habits.

Ok, imagine this approach is OK.

I learned, raw pointers are evil. (OK, they are not evil per definition, but I try to avoid them).

So, I want to move to some smart pointers. Lacking boost and C++11 on this machine I'm starting with auto_ptr.

OK, new approach:

```<code>std::vector< auto_ptr<AbstractBaseClass> > objectList;
Factory f;
objectList = f.create("path/to/config.txt");
</code>```

And Factory:

```<code>std::vector< auto_ptr <AbstractBaseClass> > Factory ::create(std::string configFile)
</code>```

This looks evil.

And it doesn't compile because at the moment, I'm getting some crazy STL compiler errors.

But, imagin' it compiles.

Is this good?

I've never seen such a construct - a factory returning a container of smart pointers.
And because I'm not that expert, I want to ask what you think about this.

On a related note, what smart pointer shall I use?

The business logic is the only owner of the objects, so I guess unique_ptr.
However, I'm not sure if a unique_ptr container can be returned.
shared_ptr is easier to implement, I think.

答:
If you use C++ as a mostly OOP language, you'll have to deal with pointers in some form or another. The answer to almost all pointer problems is std::unique_ptr, because it has fairly value-like semantics while still enabling you to use polymorphism. Its only overhead is syntactic clutter. This is a lot better than

raw pointers, because pointers have no inherent ownership semantics. I've seen pointers being used for both reference-like borrowing semantics, and copy-like ownership transferral. That might be in the documentation, but it certainly isn't encoded in the source code or the type system.

the C++11 std::shared_ptr because this has additional overhead for reference counting.

the deprecated std::auto_ptr because it has confused semantics: copying behaves like moving, which also requires that the copy source is not const so that the moved pointer can be erased from the source. (Also note that the copy assignment operator for std::vector expects a const reference, so vector<auto_ptr<T>> is non-copyable.)

hand-written Pimpl wrappers, since it can be challenging to implement a type correctly – I've seen enough memory leaks and segfaults from less-than-correct implementations (tip: make it impossible to use a null pointer as the impl). In fact, I recommend Pimpls to be implemented in terms of a private unique_ptr field since that takes care of all necessary resource management.

However, using a Pimpl as Bridge Pattern can enable you to design a polymorphic class hierarchy with a value-based API but pointer-like semantics. In particular, you could use vector<BaseClass> as a more convenient notation for vector<unique_ptr<BaseClassIf>>.

The “problem” with std::unique_ptr is that it requires C++11. The core idea of this pointer type is that it can't be copied, but it can be moved. Therefore, ownership is always clearly defined. When you return an object by value, it will be subject to copy semantics (even if the actual copy might be optimized away), except in C++11 where move semantics will allow you to return an unique_ptr by value.

In general, using a container of smart pointers is perfectly fine, and better than the alternatives. In your case, it fails because of the restricted semantics of C++03 with regards to auto_ptr. If you can't upgrade to C++11 (which is supported in all current mainstream compilers), you have two realistic choices: use raw pointers, or wrap the pointer in a custom Pimpl. I'd use the Pimpl if the effort is justifiable. It isn't tremendously complicated code, but you have to be careful to forward all necessary operations:

```<code>class BaseClassIf {
public:
  virtual ~BaseClassIf() {}
  virtual void someOperation() = 0;
  virtual BaseClassIf* copy() = 0; // { return new T(*this); }
}

class BaseClass {
  BaseClassIf* impl;
  void assertInvariant() { if (!impl) throw ...; }
public:
  BaseClass(BaseClassIf* impl) : impl(impl) { assertInvariant(); }

  ~BaseClass() { if (impl) delete impl; impl = 0; }

  BaseClass(const BaseClass& o) : impl(o.impl->copy()) { assertInvariant(); }

  void someOperation() { impl->someOperation(); }

private:
  BaseClass& operator=(const BaseClass&);
  // Cannot be reasonably overloaded as a value-based copy,
  // e.g. "*impl = *rhs.impl" since the exact types are unknown.
  // Cannot be overloaded as a reference copy,
  // e.g. "impl = rhs.impl" since that violates pointer ownership.
};
</code>```

Note that the interface must make provisions to access the copy constructor, since the exact type is unknown by the BaseClass wrapper. This is an occasionally useful technique (e.g. as “type erasure” to hide template parameters), but here it's just annoying fallout from using polymorphism. Also note that it is not possible to define a copy assignment operator for the adapter, unless you include a common virtual BaseClassIf::operator=(const BaseClassIf&) method in your interface – but most object hierarchies cannot do an useful copy from their common base.

Body:
If you use C++ as a mostly OOP language, you'll have to deal with pointers in some form or another. The answer to almost all pointer problems is std::unique_ptr, because it has fairly value-like semantics while still enabling you to use polymorphism. Its only overhead is syntactic clutter. This is a lot better than

raw pointers, because pointers have no inherent ownership semantics. I've seen pointers being used for both reference-like borrowing semantics, and copy-like ownership transferral. That might be in the documentation, but it certainly isn't encoded in the source code or the type system.

the C++11 std::shared_ptr because this has additional overhead for reference counting.

the deprecated std::auto_ptr because it has confused semantics: copying behaves like moving, which also requires that the copy source is not const so that the moved pointer can be erased from the source. (Also note that the copy assignment operator for std::vector expects a const reference, so vector<auto_ptr<T>> is non-copyable.)

hand-written Pimpl wrappers, since it can be challenging to implement a type correctly – I've seen enough memory leaks and segfaults from less-than-correct implementations (tip: make it impossible to use a null pointer as the impl). In fact, I recommend Pimpls to be implemented in terms of a private unique_ptr field since that takes care of all necessary resource management.

However, using a Pimpl as Bridge Pattern can enable you to design a polymorphic class hierarchy with a value-based API but pointer-like semantics. In particular, you could use vector<BaseClass> as a more convenient notation for vector<unique_ptr<BaseClassIf>>.

The “problem” with std::unique_ptr is that it requires C++11. The core idea of this pointer type is that it can't be copied, but it can be moved. Therefore, ownership is always clearly defined. When you return an object by value, it will be subject to copy semantics (even if the actual copy might be optimized away), except in C++11 where move semantics will allow you to return an unique_ptr by value.

In general, using a container of smart pointers is perfectly fine, and better than the alternatives. In your case, it fails because of the restricted semantics of C++03 with regards to auto_ptr. If you can't upgrade to C++11 (which is supported in all current mainstream compilers), you have two realistic choices: use raw pointers, or wrap the pointer in a custom Pimpl. I'd use the Pimpl if the effort is justifiable. It isn't tremendously complicated code, but you have to be careful to forward all necessary operations:

class BaseClassIf {
public:
  virtual ~BaseClassIf() {}
  virtual void someOperation() = 0;
  virtual BaseClassIf* copy() = 0; // { return new T(*this); }
}

class BaseClass {
  BaseClassIf* impl;
  void assertInvariant() { if (!impl) throw ...; }
public:
  BaseClass(BaseClassIf* impl) : impl(impl) { assertInvariant(); }

  ~BaseClass() { if (impl) delete impl; impl = 0; }

  BaseClass(const BaseClass& o) : impl(o.impl->copy()) { assertInvariant(); }

  void someOperation() { impl->someOperation(); }

private:
  BaseClass& operator=(const BaseClass&);
  // Cannot be reasonably overloaded as a value-based copy,
  // e.g. "*impl = *rhs.impl" since the exact types are unknown.
  // Cannot be overloaded as a reference copy,
  // e.g. "impl = rhs.impl" since that violates pointer ownership.
};

Note that the interface must make provisions to access the copy constructor, since the exact type is unknown by the BaseClass wrapper. This is an occasionally useful technique (e.g. as “type erasure” to hide template parameters), but here it's just annoying fallout from using polymorphism. Also note that it is not possible to define a copy assignment operator for the adapter, unless you include a common virtual BaseClassIf::operator=(const BaseClassIf&) method in your interface – but most object hierarchies cannot do an useful copy from their common base.


答:
To your first question: "is it good style to let a factory return method a container?":

IMHO there is nothing special with a type like std::vector<AbstractBaseClass*> - it is, at least in principle, a user defined type like any other type. You could make a typedef alias like

```<code> typedef std::vector<AbstractBaseClass*> MyAbstractBaseClassContainer;
</code>```

if that gives you a better abstraction, or wrap it within a new class. The latter gives you the opportunity to make the constructor private, so prohibiting the creation of objects of that type by any different means than a static class member factory method.  But that is actually not necessarily required for a "good" factory - if std::vector<AbstractBaseClass*> suits your needs, go ahead!

If you should prefer some_smart_ptr<AbstractBaseClass> over AbstractBaseClass*, especially in the context of a vector is a completely independent question from the first one. Since there were already good answers to that question, for example here or here, or @amon's answer, I am not trying to answer this one, I doubt my answer would become better.

Title: Factories, vectors and smart pointers - Design Question

Body:
So, my Business Code needs some Objects.

It does not know how much objects it needs and it does not know the exact types (because polymorphism is involved).

For me, that sounds for a good reason to go factory pattern.

My code now looks like:

```<code>std::vector<AbstractBaseClass*> objectList;
Factory f;
objectList = f.create("path/to/config.txt");
</code>```

The prototype of the factory's create-method looks like:

```<code>std::vector<AbstractBaseClass*> Factory ::create(std::string configFile)
</code>```

Good news, its working!

The Factory reads the config, and then decides how many objects to create and which concrete types they have.

Well, I did a lot of searching but I couldn't find an example of a factory returning not a single object but a container. Thus, my question: is this good style?

I think yes because this way the whole parsing/creation process is hidden from the business logic. The logic only knows it has some container with a bunch of objects. But maybe you have other opinions?

Please note: this project is all about learning good OOP habits.

Ok, imagine this approach is OK.

I learned, raw pointers are evil. (OK, they are not evil per definition, but I try to avoid them).

So, I want to move to some smart pointers. Lacking boost and C++11 on this machine I'm starting with auto_ptr.

OK, new approach:

```<code>std::vector< auto_ptr<AbstractBaseClass> > objectList;
Factory f;
objectList = f.create("path/to/config.txt");
</code>```

And Factory:

```<code>std::vector< auto_ptr <AbstractBaseClass> > Factory ::create(std::string configFile)
</code>```

This looks evil.

And it doesn't compile because at the moment, I'm getting some crazy STL compiler errors.

But, imagin' it compiles.

Is this good?

I've never seen such a construct - a factory returning a container of smart pointers.
And because I'm not that expert, I want to ask what you think about this.

On a related note, what smart pointer shall I use?

The business logic is the only owner of the objects, so I guess unique_ptr.
However, I'm not sure if a unique_ptr container can be returned.
shared_ptr is easier to implement, I think.

Body:
To your first question: "is it good style to let a factory return method a container?":

IMHO there is nothing special with a type like std::vector<AbstractBaseClass*> - it is, at least in principle, a user defined type like any other type. You could make a typedef alias like

 typedef std::vector<AbstractBaseClass*> MyAbstractBaseClassContainer;

if that gives you a better abstraction, or wrap it within a new class. The latter gives you the opportunity to make the constructor private, so prohibiting the creation of objects of that type by any different means than a static class member factory method.  But that is actually not necessarily required for a "good" factory - if std::vector<AbstractBaseClass*> suits your needs, go ahead!

If you should prefer some_smart_ptr<AbstractBaseClass> over AbstractBaseClass*, especially in the context of a vector is a completely independent question from the first one. Since there were already good answers to that question, for example here or here, or @amon's answer, I am not trying to answer this one, I doubt my answer would become better.


问:
How to get the behavior class from its data class when they are separated for the purpose of server-client communication?
I am writing a server-client program with the following idea (analogy for my real program). There are many types of shapes. The client represents the shapes to the user which can queue operations (like translation, rotation...) on them. The client sends the server the id and operation type. The server performs the operation and sends the new shape data back to the client.

In my current design I have the classes I detail below.

The Shape class sits only on the server, its subclasses contain algorithms for performing the operations for each shape (pretend that rotating a triangle and a square is very different). I do not want nor need that they be accessible to the client.

```<code>abstract class Shape {

    ShapeData data; // see below
    int[] plane; // some non-static parameter used by the server

    abstract void rotate();
    abstract void translate();
    abstract void rescale();
    // ... 10 more
}
</code>```

The subclasses also sit only on the server

```<code>class Square extends Shape {

    void rotate()    { /* using ShapeData data and int[] plane ...*/ }
    void translate() { /*    "   */ };
    void rescale()   { /*    "   */ };
}

class Circle extends Shape {

    // same structure as square
}

// many more shapes
</code>```

ShapeData is a class which holds the data of a shape (same data structure for all shapes). It is the class that is transfered from the server to the client from which the client can, for example, draw the shape. The class is also used by the server to perform the computations as seen above.

```<code>abstract class ShapeData implements Serializeable {

    int id; // after manipulating the shape represented by this class, the
            // client send this id back to the server

    int edgesNum;
    int width;
    int height;
    // ...

    // setters and getters
}
</code>```

I understand that separating data and behavior is not an OO approach, but I treat this class as a DTO (reference).

Getting the shape data from the shape is simple as it is "composed" into it, the problem is the other way around. The server keeps a List<ShapeData> which I retrieve from by id, but there is no obvious way to get the Shape on which to apply the transformation. This lead me to think that the design is bad.

Right now I keep a Map<ShapeData, Shape> to retrieve Shape. Another way is to add an id field to Shape with the same value as in its ShapeData and keep a List<Shape> from which I retrieve by id too.

Is the design bad or is there just some modification I can do to make it work "properly"?

答:
The design is not inherently bad. Let's asume the transformations to be performed on the shapes are resource consuming and that is reason enough to have the behavior un the server.

In MHO the matching id is the way to go. You then pass a List<ShapeData> object back and forth. The client receives such a list and renders the graphics. The server receives such a list and matches every ShapeData with its corresponding Shape to make transformations.

EDIT

(1) Why do you prefer this approach?

To me every different type of Shape is a flyweight object, data is injected everytime a transformation is needed.

The id would help implement Chain-of_responsability pattern in which every processor object see whether the data is for them to work on they must pass it on to the next processor.

(2) The client send only the id and transformation request (not included in my classes above), I don't see why it should pass the whole unchanged data class.

So the servers doesn't have to have a permanent copy of every user's object. Objects live in the client, they are send to the server and the server sends them back transformed, servder doesn't need to have a synchronized copy of them. IMHO.

(3) So you suggest that I go with keeping a List<Shape> and search it by id

That way you could implement chain-of_responsability and flyweight patterns.