Here is a very basic example of what I am trying to do. In reallity there are more relations but not something extreme or memory heavy.
public class ClassA : ISomething
{
public double property { get; set; }
...
public ClassB classb { get; set; }
}
public class ClassB : ISomething2
{
public double Length { get; set; }
...
}
public class MyProject : BaseProject
{
public IEnumerable<ISomething> ISomethings { get; set; }
...
public IEnumerable<ISomething2> ISomethings2 { get; set; }
...
}
The issue here is that I have to keep a list of MyProject
.ISomethings2
and then classb
property of ClassA to reference only an existing item in MyProject
.ISomethings2
list. The hard thing here is that:
- Removing an item from
ISomething2
should remove all references to it (classb
property of ClassA instances to be set to null) - Prevent other developers setting
classb
property to a non existing object in list or a new user created object. - Objects in
MyProject
.ISomethings2
could be added without having to be referenced from elsewhere.
These classes are used for project description not database stuff. Like when you open a project file for an application. So changing a property in classB should be visible to all since it is the same object reference.
Is there a pattern to achieve what I want without much coupling? Alternative designs/approaches are also welcome.
4
Is there a pattern to achieve what I want without much coupling?
Not really, since at its core what you want to do “when X happens, I want to do Y to these other things” is coupling by definition. Which also makes this a rather undesirable design for the problem at hand.
If I had to work with this, I’d start by looking to make the classes immutable (publically at least) and controlled by the project. If you can’t set the classb
property on the object, there’s no way to set it to be invalid. Instead the project class can do that (along with validation rules, and possible optimizations like reference counting perhaps).
But honestly, I would try very hard to not work with this. Project here is a manager of the other objects. Forcing class instances to be in some external collection is gross and unweildly. Occasionally it’s somewhat necessary (games especially do this), but it should be avoided where possible and used with care otherwise. Without knowing more about the problem you’re trying to solve, I can’t say for sure which bucket this falls in.
3
Note: I’m assuming the language is C#. If it’s Java, similar mechanisms should exist as well.
-
If you want to track changes to the properties of
ClassA
, you can useINotifyPropertyChanged
. -
If you want to track changes to the
ISomethings2
sequence, instead ofIEnumerable<T>
, useObservableCollection<T>
. -
If you just need to keep
ISomethings2
sequence in sync withISomethings
, rewrite the property as:public IEnumerable<ISomething2> ISomethings2 { get { return this.ISomethings.Select(c => c.classb); } }
If this doesn’t give you an answer, consider editing your question. Its actual form is very unclear because of the lack of proper terminology and cryptic names of your example. Also note that you currently cannot remove anything from ISomethings2
, given its type.