Domain modeling issue

Hello,

I have an issue where I'm struggling to come up with a satisfying solution.
I have 3 entities which can be linked like so:
A (1 <-> N) -> B <- (1 <-> M) C

My current solution involves:

pub struct A { bs: Vec<B> }
impl A {
    fn cs(&self, z: &Z) -> Vec<C> {
        let mut cs: Vec<C> = Vec::new();
        for b in self.bs {
            // the clone I'm not happy about
            let inners = C::cs(Rc::new(b.clone()), z);
            cs.append(&mut inners);
        } 
        cs
    }
}

pub struct B { }
impl B {
  fn fs(&self, z: &Z) -> Vec<f64> {
    vec![]
  }
}

pub struct C { b: Rc<B>, f: f64 }
impl C {
  // tags each f with the proper B
  fn cs(b: Rc<B>, z: &Z) -> Vec<C> {
    b.fs(z).iter().map(|f| C { Rc::clone(&b), *f }).collect()
  }
}

pub struct Z { }

I'm not happy with having to clone each B once and would like to remove that part.

If you have any ideas, there are welcome, thank you :slight_smile:

Why doesn't B have a Vec<C>, instead of each C having a Rc<B>? Like you do with A and B?

Probably because the OP needs to go from C to B and that would be difficult (or impossible) if keeping a Vec<C> in B.

Well yeah, but I'm curious about the reasoning behind it.

That's exactly it, further down the line, I will need links from C going back up to B. That's why I ended up in this situation in the first place.

In those situations, why can't you fetch the right B from somewhere else but C itself? Like some sort of application state that you can query?

You could keep them in Rc from the start.

pub struct A { bs: Vec<Rc<B>> }

I stayed away from that because it was a painful refactor but it did work, thanks :+1:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.