答:
Your phrase

"Is the coordinator and translator between the Model and the View."

indicates that your Bridge is the Presenter in an MVP architecture.

MVP and MVC are very similar, except that in MVP only the Presenter observes the Model while in MVC the View is also allowed to directly observe the Model (without the Presenter as a "Bridge").

Your Model responsibility

"Informs the Bridge when data changes (for data the Bridge has expressed interest in)."

is perhaps poorly phrased or perhaps a mistake: you don't want the Model to have a dependency on either the Bridge/Presenter/Controller or the View. Instead, you use either an Observer pattern, Events, or Reactive Programming to allow the Bridge to subscribe to changes in the Model. And then you can rephrase your responsibility as:

"Allows outside subscribers (about which it knows nothing) to monitor it's state or calculation results."

If your Model has no dependencies on your Controller or View, it is easier to test and vastly more portable.

Title: Proper Model-View-_____ design

Body:
I've been reading up about Model View Controller, Model View Presenter, Model View ViewModel, and so on, and generally, the underlying concept seems pretty simple to understand: keep the pretty visuals and sciencey guts as separate and ignorant of each other as possible. No getting the logic peanut butter in the design chocolate; cool, I like that.

The problem is I'm still a bit fuzzy as to that third part... the not-model-or-view one. Everyone seems to have their own idea of what to call it, what it should do, what's proper, what's just plain wrong... and I'm going nuts trying to figure out when a Presenter becomes a ViewModel and when a View shouldn't be doing that because that's the Presenter's job and--

I'm rambling.

Rather than asking for someone to explain the difference between them--because that's already been done time and time again (I know; I've read more articles than I can count)--I'd be curious to hear the thoughts of a few programmers on the model I've cobbled together myself.

That said, what would you classify this design as, and perhaps more importantly, do you see anything about this that obviously sucks? Sure, I'd love to hear I'm doing good if this truly is solid design, but I'd much rather be given solid advice over praise.

Note: I'll be using "the Bridge" for the mysterious third part of Model-View-? to avoid any subconscious suggestions of what it "should" be.

Model

Is the authority on data.

Receives information about requested changes from the Bridge.

Contains and performs all logic for how data relates to other data.

<s>Informs the Bridge when data changes (for data the Bridge has expressed interest in).</s> Wording edit: Allows outside subscribers (about which it knows nothing) to monitor it's state or calculation results.

Has zero knowledge of the View.

View

Is concerned with providing the user a way to view and manipulate data.

Receives information about data updates from the Bridge.

Contains and performs all logic for how to present data and controls to the user.

Informs the Bridge when the user has performed an action that (possibly) affects the Model.

Informs the Bridge what information it's interested in.

Has zero knowledge of the Model.

Bridge

Is the coordinator and translator between the Model and the View.

Makes any appropriate formatting changes to information being passed between the Model and the View.

Retains information on "who needs to know what".

Has knowledge of both the Model and the View.

Additional Notes

In more complicated programs, it's common for there to be multiple Models. In this situation, the Bridge typically takes on the job of coordinating/translating between the multiple Models, and thus becomes the authority on what protocall/API/design Models should be built to. (e.g. if building a card game program, and you want to build an alternate deck shuffling model, you should use the Bridge for determining what functions are required for properly communication with the Bridge.)

In small simple programs with only one View and Model, it's common for the Bridge to "assume" what functionality is available on either side. However, as programs become more complex, it's recommended that the View(s) and Model(s) report their functionality to the Bridge so that it can avoid inefficiencies and buggy assumptions.

I think that just about covers it. By all means, I welcome any questions you might have about the design I tend to use, and I likewise encourage any suggestions.

And as always, thank you for your time.


问:
How is a floating point number represented in Java?
Which algorithm does java uses to convert floating point number (Ex:0.15625) into binary(0.00101)?

Whether java uses normalized form or denormalized format?

If I type float ab=0.15625 in Java source file, which part of compiling and running the code will convert that floating point number into a format that could be stored in memory and used by the JVM?

答:
The first thing to realize is that the binary representation of 0.15625 is not 0.00101.  Yes, that is what you would write if you were writing out the number by hand.  The actual representation of the number within the computer using IEE 754 for single precision 32 bit.  This is specified as part of the Java Language Specification 4.2:

The floating-point types are float, whose values include the 32-bit IEEE 754 floating-point numbers, and double, whose values include the 64-bit IEEE 754 floating-point numbers.

The IEEE 754 binary representation of 0.15625 is: 0x3E200000 which can be broken down into:

a sign bit: 0 meaning it is positive.

the exponent for bits: 01111100 which is 124.  This value is subtracted from 127 to get the actual exponent that will be used (-3)

the  significand: .0100000 00000000 00000000.  The . I put there is for reading so that it is bytes, not part of the value (the significant uses the lower 23 bits of the number... so the 24th bit I represent with a . so the alignment is easier to read)  This value is added to 1 giving us the binary value of 1.010.... or in base 10, 1.25000...

Combining these all together, we get:

(-1)0 * 1.012 * 2-3 which comes out to be, when written, 0.00101.  But remember, that we're really dealing with 0x3E200000.

Lets take a quick Java source file:

```<code>package com.michaelt.so.floating;

public class Demo {
    float foo = 0.15625f;
}
</code>```

The byte code for this, when decompiled is:

```<code>// class version 50.0 (50)
// access flags 0x21
public class com/michaelt/so/floating/Demo {

  // compiled from: Demo.java

  // access flags 0x0
  F foo

  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 3 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
   L1
    LINENUMBER 4 L1
    ALOAD 0
    LDC 0.15625
    PUTFIELD com/michaelt/so/floating/Demo.foo : F
    RETURN
   L2
    LOCALVARIABLE this Lcom/michaelt/so/floating/Demo; L0 L2 0
    MAXSTACK = 2
    MAXLOCALS = 1
}
</code>```

Which really isn't too interesting.  You can see the LDC 0.15625 in there which is a load constant opcode.  It takes one argument from a constant pool and pushes it on the stack.

So, lets look at Demo.class with a hex dump viewer.

```<code>$ hexdump -C Demo.class
00000000  ca fe ba be 00 00 00 32  00 15 0a 00 05 00 11 04  |.......2........|
00000010  3e 20 00 00 09 00 04 00  12 07 00 13 07 00 14 01  |> ..............|
00000020  00 03 66 6f 6f 01 00 01  46 01 00 06 3c 69 6e 69  |..foo...F...<ini|
00000030  74 3e 01 00 03 28 29 56  01 00 04 43 6f 64 65 01  |t>...()V...Code.|
00000040  00 0f 4c 69 6e 65 4e 75  6d 62 65 72 54 61 62 6c  |..LineNumberTabl|
00000050  65 01 00 12 4c 6f 63 61  6c 56 61 72 69 61 62 6c  |e...LocalVariabl|
00000060  65 54 61 62 6c 65 01 00  04 74 68 69 73 01 00 1f  |eTable...this...|
00000070  4c 63 6f 6d 2f 6d 69 63  68 61 65 6c 74 2f 73 6f  |Lcom/michaelt/so|
00000080  2f 66 6c 6f 61 74 69 6e  67 2f 44 65 6d 6f 3b 01  |/floating/Demo;.|
00000090  00 0a 53 6f 75 72 63 65  46 69 6c 65 01 00 09 44  |..SourceFile...D|
000000a0  65 6d 6f 2e 6a 61 76 61  0c 00 08 00 09 0c 00 06  |emo.java........|
000000b0  00 07 01 00 1d 63 6f 6d  2f 6d 69 63 68 61 65 6c  |.....com/michael|
000000c0  74 2f 73 6f 2f 66 6c 6f  61 74 69 6e 67 2f 44 65  |t/so/floating/De|
000000d0  6d 6f 01 00 10 6a 61 76  61 2f 6c 61 6e 67 2f 4f  |mo...java/lang/O|
000000e0  62 6a 65 63 74 00 21 00  04 00 05 00 00 00 01 00  |bject.!.........|
000000f0  00 00 06 00 07 00 00 00  01 00 01 00 08 00 09 00  |................|
00000100  01 00 0a 00 00 00 39 00  02 00 01 00 00 00 0b 2a  |......9........*|
00000110  b7 00 01 2a 12 02 b5 00  03 b1 00 00 00 02 00 0b  |...*............|
00000120  00 00 00 0a 00 02 00 00  00 03 00 04 00 04 00 0c  |................|
00000130  00 00 00 0c 00 01 00 00  00 0b 00 0d 00 0e 00 00  |................|
00000140  00 01 00 0f 00 00 00 02  00 10                    |..........|
0000014a
</code>```

Look, right there at the start of the second line...

```<code>00000010  3e 20 00 00
</code>```

There's the number.

Someone is going to ask 'but why is the number way up there? There's not even a 12 near it (the hex value for LDC).' And they are right to ask this.  Remember that the LDC tool a value from the constant pool.  The byte code that I had earlier was converted back into something a person could read.

The structure of a class file can be found in the Java Virtual Machine Specification section 4.1:

```<code>ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}
</code>```

We've got the magic number at the top (ca fe ba be), and the minor version (00 00), and major version (00 32 = 5010) and then the constant pool count (00 15) which then has the constant pool itself.

The constant pool is specified in section 4.4 which has the format:

```<code>cp_info {
    u1 tag;
    u1 info[];
}
</code>```

The tag value of 04 says that 'what is next is a float`. You can see it at the end of the preceding line.

```<code>00000000  ca fe ba be 00 00 00 32  00 15 0a 00 05 00 11 04  |.......2........|
00000010  3e 20 00 00 09 00 04 00  12 07 00 13 07 00 14 01  |> ..............|
</code>```

The other stuff that is around the number is information about locations for methods (it still has a default constructor), the name of the field, the name of the class, etc... there are a bunch of constants in there.

The key thing there though, you can see the floating point number stored in the class file as an IEEE 754 value that indicates this is something that the compiler does.

ContentLicense: CC BY-SA 3.0

Body:
The first thing to realize is that the binary representation of 0.15625 is not 0.00101.  Yes, that is what you would write if you were writing out the number by hand.  The actual representation of the number within the computer using IEE 754 for single precision 32 bit.  This is specified as part of the Java Language Specification 4.2:

The floating-point types are float, whose values include the 32-bit IEEE 754 floating-point numbers, and double, whose values include the 64-bit IEEE 754 floating-point numbers.

The IEEE 754 binary representation of 0.15625 is: 0x3E200000 which can be broken down into:

a sign bit: 0 meaning it is positive.

the exponent for bits: 01111100 which is 124.  This value is subtracted from 127 to get the actual exponent that will be used (-3)

the  significand: .0100000 00000000 00000000.  The . I put there is for reading so that it is bytes, not part of the value (the significant uses the lower 23 bits of the number... so the 24th bit I represent with a . so the alignment is easier to read)  This value is added to 1 giving us the binary value of 1.010.... or in base 10, 1.25000...

Combining these all together, we get:

(-1)0 * 1.012 * 2-3 which comes out to be, when written, 0.00101.  But remember, that we're really dealing with 0x3E200000.

Lets take a quick Java source file:

package com.michaelt.so.floating;

public class Demo {
    float foo = 0.15625f;
}

The byte code for this, when decompiled is:

// class version 50.0 (50)
// access flags 0x21
public class com/michaelt/so/floating/Demo {

  // compiled from: Demo.java

  // access flags 0x0
  F foo

  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 3 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
   L1
    LINENUMBER 4 L1
    ALOAD 0
    LDC 0.15625
    PUTFIELD com/michaelt/so/floating/Demo.foo : F
    RETURN
   L2
    LOCALVARIABLE this Lcom/michaelt/so/floating/Demo; L0 L2 0
    MAXSTACK = 2
    MAXLOCALS = 1
}

Which really isn't too interesting.  You can see the LDC 0.15625 in there which is a load constant opcode.  It takes one argument from a constant pool and pushes it on the stack.

So, lets look at Demo.class with a hex dump viewer.

$ hexdump -C Demo.class
00000000  ca fe ba be 00 00 00 32  00 15 0a 00 05 00 11 04  |.......2........|
00000010  3e 20 00 00 09 00 04 00  12 07 00 13 07 00 14 01  |> ..............|
00000020  00 03 66 6f 6f 01 00 01  46 01 00 06 3c 69 6e 69  |..foo...F...<ini|
00000030  74 3e 01 00 03 28 29 56  01 00 04 43 6f 64 65 01  |t>...()V...Code.|
00000040  00 0f 4c 69 6e 65 4e 75  6d 62 65 72 54 61 62 6c  |..LineNumberTabl|
00000050  65 01 00 12 4c 6f 63 61  6c 56 61 72 69 61 62 6c  |e...LocalVariabl|
00000060  65 54 61 62 6c 65 01 00  04 74 68 69 73 01 00 1f  |eTable...this...|
00000070  4c 63 6f 6d 2f 6d 69 63  68 61 65 6c 74 2f 73 6f  |Lcom/michaelt/so|
00000080  2f 66 6c 6f 61 74 69 6e  67 2f 44 65 6d 6f 3b 01  |/floating/Demo;.|
00000090  00 0a 53 6f 75 72 63 65  46 69 6c 65 01 00 09 44  |..SourceFile...D|
000000a0  65 6d 6f 2e 6a 61 76 61  0c 00 08 00 09 0c 00 06  |emo.java........|
000000b0  00 07 01 00 1d 63 6f 6d  2f 6d 69 63 68 61 65 6c  |.....com/michael|
000000c0  74 2f 73 6f 2f 66 6c 6f  61 74 69 6e 67 2f 44 65  |t/so/floating/De|
000000d0  6d 6f 01 00 10 6a 61 76  61 2f 6c 61 6e 67 2f 4f  |mo...java/lang/O|
000000e0  62 6a 65 63 74 00 21 00  04 00 05 00 00 00 01 00  |bject.!.........|
000000f0  00 00 06 00 07 00 00 00  01 00 01 00 08 00 09 00  |................|
00000100  01 00 0a 00 00 00 39 00  02 00 01 00 00 00 0b 2a  |......9........*|
00000110  b7 00 01 2a 12 02 b5 00  03 b1 00 00 00 02 00 0b  |...*............|
00000120  00 00 00 0a 00 02 00 00  00 03 00 04 00 04 00 0c  |................|
00000130  00 00 00 0c 00 01 00 00  00 0b 00 0d 00 0e 00 00  |................|
00000140  00 01 00 0f 00 00 00 02  00 10                    |..........|
0000014a

Look, right there at the start of the second line...

00000010  3e 20 00 00

There's the number.

Someone is going to ask 'but why is the number way up there? There's not even a 12 near it (the hex value for LDC).' And they are right to ask this.  Remember that the LDC tool a value from the constant pool.  The byte code that I had earlier was converted back into something a person could read.

The structure of a class file can be found in the Java Virtual Machine Specification section 4.1:

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

We've got the magic number at the top (ca fe ba be), and the minor version (00 00), and major version (00 32 = 5010) and then the constant pool count (00 15) which then has the constant pool itself.

The constant pool is specified in section 4.4 which has the format:

cp_info {
    u1 tag;
    u1 info[];
}

The tag value of 04 says that 'what is next is a float`. You can see it at the end of the preceding line.

00000000  ca fe ba be 00 00 00 32  00 15 0a 00 05 00 11 04  |.......2........|
00000010  3e 20 00 00 09 00 04 00  12 07 00 13 07 00 14 01  |> ..............|

The other stuff that is around the number is information about locations for methods (it still has a default constructor), the name of the field, the name of the class, etc... there are a bunch of constants in there.

The key thing there though, you can see the floating point number stored in the class file as an IEEE 754 value that indicates this is something that the compiler does.


问:
.NET Framework standard container type for multi-value property?
I'd like to create a simple class property which can contain multiple values set from the outside. (Values are of the same type.)
Example of property name and contained items:

```<code>KnownHidScanners

"\\?\ACPI#IDEA0100#4&b74a345&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}"
"\\?\HID#VID_045E&PID_071D&MI_00#9&e6a1767&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}"
</code>```

Is there a standard approach in .NET for data type of such a multi-value class property?

When searching MSDN for multi-value property, I can find Properties with Multiple Values concept article which suggests PropertyValueCollection data type. But if you check the data type closer, it is too tightly related to ActiveDirectory.

Off hand I can implement property as

array of type

collection of type

list of type

but which one is the most used approach in out-of-the-box .net objects when they need multiple-value properties?  I'm not long enough with .NET ecosystem to observe what is generally used.

Note: this is not an opinion-based question. I'm asking developers who are long enough with the framework which approach is already used so I can get consistent with standards.

Edit: clarity was improved after first answerer wrote he misread the question

答:
For a property that with string values like that, I would have:

```<code>List<string> KnownHidScanners = new List<string>();
</code>```

However, if you're going to expose this property externally as an API, there is:

```<code>ICollection<string> KnownHidScanners = new List<string>();
</code>```

or more appropriately is to create your own type that inherits from ICollection like:

```<code>public class ScannerCollection : ICollection<string>
{
    //Class definition and implementation of ICollection<T>.
}
</code>```

See ICollection(T) Interface documentation.

If you are exposing the property externally, but you don't want the user to be able to modify the collection, you should then use the ReadOnlyCollection(T) class like:

```<code>ReadOnlyCollection<string> KnownHidScanners = new ReadOnlyCollection<string>(myPrivateListOfScanners);
</code>```

Body:
For a property that with string values like that, I would have:

List<string> KnownHidScanners = new List<string>();

However, if you're going to expose this property externally as an API, there is:

ICollection<string> KnownHidScanners = new List<string>();

or more appropriately is to create your own type that inherits from ICollection like:

public class ScannerCollection : ICollection<string>
{
    //Class definition and implementation of ICollection<T>.
}

See ICollection(T) Interface documentation.

If you are exposing the property externally, but you don't want the user to be able to modify the collection, you should then use the ReadOnlyCollection(T) class like:

ReadOnlyCollection<string> KnownHidScanners = new ReadOnlyCollection<string>(myPrivateListOfScanners);


答:
With modern .NET / C# we try to use generics. Check out System.Collections.Generic namespace

I recommend List<T> until you find something it doesn't do for you.

If you need random access of more than 3 values, go with a Dictionary<K,T>

For a small number of values where you always know where they are, you can use Tuples (such as a 3D coordinate, or a complex key, if there wasn't another data structure to use)

Title: .NET Framework standard container type for multi-value property?

Body:
I'd like to create a simple class property which can contain multiple values set from the outside. (Values are of the same type.)
Example of property name and contained items:

```<code>KnownHidScanners

"\\?\ACPI#IDEA0100#4&b74a345&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}"
"\\?\HID#VID_045E&PID_071D&MI_00#9&e6a1767&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}"
</code>```

Is there a standard approach in .NET for data type of such a multi-value class property?

When searching MSDN for multi-value property, I can find Properties with Multiple Values concept article which suggests PropertyValueCollection data type. But if you check the data type closer, it is too tightly related to ActiveDirectory.

Off hand I can implement property as

array of type

collection of type

list of type

but which one is the most used approach in out-of-the-box .net objects when they need multiple-value properties?  I'm not long enough with .NET ecosystem to observe what is generally used.

Note: this is not an opinion-based question. I'm asking developers who are long enough with the framework which approach is already used so I can get consistent with standards.

Edit: clarity was improved after first answerer wrote he misread the question


问:
Inter-aggregate commands/transactions in an eventual consistency manner
I am trying to model a business transaction that operates on two aggregates. Let's say we have a Bag aggregate type that contains Items (entities). I would like to have a command TransferItemToBag(itemName: String, fromBag: BagId, toBag: BagId) which extracts an item from the first Bag and puts it to the second one. When this command is received, I want to send a command AddItemToBag(...) to the second bag and when it responds with ItemAddedToBag(...) send RemoveItemFromBag(...).

In other words, I would like to create a command in the system that does what user can do with the two other commands, sending them one by one. Pseudocode:

```<code>on(FirstSecondCombinedCommand cmd) {
   eventBus.register(eventType=FirstEvent, {
       aggregate = repository.ofId(cmd.id2)
       aggregate.handle(SecondCommand(...))
   })

   aggregate = repository.ofId(cmd.id1)
   aggregate.handle(FirstCommand(...))   // produces FirstEvent
}
</code>```

Where does this logic belongs to? Please notice I don't want to have a strong consistency, rather eventual one. I am also ok if the transaction is interrupted because there was a different competing command in between that came to one of the aggregates. I considered several possibilities:

Aggregate - the command is only about a single aggregate type, so the rule of thumb for choosing a place for a business logic (aggregate/entity vs domain service) suggests me to go with that. On the other hand it means the command handler in the aggregate needs to be able to produce commands. It may violate a rule of single aggregate mutation within a transaction/command but what if it done asynchronously to avoid it? I mean posting the command on some kind of Command Bus and let it be dispatched later, maybe by a different thread.

Saga - the situation is in fact a kind of a (long) running process and that made me think about Sagas for the implementation. On the other hand I was always considering Sagas as something stateful. I don't see an explicit state in my situation.

Application Service - I have seen in IDDD that it is a place for setting up listeners and invoking various commands but still the situation I am describing is a part of a business logic for me and I would like to keep it in the domain.

Domain Service - the last possibility I can think of. Seems to be a reasonable place for inter-aggregatetype stuff, but what if we have the same aggregate type?

Please do not focus on this concrete example of aggregates (it is devised). I am interested in a generic answer where to put such "transaction" code.

答:
You're not going to like the answer. It depends. In the case of your simple transaction, you might as well let the Aggregates interact together.

But if it's possible that the interactions involve a number of aggregates (and hence a number of commands and events), your best bet would be to use a Saga. This lets you keep the process in one location, making it easier to update the workflow when the need arises. This would also make it easier to follow the workflow instead of having to trace it across several aggregates. Microsoft worked with a lot of luminaries within the DDD/CQRS community to create a nice blueprint of the approach, their discussion on sagas (which they rename process managers) is worth reading.


问:
How common is prototyping as the first stage of development?
I've been taking some software design courses in the past few semesters, and while I see the benefit in a lot of the formalism, I feel like it doesn't tell me anything about the program itself:

You can't tell how the program is going to operate from the Use Case spec, even though it discusses what the program can do.

You can't tell anything about the user experience from the requirements document, even though it can include quality requirements.

Sequence diagrams are a good description of how the software works as the call stack, but are very limited, and give a highly partial view of the overall system.

Class diagrams are great for describing how the system is built, but are utterly useless in helping you figure out what the software needs to be.

Where in all this formalism is the bottom line: how the program looks, operates, and what experience it gives? Doesn't it make more sense to design off of that? Isn't it better to figure out how the program should work via a prototype and strive to implement it for real?

I know that I'm probably suffering from being taught engineering by theoreticians, but I need to ask, do they do this in the industry? How do people figure out what the program actually is, not what it should conform to? Do people prototype a lot, or do they mostly use the formal tools like UML and I just didn't get the hang of using them yet?

答:
In the business world, it matters a-lot

I too use to think that, until you hit the business world. Then its no longer simple enough to just take requirements and go forth and build.

Its in business that user "flow" diagrams, and lo-fi prototypes really make sense.

How the "program" operates is probably the easy part. In LOB (Line Of Business) apps, most of it is just CRUD. The challenge lies in the business logic and rules. This is where user flow diagrams and business process flows become extremely important in order to understand and plan effectively.

ContentLicense: CC BY-SA 2.5


问:
Establish connection between parent and child class
Assume you have two classes, a Manager who holds a set of Clients and the Client holds a backreference to the Manager.

```<code>class Manager {
public:
    void addClient(Client* client) {
        m_clients.push_back(client);
        client->setManager(this);
    }
private:
    std::list<Client*> m_clients;
};

class Client {
public:
    void setManager(Manager* manager) {
        m_manager = manager;
    }

private:
    Manager* m_manager;
};
</code>```

The confusing, probably even dangerous feature of this API is that Client exposes a setManager() method that can be called by anyone, yet should only be called by the Manager::addClient() method.

assert(manager->hasClient(this)) in setManager() would prevent wrong calling at runtime, however I would prefer a solution that doesn't allow the user to call methods he isn't supposed to call.

What would be common solution? I don't

want to use friend to expose all of Clients members to Manager so that he can establish the binary connection in addChild()

want both classes to share some kind of Composite base class. They should remain unrelated inheritancewise.

答:
One fairly standard approach would be to make Client::setManager protected and declare Manager::addClient as a friend function in Client. This will allow Manager::addClient access to all of Client's private and protected members, not just Client::setManager, but is more encapsulated overall than a public Client::setManager.

See also:

Specify a class member function as a friend of another class?

What is the use-case to use C++ friend class?

Should I use friend classes in C++ to allow access to hidden members?

When should you use 'friend' in C++?

How does the friend keyword (Class/Function) break encapsulation in C++?


问:
Fixing bad data in a database - redo or incremental
I have pseudo-ownership of a fairly old db (original data from 30 years ago; current design is >15 years old). In my opinion, the schema is pretty broken, and one of the implications of this is that there are a lot of inconsistencies/issues with the data. I'm planning to write a new schema and port the data across, which is a fairly simple task as new data comes in rarely.

Would you attempt to fix the inconsistencies in the old database first, or iron them out as part of the migration process? I'm tempted to go with the latter - since I'll need proper validation anyway, and some errors will pop out naturally with the different schema design - but fixing the data first would break the task into smaller chunks and allow people familiar with the old db to validate the fixes.

Thoughts?

答:
Your latter strategy is likely the better choice. It will be difficult to find all the problems in the data while it is still resting in its current format.

I would treat this an ETL process of sorts, combined with an iterative approach. Something like this:

Build a beta version of the schema.

Write a program to read the old data, scrub/transform it, and finally load it to the new schema. Log any new and unexpected problems with the data that your program's scrub/transform logic and/or the schema can't handle.

Review problems detected in step #2 and change the schema and/or ETL program.

Delete all the saved data

Run the revised program against the revised schema.

Lather rinse, and repeat until you and the data experts are comfortable with the schema design and transformed data. Move data to production.

Edit

If the data experts are concerned about what will happen during the transform process, make extra effort to keep an open dialog going with them concerning what you are seeing in the data and how they want to you to handle it.

This process will likely be a great way to clarify what the business rules and logic are for the data. As the load program attempts to confirm the data to these rules, it may discover problems with the data that no one knew even existed. It may also discover previously unknown scenarios that require new rules. The end result is both better data and a better understanding of what it can tell you.


问:
Proper Model-View-_____ design
I've been reading up about Model View Controller, Model View Presenter, Model View ViewModel, and so on, and generally, the underlying concept seems pretty simple to understand: keep the pretty visuals and sciencey guts as separate and ignorant of each other as possible. No getting the logic peanut butter in the design chocolate; cool, I like that.

The problem is I'm still a bit fuzzy as to that third part... the not-model-or-view one. Everyone seems to have their own idea of what to call it, what it should do, what's proper, what's just plain wrong... and I'm going nuts trying to figure out when a Presenter becomes a ViewModel and when a View shouldn't be doing that because that's the Presenter's job and--

I'm rambling.

Rather than asking for someone to explain the difference between them--because that's already been done time and time again (I know; I've read more articles than I can count)--I'd be curious to hear the thoughts of a few programmers on the model I've cobbled together myself.

That said, what would you classify this design as, and perhaps more importantly, do you see anything about this that obviously sucks? Sure, I'd love to hear I'm doing good if this truly is solid design, but I'd much rather be given solid advice over praise.

Note: I'll be using "the Bridge" for the mysterious third part of Model-View-? to avoid any subconscious suggestions of what it "should" be.

Model

Is the authority on data.

Receives information about requested changes from the Bridge.

Contains and performs all logic for how data relates to other data.

<s>Informs the Bridge when data changes (for data the Bridge has expressed interest in).</s> Wording edit: Allows outside subscribers (about which it knows nothing) to monitor it's state or calculation results.

Has zero knowledge of the View.

View

Is concerned with providing the user a way to view and manipulate data.

Receives information about data updates from the Bridge.

Contains and performs all logic for how to present data and controls to the user.

Informs the Bridge when the user has performed an action that (possibly) affects the Model.

Informs the Bridge what information it's interested in.

Has zero knowledge of the Model.

Bridge

Is the coordinator and translator between the Model and the View.

Makes any appropriate formatting changes to information being passed between the Model and the View.

Retains information on "who needs to know what".

Has knowledge of both the Model and the View.

Additional Notes

In more complicated programs, it's common for there to be multiple Models. In this situation, the Bridge typically takes on the job of coordinating/translating between the multiple Models, and thus becomes the authority on what protocall/API/design Models should be built to. (e.g. if building a card game program, and you want to build an alternate deck shuffling model, you should use the Bridge for determining what functions are required for properly communication with the Bridge.)

In small simple programs with only one View and Model, it's common for the Bridge to "assume" what functionality is available on either side. However, as programs become more complex, it's recommended that the View(s) and Model(s) report their functionality to the Bridge so that it can avoid inefficiencies and buggy assumptions.

I think that just about covers it. By all means, I welcome any questions you might have about the design I tend to use, and I likewise encourage any suggestions.

And as always, thank you for your time.

答:
There is a lot of discussion in the programming community about this exact nomenclature. No one seems to agree about much of anything.

For me, how the bridge is wired to the view mostly determines the name.

If there can be a collection of views per bridge, then the bridge is a controller.

If there is always one view per bridge, then the bridge is a presenter.

If there can be a collection of bridges per view, then the bridge is a view model.

Sometimes things are not so clear cut. For example, a presenter could be connected to a composite view made of multiple subviews or a controller could be created without any knowledge of its views. Despite this, I think my rules are a good start.

As a side note, I like to pair down the responsibilities like this:

Model

Primary Responsibility: Persist data

Secondary Roles: Validate updates, notify observers of updates

View

Primary Responsibility: Present data

Secondary Roles: Accept input, present UX

Bridge

Primary Responsibility: Update data

Secondary Roles: Clean input, sync data and views

Title: Proper Model-View-_____ design


问:
DDD: placement of method whose behavior may be implemented with single database query
Let's say we have Book entity in our library. A requirement says:

Librarian may disable 'available' flag to books published before some year. For example, librarian may 'hide' some old books from being publicly available as they are rare.

This behavior is easily done with single SQL command. The method name for this behavior may be e.g. hideBooksPriorToYear().

But where to put this method?

if we put it in the Repository, soon it will be full of such methods; moreover, this is a business method, not a repo method.

we might fetch all old books and hide one by one, but this is slow.

we might create a business service for that, but that looks like anemic model again

we might put this method in a model, but I don't want to put sql there.

Any wisdom on this?

EDIT

Trying to clarify. When I try to move behavior to the entities methods, I found out that most of the business is not available without a repo. And I do not want to inject repo instance into the models. So my entities soon starts to be: 1) simple data objects, and 2) factories for entities/aggregates that are related to the model.

答:
In your particular case, as a rule of thumb, methods which operate on a single entity should be defined on the model itself, whilst those methods which operate on the entity collection as a whole should be defined on the service.

Methods such as getLatest, getMostPopular, getOutOfStock, deleteFromPublisher, deleteFromAuthor are all ideal candidates for being defined on the service in your architecture, since such queries would inspect all existing entities.

To contrast, methods such as delete, hide, setStock, setPrice should ideally be defined on the model itself, since you would utilize these on a particular entity which you have in the current context.

Your concern that you might end up with a lot of such methods on the service is subjective. From the perspective of maintenance, there are ways to deal with this should it become unbearable, but it still doesn't change the fact that these should be qualified from the service object itself.


问:
Should I bother to develop for JavaScript disabled?
Should I bother to develop for JavaScript disabled?

I feel that my time is better spent developing for the majority.

答:
It depends on the site and who will be using it.

Is the site public or is it an intranet or a site that will only be available to certain customers? You will probably encounter users without JavaScript in the public. If it will only be used by clients can you tell them you only support JavaScript enabled?

Is SEO a consideration or is the entire site behind a log-in screen or SEO is it otherwise not a factor? It is much easier to optimize for search engines if there's no JavaScript.

Will the site ever be used on mobile browsers? Mobile browsers often have no or poor JavaScript support.

You should also realize that JavaScript can make it difficult for screen readers to process your site and has other potentially negative accessibility considerations.

Users of text based browsers (e.g. lynx) also have little or no JavaScript support.

You have to look at your site and your audience and decide if you need to support users who have JavaScript disabled. You also have to see if it's even possible not to use JavaScript. If you're making an advanced Web Application and need things like webcam and microphone support it may be impossible to not use JavaScript.

If you decide that you need to support users without JavaScript then you can still use JavaScript. You should just make the website still functional without it. This is called progressive enhancement, it should gracefully degrade if there is no JavaScript support.

If you decide to require JavaScript you should notify your users (using the  tag) that you are doing so.

Body:
It depends on the site and who will be using it.

Is the site public or is it an intranet or a site that will only be available to certain customers? You will probably encounter users without JavaScript in the public. If it will only be used by clients can you tell them you only support JavaScript enabled?

Is SEO a consideration or is the entire site behind a log-in screen or SEO is it otherwise not a factor? It is much easier to optimize for search engines if there's no JavaScript.

Will the site ever be used on mobile browsers? Mobile browsers often have no or poor JavaScript support.

You should also realize that JavaScript can make it difficult for screen readers to process your site and has other potentially negative accessibility considerations.

Users of text based browsers (e.g. lynx) also have little or no JavaScript support.

You have to look at your site and your audience and decide if you need to support users who have JavaScript disabled. You also have to see if it's even possible not to use JavaScript. If you're making an advanced Web Application and need things like webcam and microphone support it may be impossible to not use JavaScript.

If you decide that you need to support users without JavaScript then you can still use JavaScript. You should just make the website still functional without it. This is called progressive enhancement, it should gracefully degrade if there is no JavaScript support.

If you decide to require JavaScript you should notify your users (using the <noscript> tag) that you are doing so.


答:
Okay, in the meantime I've invested additional time and made my own study on the topic.

Findings:

checking through Object inspector how properties containing word "Items" are declared in existing libraries reveals somewhat a surprise – I found every form: array, collection, list and custom types

dominant types are these two: collections (generic or inherited) and lists (mostly generic)

answers in this question shed light when to prefer collection and when list. The key is in character of the class: collections are recommended for exposed classes (API etc.), lists are more preferred for internal implementation stuff

here must be noted that Collection<T> is no longer part of System.Collections.Generic since .NET .3.5., it's been moved to System.Collections.ObjectModel

if property will have some obvious benefit from some specific type, then ignore the above recommendation and use that type. Example is out-of-the-box String.Chars which is an array.

defining custom multi-value container type (with item list based on some of the above) has its place if I want to add some custom properties/methods to items or for manipulation with the list etc.

some Property design guidelines are also available from the Microsoft, but for this topic they are not very helpful


问:
What is the actual reason that locks (sentinels) in OO are hard to reason about?
In this talk, Rich Hickey introduces Clojure. He gives an Ants demo and talks about his motivations for implementing a Software Transactional Memory (STM) system.

His reasoning for STM is that "locks are hard to reason about".

I took that to mean that the deadlock situation, where two threads are trying to update the same item and they hold resources that the other thread needs.

So to be atomic one thread has to roll back and retry and the other has to roll forward.

To make this work in an Object Oriented Language, you have to either use an STM framework or roll it yourself by hand.

That's my understanding, but I suspect I've only covered one problem case and I would imagine there is a more general principle that I'm missing. Perhaps the issue is that locks don't compose or something.

My question is: What is the actual reason that locks (sentinels) in OO are hard to reason about?

答:
It's not the locking that is hard to understand. Locks are easy. They work just like the locks in real life. It's the concurrency that's hard to understand.

The only reason locking makes people's head spin is that we only ever use it in concurrent systems. But imagine for a moment that we had a highly concurrent system with no synchronization whatsoever; the system's state would over time change to hilariously invalid configurations. Many of those configurations are just as hard to understand; they make people go "Huh? How on Earth could this ever happen?" The reason is that we are not built to understand the weird mix of simultaneous and and alternating changes that modern time-slicing systems yield. Little else in real life works that way, so our brains have a really hard time with it.


问:
Software engineering - "Precious project" syndrome?
I recently failed three projects with a similar pattern:

I had to work on each of them alone

With time I started to take the project too personally, like it is my spiritual child, and I tried to make it perfect

Soon my progress slowed to a halt, and effected everyone, which in turn made me feel more guilty and desired to make things even more perfect!

Eventually I had to drop it in shame.

I want to ask if there's anyone who have suffered the same:

How do you overcome it?

If you absolutely cannot work on a solo project then how do you explain it to your boss so that it doesn't seem like you're incompetent?

答:
One thing I could suggest from my own experience is to have a clear "definition of done" for every task you are working on.
Although this term comes mainly from the scrum environment (see a description here) it could also be helpful to adopt it when working alone on a project.

The main idea is that you define clear, measurable criteria that describe when a given task is completed.
But the important thing is that it also works the other way round:
As soon as the criteria are reached, the task is considered done and no more work should be spent on this specific task.
If you still think you could polish or tweak things a bit more up, define a new task (maybe with a lower priority) and define exactly what and how you want to polish this (again with clear acceptance criteria). But start this new task only after you have finished all other tasks with a higher priority.

In that way you could ensure that you do only the work which needs to be done to get the program to work.
Sure this might even mean that the software is not yet perfect but it doesn't matter, at least it does what it should, and improvements can be done after that.

If your project has at least a product owner (or a person with an equivalent role) you both could sit together and define the DODs for every tasks together.


问:
How to avoid long call chains?
I have a hierarchy of objects, mostly connected by composition. I.e. (not showing the class methods for readability):

```<code>class A {}
class B {A a;}
class C {B b;}
etc...
class Z {Y y;}
</code>```

class Z provides the API for executing commands from another program - a control panel. I think this is called Chain of Responsibility, but might be at an error.

Now when an action on A needs to be performed, Z calls a method of Y, because Z knows only about Y. So on, until we reach A, which has the proper members and methods to handle the request.

This has the fundamental problem that debugging becomes tedious - one has to step in many times, and each time be careful not to miss the actual working method - otherwise the debugging session needs to be restarted.

How do I make debugging more straightforward? A change in the architecture of a method of using gcc that is more suited to this situation?

答:
Use logging. (I don't know what are logging options in c++, but i would be surpirsed if there wasn't something close to what is available in Java).

Log entering and exiting method and what is going in/out (and either do it in configurable automatic way, or only in interesting places). This way you know where it went and if you can formulate postconditions and preconditions, you can check them when going through logs to find where something strange is happening and then put breakpoint to the right place.

When same method is called repeatedly and only after log run it breaks down on border case, you can use conditional breakpoint, because you know (from logs) what data causes problem.

This will require multiple runs to examine problem, but log run will be without manual steping, so much faster, and in debug run you will start closer to actuall problem (or at least its closer to its manifestation.

Title: How to avoid long call chains?


答:
The particular issue with OOP and concurrency is that often programmers are tempted to try to hide thread safety implementation away using encapsulation.

When this is done by baking locks right into objects, then it is almost always a leaky abstraction, because of the side effects that locks cause.

If you have a lot of these hidden locks, then you're unlikely to run into race conditions, but it becomes really easy to get deadlocks (which arguably themselves are actually just race conditions, but I think you get my point). So then you have to reason about the order in which you call certain methods to avoid deadlocks. Not easy to reason about. And the encapsulation you wanted simply isn't there.

Or you use locks more sparsely, which makes it easier to avoid deadlocks. But it's also hard to reason about where the locks should be put to avoid weird/unexpected behavior. That also means that you will all too often have to intimately couple the implementation of an object to when (as opposed to just how) it is going to be interfaced by the outside world. So there's also no real encapsulation.

So it's not that having objects makes dealing with concurrency harder. It's that trying to have object deal with concurrent access to them makes dealing with those objects harder. You can always, for example, have a model that is not the least bit thread safe, and just guarantee that all interaction is routed through a facade that deals with thread safety (e.g. through a reactor pattern). Then said facade has the single responsibility of dealing with concurrency.

Body:
In this talk, Rich Hickey introduces Clojure. He gives an Ants demo and talks about his motivations for implementing a Software Transactional Memory (STM) system.

His reasoning for STM is that "locks are hard to reason about".

I took that to mean that the deadlock situation, where two threads are trying to update the same item and they hold resources that the other thread needs.

So to be atomic one thread has to roll back and retry and the other has to roll forward.

To make this work in an Object Oriented Language, you have to either use an STM framework or roll it yourself by hand.

That's my understanding, but I suspect I've only covered one problem case and I would imagine there is a more general principle that I'm missing. Perhaps the issue is that locks don't compose or something.

My question is: What is the actual reason that locks (sentinels) in OO are hard to reason about?


答:
As Churchill famously remarked, "the maxim 'nothing avails but perfection' may be spelt shorter: p-a-r-a-l-y-s-i-s".

You need to internalize the notion that this approach is unprofessional.

Or, as Jamie Zawinski put it (in "Coders at Work", recommended by Joel Spolsky once), "At the end of the day, ship the fucking thing! It’s great to rewrite your code and make it cleaner and by the third time it’ll actually be pretty. But that’s not the point—you’re not here to write code; you’re here to ship products."

And that contains an important observation. The job of a programmer is not to write code! It is to solve problems. If a problem can be solved by not writing a line of code, or even by deleting code - all the better.

See your job as one of a problem-solver, who only happens to be a coder. Not the other way round. A shift in priorities follows organically.

I am suffering from the same syndrome, but I cope with it by doing hobby projects, in which I have no deadline and I have my own little perfect world. (And yes, they typically end up paralysed by perfectionism). But at least thanks to that I'm venting off from all the rotten compromises I have to make at work, and everybody's happy :)

Thus my advice would be: try to write perfect programs in your spare time. You will learn that you're chasing a mirage and it's not worth it. Or you may get addicted to the thrill of chasing this mirage, but since it's your spare time, your professional reputation won't be exposed to risk, and you won't feel so perfection-hungry at your pragmatic, day-to-day work. Or perhaps you'll actually learn to write perfect programs in finite time. Either outcome is good!

If you absolutely cannot work on a solo project then how do you
  explain it to your boss so that it doesn't seem like you're
  incompetent?

Sorry to say that, but it wouldn't only seem so. It is a form of incompetence, fortunately one that can be dealt with fairly easily.

Title: Software engineering - "Precious project" syndrome?

Body:
I recently failed three projects with a similar pattern:

I had to work on each of them alone

With time I started to take the project too personally, like it is my spiritual child, and I tried to make it perfect

Soon my progress slowed to a halt, and effected everyone, which in turn made me feel more guilty and desired to make things even more perfect!

Eventually I had to drop it in shame.

I want to ask if there's anyone who have suffered the same:

How do you overcome it?

If you absolutely cannot work on a solo project then how do you explain it to your boss so that it doesn't seem like you're incompetent?


答:
It is not clear from the question if the projects were actually released at some point or were they abandoned before the first release.

In the latter case it's clear that a change in mindset is needed. We engineers would always like to perfect our product and feel uneasy when we need to release something that still has lots to improve. But this is exactly what needs to be done. You need to release early and release often and accept the fact that the first version will be painfully bad. This is the only way to write quality software that actually solves the problems your users wan't to get solved.

It might also be beneficial for you to familiriaze yourself with the concept of Minimum viable product and perhaps even read the Lean Startup book from Eric Ries.


答:
I don't have any experience with STM but I'll address the locking part.

Getting single threaded code right is hard. It's pretty telling that the prevalent methodology is to create a large battery of unit tests and hope that if they all pass, nothing is wrong. For code that won't result in loss of life or billions of dollars, that's a reasonable approximation, but the point I'm trying to make is that proving code correct is hard. Harder than most people are willing to put effort into.

Now consider concurrent code using locks. To prove it works, you have to prove that you've manually synchronized the threads properly for every possible interleaving/scheduling. That's a monumental task. And if you screw up, because the code is non-deterministic, the buggy behavior is non-deterministic too! It's not unlike manual memory management, except that tracking resources in single-threaded code is easier (yet still too hard to get right).

Even worse code that uses locks isn't composable. Suppose you have two collections, and you make every operation on them thread-safe. Now suppose you want to remove an item from one collection and add it to the other. Just because removing the element is thread-safe and adding the element is thread-safe it doesn't mean the entire operation is thread-safe. If you wrote the code for the thread-safe collections and your coworker is the one that has to write the program, it's on them to make sure whatever combination of actions they do is safe. Contrast that with the single-threaded scenario, where proving that the insertion and deletion code is correct also proves that moving an element between collections is correct. Also compare to manual memory management, where freeing allocated memory is the function caller's job.

I'm not really sure how OO fits into this. Lock-based concurrency is hard no matter what paradigm you choose.

Title: What is the actual reason that locks (sentinels) in OO are hard to reason about?


答:
It has nothing to do with OO in particular. The problems are problems with the "explicit locking" paradigm as an approach to concurrency, regardless of other paradigms used in other parts of the problem.

I haven't watched that two hour talk, so I won't comment on Hickey's reasoning. Here are the criticisms of locks I hear most commonly, summarized:

Locks are not composable. If you have two pieces of code A and B that work correctly (in particular, atomically) on their own, you can't write A; B to perform the two actions together, atomically. At least not without either mucking around with the locks A and B use (which are often private, for good reasons) or introducing yet another lock and introducing it everywhere it needs to be adhered to.

Locks, as usually implemented, are not formalized in what they protect and when they must be acquired. If the system is any good, it will be documented, but programmers get no automated assistance in adhering to the rules.

Locks are low-level. To properly understand their interactions and what they mean for synchronization, you have to consider all possible ways the concurrent executions might interleaving, and all possible ways code might be reordered. Flow-dependent reasoning is already tricky for a single thread of execution, but concurrency makes the number of paths to consider explode.

Functional programming advocates like to argue that OOP also needs far more synchronization because it uses far more shared mutable state, but this is beside the point here. How much synchronization is needed is orthogonal to how you choose to synchronize.


问:
Is there any hard data on the (dis-)advantages of working from home?
Is there any hard data (studies, comparisons, not-just-gut-feel analysis) on the advantages and disadvantages of working from home?

My devs asked about e.g. working from home one day per week, the boss doesn't like it for various reasons, some of which I agree with but I think they don't necessarily apply in this case.

We have real offices (2..3 people each), distractions are still common. IMO it would be beneficial for focus, and with 1 day / week, there wouldn't be much loss at interaction and communication. In addition it would be a great perk, and saving the commute.

Related: Pros and cons of working remotely / from home  (interesting points, but no hard facts)

To clarify: it's not my decision to make, I agree that there are pro's and con's depending on circumstances, and we are pushing for "just try it". I've asked this specific question because (a) facts are a good addition to thoughts in arguing with an engineer boss, and (b) we, as developers, should build upon facts like every respectable trade.

答:
Just make a google search about the rates of depression among people who spend a lot of time home.

There have been studies about the different distractions available at home (like the internet, or even sleeping) that show a direct correlation between the onset of depression, and the reduction of outside contact. Without mentioning the studies about how the loss of sunshine affects the brain and eases the mind into a state where it can easily get depressed.

There are studies out there. Problem is most people do not pay attention to them, and they later find themselves visiting psychiatrists for no other reason than to get a fix for a problem they did not need to have in the first place.

I'm not saying you will experience such symptoms. I assume that you are a normal, and well adjusted individual with a strong moral and principles base. So, I'm just warning you against of what possibilities may lay ahead.

Also, how would you escape from work?

```<code>if home = work
then what?
</code>```

Where would you go to escape from work?

The toilet?

Body:
Just make a google search about the rates of depression among people who spend a lot of time home.

There have been studies about the different distractions available at home (like the internet, or even sleeping) that show a direct correlation between the onset of depression, and the reduction of outside contact. Without mentioning the studies about how the loss of sunshine affects the brain and eases the mind into a state where it can easily get depressed.

There are studies out there. Problem is most people do not pay attention to them, and they later find themselves visiting psychiatrists for no other reason than to get a fix for a problem they did not need to have in the first place.

I'm not saying you will experience such symptoms. I assume that you are a normal, and well adjusted individual with a strong moral and principles base. So, I'm just warning you against of what possibilities may lay ahead.

Also, how would you escape from work?

if home = work
then what?

Where would you go to escape from work?

The toilet?


答:
When you split up big methods into smaller ones, and separate concerns to many classes, and write more functions with clearly separated levels of abstraction, you will end up with long call chains, that's true. But when you choose your abstractions well your code becomes much more readable and understandable than the typical 200 lines-of-code-spagetthi function.

And readable code avoids a lot of bugs at first hand, so to my experience this outweighs the increased debugging efforts caused by the call chains by a multitude. So my advice is: live with it. Don't use this "long call chains make debugging harder" argument as an excuse for not refactoring your code into smaller functions, such reasoning leads always to a fallacy.

As a hint for debugging when you accidentally missed the cause of an error: some debuggers (like gdb) allow you to "undo" your last steps in the middle of a debugging session.

Title: How to avoid long call chains?

Body:
I have a hierarchy of objects, mostly connected by composition. I.e. (not showing the class methods for readability):

```<code>class A {}
class B {A a;}
class C {B b;}
etc...
class Z {Y y;}
</code>```

class Z provides the API for executing commands from another program - a control panel. I think this is called Chain of Responsibility, but might be at an error.

Now when an action on A needs to be performed, Z calls a method of Y, because Z knows only about Y. So on, until we reach A, which has the proper members and methods to handle the request.

This has the fundamental problem that debugging becomes tedious - one has to step in many times, and each time be careful not to miss the actual working method - otherwise the debugging session needs to be restarted.

How do I make debugging more straightforward? A change in the architecture of a method of using gcc that is more suited to this situation?


问:
What to do about "stopping point syndrome"?
I have noticed a behavior in myself that I call "stopping point syndrome"... it means I cannot stop working until I reach a "stopping point" (or I become exhausted).  In other words, if I am in the zone working on getting a feature completed, I won't stop until I get it done.   If it's a bug I'm working on, this effect is even more pronounced... I won't stop until it's fixed, or at the very least, understood.  Even though I work from a laptop and have VPN and could easily go home and pick up on the work later that evening, that fact does not help me leave work... it's like I'm afraid I will die before I find the bug.

I have a very hard time explaining this to family members who can't figure out why I never come home from work at the same time and sometimes come home at 11 pm.  Even managers have been mystified by this, and I've noticed that most of my colleagues have no trouble working the same hours every day.

Does anyone else have this problem?  Should I be worried about this and/or try to change it?  If so how?

答:
If you have a family, this is a no-brainer.

If I leave work at 5pm, the code will be exactly as I left it when I get in tomorrow.

If I leave work at 10pm, my son will already be in bed when I get home and I won't have given him a hug or seen him show off any of the things he learnt that day.  And my wife will be cranky because she's had to work her ass off all day with no help.

But if you are single and are not overly interested in the 'social scene', then go nuts!

Keep in mind though that the work you do at 9pm will probably be of a lower quality than the work you do at 9am.  Don't underestimate the advantage of being well rested and having a clear mind.


问:
DDD: Global unique identities vs surrogate
Let's start with an example: we have an entity: Book. It has unique identity: Isbn - a value object that wraps a String. This is an UUID.

The Book entity also needs a surrogate id from the repo (sql db). We need it so we can e.g. find the books in faster way, since databases find by number faster then by string.

From what I read, the surrogate key should be hidden from the Books interface. But we want to use it, to locate books much faster.

How to deal with this in a proper way?

[A] We can simply add a getSurrogateId() (or any better name) in the Book. This pollutes the entity, but its KISS.

[B] We can have the repo responsible for finding the surrogate keys for the natural ones. For example, BookRepository may have the following method:

```<code>long toSurrogateKey(Isbn isbn) {
     // lookup the cache
     // if not found, lookup the db
}
</code>```

to return the surrogate key - of course, these values can be cached locally, so we do not need to search db every time. This method should not be public (right)?

[C] We can go even further: to think about surrogate key as a repository specific one. Book may be an interface, and SqlBook may be an repository-made implementation. This SqlBook implementation may then store any additional information needed for the repository. In this case, we would have the surrogate key as one of the properties of SqlBook - and we do not care it is visible, as users of SqlBook only sees it as a Book, i.e. not knowing about the surrogate id.

So above method becomes (defined in SqlBook class):

```<code>long toSurrogateKey(Book book) {
     return ((SqlBook)book).getSurrogateId();
}
</code>```

The only drawback here is that Book (and other entities) must be created by a Factory that is repository-aware. In other words, we would need to have SqlFactory implementation of some factory that creates SqlBooks for us.

Any wisdom on this?

答:
We need it so we can e.g. find the books in faster way, since databases find by number faster then by string.

Surrogate keys should primarily be added because they provide you a uniform way for building your primary keys, not because of any hypothetical performance issues. They will help you to avoid having business data like an Isbn distributed over half of your model in separate places because you misuse them as foreign keys.

"From what I read, the surrogate key should be hidden from the Books
  interface".

Maybe you just misunderstand the purpose of this? Surrogate keys are technical details which should be hidden when discussing the model with your domain experts, but it is perfectly ok to see them when you change your viewpoint to the implementation of the model. So go with [A], but make sure the getSurrogateId() accessor is not visible in your graphical form of your domain model.


问:
Are DDD Aggregates really a good idea in a Web Application?
I'm diving in to Domain Driven Design and some of the concepts i'm coming across make a lot of sense on the surface, but when I think about them more I have to wonder if that's really a good idea.

The concept of Aggregates, for instance makes sense.  You create small domains of ownership so that you don't have to deal with the entire domain model.

However, when I think about this in the context of a web app, we're frequently hitting the database to pull back small subsets of data.  For instance, a page may only list the number of orders, with links to click on to open the order and see its order id's.

If i'm understanding Aggregates right, I would typically use the repository pattern to return an OrderAggregate that would contain the members GetAll, GetByID, Delete, and Save.  Ok, that sounds good.  But...

If I call GetAll to list all my order's, it would seem to me that this pattern would require the entire list of aggregate information to be returned, complete orders, order lines, etc... When I only need a small subset of that information (just header information).

Am I missing something?  Or is there some level of optimization you would use here?  I can't imagine that anyone would advocate returning entire aggregates of information when you don't need it.

Certainly, one could create methods on your repository like GetOrderHeaders, but that seems to defeat the purpose of using a pattern like repository in the first place.

Can anyone clarify this for me?

EDIT:

After a lot more research, I think the disconnect here is that a pure Repository pattern is different from what most people think of a Repository as being.

Fowler defines a repository as a data store that uses collection semantics, and is generally kept in-memory.  This means creating an entire object graph.

Evans alters the Repository to include Aggregate Roots, and thus the repository is amputated to only support the objects in an Aggregate.

Most people seem to think of repositories as glorified Data Access Objects, where you just create methods to get whatever data you want.  That doesn't seem to be the intent as described in Fowler's Patterns of Enterprise Application Architecture.

Still others think of a repository as a simple abstraction used primarily to make testing and mocking easier, or to decouple persistence from the rest of the system.

I guess the answer is that this is a much more complex concept than I first thought it was.

答:
Your domain model contains your business logic in its purest form. All the relationships and operations that support business operations. What you're missing from your conceptual map is the idea of the Application Service Layer the service layer wraps around the domain model and provides a simplified view of the business domain (a projection if you will) that allows the Domain model to change as needed without directly impacting the applications using the service layer.

Going further. The idea of the aggregate is that there is one object, the aggregate root, responsible for maintaining consistency of the aggregate. In your example, the order would be responsible for manipulating its order lines.

For your example, the service layer would expose an operation like GetOrdersForCustomer that would only return what's needed to view a summary listing of the orders (as you call them OrderHeaders).

Finally, the Repository pattern isn't JUST a collection, but also allows for declarative queries. In C# you can use LINQ as the Query Object, or most other O/RMs provide a Query Object specification as well.

A Repository mediates between the domain and data mapping layers,
  acting like an in-memory domain object collection. Client objects
  construct query specifications declaratively and submit them to
  Repository for satisfaction. (from Fowler's Repository page)

Seeing that you can create queries against the repository, it also makes sense to provide convenience methods that handle common queries. I.e. if you just want the headers of your order, you can create a query that returns just the header and expose it from a convenience method in your repositories.

Hope this helps clarify things.


问:
Interface to enumerate over files
I'm trying to design a generic interface for enumerating over a list files. Each iteration will open a file, allow the consuming code to access the file to perform some task, and then close the file.

At first this seemed like like a simple enumeration pattern, but the consuming code actually needs to know the status of each file both after it is opened and after it is closed. So rather then having a single MoveNext() method my interface has OpenNextFile() and CloseCurrentFile() methods, each of which may return a failure status. In addition, CloseCurrentFile() needs a way to report whether each file was saved or not when it was closed.

Here's my current interface.

```<code>public interface IFileEnumerator
{
    //The following properties reflect the current state of the IFileEnumerator
    FileEnumeratorStatus Status { get; }
    string StatusMessage { get; }
    string FileName { get; }
    byte[] FileData { get; }

    //Attempts to open the next file
    FileEnumeratorStatus OpenNextFile();

    //Closes the current file
    FileEnumeratorStatus CloseCurrentFile();
}

public enum FileEnumeratorStatus
{
    AtStart, //Files have not been opened
    Opened, //File currently opened
    Opened_Failed, //Failed to open file
    Close_Saved, //File closed and saved
    Closed_NotSaved, //File closed and not saved
    Close_SaveFailed, //File closed saving failed
    AtEnd //No more files
}
</code>```

Here's an example of the consuming code:

```<code>//FileProcessor is a class which run a ProcesssJob on a set of files returned by a
//IFileEnumerator and returns a ProcesssingJobResult with results of all the files
public class FileProcessor
{
    public ProcesssingJobResult RunJob(IFileEnumerator fileEnumerator, ProcesssJob job)
    {
        List<FileProcessingResult> resultList = new List<FileProcessingResult>();

        while (fileEnumerator.OpenNextFile() != FileEnumeratorStatus.AtEnd)
        {
            FileProcessingResult currentFileResult = new FileProcessingResult();
            currentFileResult.FileName = fileEnumerator.FileName;

            if (fileEnumerator.Status == FileEnumeratorStatus.Opened)
            {
                currentFileResult.JobCompleted = job.RunJob(fileEnumerator.FileData);

                var closureStatus = fileEnumerator.CloseCurrentFile();

                if (closureStatus == FileEnumeratorStatus.Close_Saved)
                    currentFileResult.Saved = true;
                else if (closureStatus == FileEnumeratorStatus.Closed_NotSaved)
                    currentFileResult.Saved = false;
                else if (closureStatus == FileEnumeratorStatus.Close_SaveFailed)
                {
                    currentFileResult.Saved = false;
                    currentFileResult.Message = fileEnumerator.StatusMessage;
                }
            }
            else if (fileEnumerator.Status == FileEnumeratorStatus.Opened_Failed)
            {
                currentFileResult.JobCompleted = false;
                currentFileResult.Message = fileEnumerator.StatusMessage;
                currentFileResult.Saved = false;
            }

            resultList.Add(currentFileResult);
        }

        ProcesssingJobResult jobresult = new ProcesssingJobResult();
        jobresult.TimeStamp = DateTime.Now.ToUniversalTime();
        jobresult.Machine = System.Environment.MachineName;
        jobresult.User = System.Environment.UserName;
        jobresult.Results = resultList;

        return jobresult;
    }
}

//A generic task that can be run on a file
public interface ProcesssJob
{
    bool RunJob(byte[] data);
}

//Result of processing one file
public class FileProcessingResult
{
    public bool JobCompleted { get; set; }
    public bool Saved { get; set; }
    public string FileName { get; set; }
    public string Message { get; set; }

}

//The overall result of processing a set of files
public class ProcesssingJobResult
{
    public DateTime TimeStamp { get; set; }
    public String Machine { get; set; }
    public String User { get; set; }
    public List<FileProcessingResult> Results { get; set; }
}
</code>```

Maybe this is just a question of careful documentation, but I'm having trouble dealing with all these different possible states. Drawing a state diagram doesn't help as it's possible to go from every state to just about every other state. Should the consuming code call CloseCurrentFile() if OpenNextFile() return Open_Failed? What if it does? Would a Closed status be returned even if a file was never opened? If CloseCurrentFile() was not called after OpenNextFile() should it be closed automatically by the next call to OpenNextFile() or should an exception be thrown? I'd rather someone implementing this interface not have to worry about getting all this right.

The problem is much simpler if I have a single OpenNextFile() method which is responsible for both closing the last opened file, and opening the next file. Yet then this single method needs to report both the result of opening the next file, as well as closing the last file. This also becomes tricky for consuming code as the final state of each file is not determined until the following iteration.

```<code>public interface IFileEnumerator_Alternate
{
    string FileName { get; }
    byte[] FileData { get; }
    string StatusMessage {get;}

    //Closes the previous file, and opens the next file
    Result OpenNextFile();
}

public class Result
{
    public bool CurrentFileOpened {get; set;}
    public string CurrentFileName {get; set;}
    public string CurrentFileStatusMessage {get; set;}

    public string LastFileName {get; set;}
    public bool LastFileClosedOk {get; set;}
    public string LastFileClosedStatusMessage {get; set;}
    public bool LastFileSaved {get; set;}
}
</code>```

Is there another way to look at this, or some other common design pattern that is more suited to what I'm trying to do? Here's an activity diagram showing the overall process.

答:
What if instead of using an interface I create an abstract class with abstract methods of each of these steps which concrete classes have to implement

Yes. An interface does not tell how the methods interact or how to process. That is just one technique for dependency injection.

Part of the problem is acquiring the list of files can be a long process. Each file may need to be downloaded, and opened to find nested contents etc..etc. So I want to do the processing as the files are being iterated over rather then opening them twice.

Document Facade

A general meta-data class & and associated "framework" with injectable custom equality and comparison functionality.

```<code>public class DocumentFacade : IEquatable<DocumentFacade>, IComparable<DocumentFacade> {
    // this class is more like document metadata, not necessarily a facade design
    // pattern wrapping the Document object itself
    protected EqualityComparer<DocFacade> equalizer;  // customized Equals, CompareTo

    public string Name { get; set; }
    // superset of any and all properties relevant to processing. Covers all
    // document sub classes.

    public DocStatus OpenStatus { get; set; }  // an enum
    public DocStatus CloseStatus { get; set; }
    public DocClass DocumentClass; // an enum, alternatively Type.Name, or even the Type object itself.

    public BaseDocClass theDoc;  //reference to the document this DocumentFacade represents
                                 // maybe you don't even need this.

   public DocumentFacade (IEqualityComparer<DocFacade> equalizer) {
       if(equalizer == null) throw new NullArgumentException();
       this.equalizer = equalizer;
   }

    public override bool Equals(object that) {
       if(that == null) return false;
       if(that.DocumentType != this.DocumentType) return false;
        return equalizer.Equals(this, other);
    }

    // the IEquatable implementation
    public bool Equals(this, y) {
        return Equals(y);
    }
}

// A class for each way we want to compare Documents; each sub-class I suppose.
// MSDN says inheriting is the way to go, vice interface implementation.
public class DocFacadeEqualizerTypeA : IEqualityComparer<DocumentFacade> {
    public override bool Equals (DocFacade x, DocFacade y) {
        // customized implementation
    }
    // ditto CompareTo override
}

public class DocumentFacadeCollection : List<DocFacade> {

    public bool Equals (DocFacade x, DocFacade y) {
        if(x == null) return false;
        return x.Equals(y);
    }

    // lots of inherited List stuff makes this class really handy.
    public DocFacadeCollection GetOpenStatus(DocStatus thisStatus) {
        Find( x => x.OpenStatus == thisStatus);
    }

    public DocFacadeCollection FindAllDuplicates (DocFacadeCollection otherList) {
         DocFacadeCollection duplicates = new DocFacadeCollection();
         duplicates.AddRange( this.FindAll( x => otherList.Contains( x )).AsEnumerable());
         return duplicates;
    }
}

public static class DocumentDNAAnalyzer {
    // this may be a factory, or perhaps more likely, the front of
    // of a Builder pattern implimentation
    // Besides a customized DocFacade object, we may also be able to
    // provide stuff for abstract template.

    public static DocFacadeFactory = new DocFacadeFactory();

    public static DocFacade Create(object TheDocument) {
        return DocFacadeFactory.Create(TheDocument));
    }
}
</code>```

See this thread for a great GetHashCode() Implementation

Title: Interface to enumerate over files

Body:
What if instead of using an interface I create an abstract class with abstract methods of each of these steps which concrete classes have to implement

Yes. An interface does not tell how the methods interact or how to process. That is just one technique for dependency injection.

Part of the problem is acquiring the list of files can be a long process. Each file may need to be downloaded, and opened to find nested contents etc..etc. So I want to do the processing as the files are being iterated over rather then opening them twice.

Document Facade

A general meta-data class & and associated "framework" with injectable custom equality and comparison functionality.

public class DocumentFacade : IEquatable<DocumentFacade>, IComparable<DocumentFacade> {
    // this class is more like document metadata, not necessarily a facade design
    // pattern wrapping the Document object itself
    protected EqualityComparer<DocFacade> equalizer;  // customized Equals, CompareTo

    public string Name { get; set; }
    // superset of any and all properties relevant to processing. Covers all
    // document sub classes.

    public DocStatus OpenStatus { get; set; }  // an enum
    public DocStatus CloseStatus { get; set; }
    public DocClass DocumentClass; // an enum, alternatively Type.Name, or even the Type object itself.

    public BaseDocClass theDoc;  //reference to the document this DocumentFacade represents
                                 // maybe you don't even need this.

   public DocumentFacade (IEqualityComparer<DocFacade> equalizer) {
       if(equalizer == null) throw new NullArgumentException();
       this.equalizer = equalizer;
   }

    public override bool Equals(object that) {
       if(that == null) return false;
       if(that.DocumentType != this.DocumentType) return false;
        return equalizer.Equals(this, other);
    }

    // the IEquatable implementation
    public bool Equals(this, y) {
        return Equals(y);
    }
}

// A class for each way we want to compare Documents; each sub-class I suppose.
// MSDN says inheriting is the way to go, vice interface implementation.
public class DocFacadeEqualizerTypeA : IEqualityComparer<DocumentFacade> {
    public override bool Equals (DocFacade x, DocFacade y) {
        // customized implementation
    }
    // ditto CompareTo override
}

public class DocumentFacadeCollection : List<DocFacade> {

    public bool Equals (DocFacade x, DocFacade y) {
        if(x == null) return false;
        return x.Equals(y);
    }

    // lots of inherited List stuff makes this class really handy.
    public DocFacadeCollection GetOpenStatus(DocStatus thisStatus) {
        Find( x => x.OpenStatus == thisStatus);
    }

    public DocFacadeCollection FindAllDuplicates (DocFacadeCollection otherList) {
         DocFacadeCollection duplicates = new DocFacadeCollection();
         duplicates.AddRange( this.FindAll( x => otherList.Contains( x )).AsEnumerable());
         return duplicates;
    }
}

public static class DocumentDNAAnalyzer {
    // this may be a factory, or perhaps more likely, the front of
    // of a Builder pattern implimentation
    // Besides a customized DocFacade object, we may also be able to
    // provide stuff for abstract template.

    public static DocFacadeFactory = new DocFacadeFactory();

    public static DocFacade Create(object TheDocument) {
        return DocFacadeFactory.Create(TheDocument));
    }
}

See this thread for a great GetHashCode() Implementation


答:
If we're building a GUI application we almost ALWAYS create a prototype or POC (proof-of-concept).  We'll establish what the visual vocabulary of the app will be. We usually get our client involved part way through the POC and make sure they understand what the purpose is and what they should be focusing on.  I've never been sorry that I produced a prototype.  Just be sure that you don't try to turn the prototype code into the production code, start the production code from scratch based on what you learned from the prototype.

Having said all that, we almost never prototype server side applications (services, middleware, etc.).  I don't really see the return on investment for that (unless you are doing some new technology and need to prove different concepts out).

Title: How common is prototyping as the first stage of development?

Body:
I've been taking some software design courses in the past few semesters, and while I see the benefit in a lot of the formalism, I feel like it doesn't tell me anything about the program itself:

You can't tell how the program is going to operate from the Use Case spec, even though it discusses what the program can do.

You can't tell anything about the user experience from the requirements document, even though it can include quality requirements.

Sequence diagrams are a good description of how the software works as the call stack, but are very limited, and give a highly partial view of the overall system.

Class diagrams are great for describing how the system is built, but are utterly useless in helping you figure out what the software needs to be.

Where in all this formalism is the bottom line: how the program looks, operates, and what experience it gives? Doesn't it make more sense to design off of that? Isn't it better to figure out how the program should work via a prototype and strive to implement it for real?

I know that I'm probably suffering from being taught engineering by theoreticians, but I need to ask, do they do this in the industry? How do people figure out what the program actually is, not what it should conform to? Do people prototype a lot, or do they mostly use the formal tools like UML and I just didn't get the hang of using them yet?


问:
What is the best way to initialize a child's reference to its parent?
I'm developing an object model that has lots of different parent/child classes.  Each child object has a reference to its parent object.  I can think of (and have tried) several ways to initialize the parent reference, but I find significant drawbacks to each approach.  Given the approaches described below which is best ... or what is even better.

I'm not going to make sure the code below compiles so please try to see my intention if the code is not syntactically correct.

Note that some of my child class constructors do take parameters (other than parent) even though I don't always show any.

Caller is responsible for setting parent and adding to the same parent.

```<code>class Child {
  public Child(Parent parent) {Parent=parent;}
  public Parent Parent {get; private set;}
}
class Parent {
  // singleton child
  public Child Child {get; set;}
  //children
  private List<Child> _children = new List<Child>();
  public List<Child> Children { get {return _children;} }
}
</code>```

Downside: setting parent is a two-step process for the consumer.

```<code>var child = new Child(parent);
parent.Children.Add(child);
</code>```

Downside: error prone.  Caller can add child to a different parent than was used to initialize the child.

```<code>var child = new Child(parent1);
parent2.Children.Add(child);
</code>```

Parent verifies that caller adds child to parent for which was initialized.

```<code>class Child {
  public Child(Parent parent) {Parent = parent;}
  public Parent Parent {get; private set;}
}
class Parent {
  // singleton child
  private Child _child;
  public Child Child {
    get {return _child;}
    set {
      if (value.Parent != this) throw new Exception();
      _child=value;
    }
  }
  //children
  private List<Child> _children = new List<Child>();
  public ReadOnlyCollection<Child> Children { get {return _children;} }
  public void AddChild(Child child) {
    if (child.Parent != this) throw new Exception();
    _children.Add(child);
  }
}
</code>```

Downside: Caller still has a two-step process for setting parent.

Downside: runtime checking – reduces performance and adds code to every add/setter.

The parent sets the child's parent reference (to itself) when the child is added/assigned to a parent.  Parent setter is internal.

```<code>class Child {
  public Parent Parent {get; internal set;}
}
class Parent {
  // singleton child
  private Child _child;
  public Child Child {
    get {return _child;}
    set {
      value.Parent = this;
      _child = value;
    }
  }
  //children
  private List<Child> _children = new List<Child>();
  public ReadOnlyCollection<Child> Children { get {return _children;} }
  public void AddChild(Child child) {
    child.Parent = this;
    _children.Add(child);
  }
}
</code>```

Downside: The child is created without a parent reference.  Sometimes initialization/validation requires the parent which means some initialization/validation must be performed in the child’s parent setter.  The code can get complicated.  It would be so much easier to implement the child if it always had its parent reference.

Parent exposes factory add methods so that a child always has a parent reference.  Child ctor is internal.  Parent setter is private.

```<code>class Child {
  internal Child(Parent parent, init-params) {Parent = parent;}
  public Parent Parent {get; private set;}
}
class Parent {
  // singleton child
  public Child Child {get; private set;}
  public void CreateChild(init-params) {
      var child = new Child(this, init-params);
      Child = value;
  }
  //children
  private List<Child> _children = new List<Child>();
  public ReadOnlyCollection<Child> Children { get {return _children;} }
  public Child AddChild(init-params) {
    var child = new Child(this, init-params);
    _children.Add(child);
    return child;
  }
}
</code>```

Downside: Can’t use initialization syntax such as new Child(){prop = value}.
Instead have to do:

```<code>var c = parent.AddChild();
c.prop = value;
</code>```

Downside: Have to duplicate the parameters of the child constructor in the add-factory methods.

Downside: Can’t use a property setter for a singleton child.  It seems lame that I need a method to set the value but provide read access via a property getter.  It’s lopsided.

Child adds itself to the parent referenced in its constructor.  Child ctor is public.  No public add access from parent.

```<code>//singleton
class Child{
  public Child(ParentWithChild parent) {
    Parent = parent;
    Parent.Child = this;
  }
  public ParentWithChild Parent {get; private set;}
}
class ParentWithChild {
  public Child Child {get; internal set;}
}

//children
class Child {
  public Child(ParentWithChildren parent) {
    Parent = parent;
    Parent._children.Add(this);
  }
  public ParentWithChildren Parent {get; private set;}
}
class ParentWithChildren {
  internal List<Child> _children = new List<Child>();
  public ReadOnlyCollection<Child> Children { get {return _children;} }
}
</code>```

Downside: calling syntax is not great.  Normally one calls an add method on the parent instead of just creating an object like this:

```<code>var parent = new ParentWithChildren();
new Child(parent); //adds child to parent
new Child(parent);
new Child(parent);
</code>```

And sets a property rather than just creating an object like this:

```<code>var parent = new ParentWithChild();
new Child(parent); // sets parent.Child
</code>```

...

I just learned that SE does not allow some subjective questions and clearly this is a subjective question.  But, maybe it is a good subjective question.

答:
I would stay away from any scenario which necessarily requires the child to know about the parent.

There are ways of passing messages from child to parent through events.  This way the parent, upon add, simply has to register to an event that the child triggers, without the child having to know about the parent directly.  Afterall, this is likely the intended usage of a child knowing about its parent, in order to be able to use the parent to some effect.  Except you wouldn't want the child performing the job of the parent, so really what you want to do is simply tell the parent that something has happened.  Therefore, what you need to handle is an event on the child, of which the parent can take advantage.

This pattern also scales very well should this event become useful to other classes.  Perhaps it is a bit of an overkill, but it also prevents you from shooting yourself in the foot later, since it becomes tempting to want to use parent in your child class which only couples the two classes even more.  Refactoring of such classes afterwards is time-consuming and can easily create bugs in your program.

Hope that helps!