Abstracting from Stateful object navigation (1

The point of this exercise is to make navigation between objects stateful.

For example, having Person and Address with 1-1 association it should:

  • If an address is assigned to a persons, then the person should be assigned to the address (and vice versa).
  • If address is assigned to person1 and then to person2, then the person1 will have no address and person2 will.

  • This is the piece of code that implements it.

    public class A {
        internal B a;
        public B Value {
            get {
                return a;
            }
            set {
                if (value == null) {
                    if (a != null)
                        a.a = null;
                }  else
                    value.a = this;
                a = value;
            }
        }
    }
    
    public class B {
        internal A a;
        public A Value {
            get {
                return a;
            }
            set {
                if (value == null) {
                    if (a != null)
                        a.a = null;
                }  else
                    value.a = this;
                a = value;
            }
        }
    }
    

    This allows following tests to pass:

    // For the common setup:
    var a = new A();
    var b = new B();
    
    // Test 1:
    a.Value = b;
    Assert.AreSame(a, b.Value);
    
    // Test 2:
    b.Value = a;
    Assert.AreEqual(b, a.Value);
    
    // Test 3:
    b.Value = a;
    b.Value = null;
    Assert.IsNull(a.Value);
    
    // Test 4:
    var a2 = new A();
    b.Value = a2;
    Assert.AreSame(b, a2.Value);
    Assert.AreNotSame(a, b.Value);
    
    // Test 5:
    a.Value = b;
    Assert.AreSame(a, b.Value);
    var a1 = new A();
    var b1 = new B();
    a1.Value = b1;
    Assert.AreSame(a1, b1.Value);
    
    // Test 6:
    var a1 = new A();
    var b1 = new B();
    Assert.IsNull(a.Value);
    Assert.IsNull(b.Value);
    Assert.IsNull(a1.Value);
    Assert.IsNull(b1.Value);
    

    Now the question is: how would you abstract the code in the setters to avoid possible mistakes when writing a lot of such classes?

    The conditions are:

  • The PUBLIC interfaces of classes A and B cannot be changed.
  • Factories should not be used.
  • Statics should not be used (to persist shared info).
  • ThreadInfo or similar should not be used.

  • I really don't understand your challenge. What happens when you instantiate a few instances of class A and then a single instance of class B?

    A a1 = new A();
    A a2 = new A();
    A a3 = new A();
    A a4 = new A();
    A a5 = new A();
    B b = new B();
    

    Which test passes? Which one fails?

    You see, once A is instantiated, it has a state . This state should be somehow involved with an instance of B , an existing instance . So this instance of B must exist even before you instantiate this A class.

    The same is true for an instance of B . It should hold a reference to an already existing instance of A .

    As far as I understand, class A should have a constructor with a reference to an existing instance of B:

    public class A
    {
        private B b;
        public A(B b)
        {
              this.b = b;
        }
    }
    
    // Then you can have:
    B b1 = new B();
    A a1 = new A(b1); // here's the link
    
    B b2 = new B();
    A a2 = new A(b2); // and another link
    

    Either this or the other way around with B .

    You write that you don't want to change the public signatures of A and B , and you don't want to add factories to the code. I really can't see a consistent solution under such constraints. Or maybe the challenge itself is not clear enough?

    EDIT: Taking a wild guess here, I think that what you try to achieve here can be done using Reflection: you might want to reflect existing code up to a point (in the call stack), and match a new instance of, say, A to an existing instance of B . This is can be done using reflection, but it's pretty hard and you must have a concrete and robust set of rules for the linkage between new instances of A s and B s. If this is the direction of the needed solution, then I think you should dive into reflection and see how it goes, it's a huge field.

    链接地址: http://www.djcxy.com/p/51372.html

    上一篇: 从具有相同列表的子项的列表中查找最大ID

    下一篇: 从状态对象导航(1