0

Suppose I have TypeA and TypeB classes, which are totally different, but both hold an list of TypeC objects.

Class TypeA { List<TypeC> cs; }
Class TypeB { List<TypeC> cs; }

Throuth all of it's life cycle, a TypeC instance is belong to a one single TypeA instance and a one single TypeB instance, which cannot be changed.

My question is how to create a new TypeC instance and associate it to TypeA and TypeB instances?

simple solution would be:

ConstructorOfC(typeA, typeB) {
    typeA.insertC(this);
    typeB.insertC(this);
}

the drawbacks of this approach is that C is aware and depend on TypeA and TypeB classes. I also expose an insert method, which I do not want since insert should be only upon creation, but this method can be called at any time.

Another solution can be:

TypeA: createTypeC() {
     this.cs.insert(new TypeC());
}

which would work if typeC had a single parent, but it's not the case.

1

You need some repository of C's to determine the scope of "All Type C's" I would suggest

Dictionary<TypeC,Tuple<TypeA,TypeB>> allCs = new Dictionary<TypeC,Tuple<TypeA,TypeB>>();

the only question is where to put it. Since you don't want TypeC to be dependent on the other types it will have to be at the application level.

I would add a Factory class to ensure that all new TypeCs are added to the collection and make the collection a singleton within the factory class.

public class CFactory : ICChecker
{
    private static Dictionary<TypeC,Tuple<TypeA,TypeB>> allCs = new Dictionary<TypeC,Tuple<TypeA,TypeB>>();

    public TypeC CreateTypeC(TypeA a, TypeB b)
    {
        var c = new TypeC();
        a.insert(c);
        b.insert(c)
        allCs.AddWithValue(c, new Tuple<TypeA,TypeB>(a,b));
    }

    public bool IsCAlreadyAssigned(TypeC c)
    {
        return allCs.ContainsKey(c);
    }
}

now in your A and B

public class TypeA
{
    private readonly ICChecker checker;
    public TypeA(ICChecker checker) { this.checker = checker; }
    public void insert(TypeC c)
    {
        if(this.checker.IsCAlreadyAssigned(c) { throw new Exception("NO!"); }
    }
}
0

From what you described, I think this is actually somewhat simple. For clarity, I'll call each type a bit differently. It's not clear

class Father {
  List<Child> children;

  public void addChild(Child child) {
    if (child.father == this) {
      children.add(child);
    }
  }
}

class Mother {
  List<Child> children;
  public void addChild(Child child) {
    if (child.mother == this) {
      children.add(child);
    }
  }
}

class Child {
  Father father;
  Mother mother;

  public Father getFather() { return this.father; }
  private void setFather(Father f) { 
      if(this.father == null) {
        this.father = f;
        f.addChild(this);
      } // throw an exception if you want
  }
  public Mother getMother() { return this.mother; }
  private void setMother(Mother m) {
     if (this.mother == null) {
       this.mother = m;
       m.addChild(this);
     }
  }

  public Child(Father f, Mother m) {
     this.setFather(f);
     this.setMother(m);
  }
}

This ensures that only the child can set its parents and only once, and the parents can only add a child if that child has them as a parent.

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.