Object creation depending on caller

82 Views Asked by At

I have a class Presenter deciding which "class" is displayed to the user:

public class Presenter
{
    public MyObject ActiveObject { get; set;}
}

All my classes which can be presented are derived from MyObject:

public abstract class MyObject
{
    protected Presenter Presenter;
}

One of the classes which can be presented is Child:

public class Child : MyObject
{
    public void Find()
    {
        Results results = ChildSearch.Find(this);
        Child newChild = new Child(results);
        Presenter.ActiveObject = newChild;
    }
}

When the Find() method is called a new child is created and sent to the Presenter so it shows the "new" child.

This works quite well.

Now I have a use case that there is also a Parent class. It has a child and then the presenter shows "both" (a transport would be the parent and the driver the child, the presenter shows transport with its driver).

Inside the Parent a search for data of the child can be done (like the name of a driver):

public class Parent : MyObject
{
    private Child child;

    public void FindChild()
    {
        child.find();
    }
}

But in this case the new Parent should be shown by the presenter. Instead, as you can see in the Find() of Child the child is shown by the presenter.

This shows that my design is bad but I really don't have a clue how this could be done.

If you know a better title for this problem please suggest one. Is there any pattern fitting to my problem?

2

There are 2 best solutions below

0
On

Let your method only do one thing. Do the set active in the base class, and overload the find method in parent and child, this way every kind of MyObject can define which object has to be active.

public abstract class MyObject
{
    protected Presenter Presenter;
    protected abstract MyObject Find();
    protected void FindAndSetAcive()
    { 
       MyObject newActiveObject = Find();
       Presenter.ActiveObject = newActiveObject;
    }
}

 public class Child : MyObject
 {
  public override MyObject Find()
  {
    Results results = ChildSearch.Find(this);
    Child newChild = new Child(results);
    return newChild;
  }
}

 public class Parent: MyObject
 {
  public override MyObject Find()
  {
     child.find();
     // here you can do what you have to do to get the new "active element"
    return this;
  }
}
0
On

To me, it smells that Presenter knows about MyObject and MyObject knows about Presenter. It's not just tightly coupled, but tightly coupled both ways.

If you take the DDD or Onion Architecture approach, you could make the Parent and Child members of the Domain Model, which don't rely/depend/know about anything outside of the Domain Model. Following the Onion Architecture, you may then have a Domain Services layer that knows about this Domain Model and implements the Find() logic. Then on top of that, perhaps an Application Layer containing the Presenter as well as the rules around each use case. (For example, a given use case may create a Parent, find its Child and display the Parent. Or whatever you need it to do; at that point you'd have the high-level building blocks you could assemble as needed.)

In any case, I think it's excellent that you're analyzing the high-level design of your app, recognizing areas that need improvement and looking for existing solution patterns that may improve it. Kudos!