Programmer1994
Programmer1994

Reputation: 975

How to connect Ui information and domain information

Say, I'm making a game with a user interface and I want certain persons to be drawn on a canvas, let's say by representing them using rectangles with above them, a textbox with the specific name of the person. Pure from a domain perspective, my person has a name. Later specific domain-logic can be added if necessary

public class Person{
  private String name;
  //Constructor and methods
}

I also need to keep track of the Ui-information concerning the person, so I decide to make a seperate class that does just that.

public Class PersonUi {
  private int x;
  private int y;
  private int length;
  private int width;

  //Constructor and methods
}

Now I have Ui and domain data in different classes. Say I want to know the name of the person when clicking on a certain Person. I can link the correct PersonUi object, but how do I know the name of the person? How to link the Ui and domain data as object oriented as possible?

e.g. how are following options considering good object oriented design?

1) Saving both in lists inside another class and using the order of the lists to know which ui object belongs to which domain object

2) Using a Map to map the two classes

3) Using a wrapper class to wrap the two classes.

Or is it okay to just define all the data in the previous example in just 1 class?

Upvotes: 0

Views: 83

Answers (1)

Reasurria
Reasurria

Reputation: 1848

Usually this problem is solved by having a service/api layer between your UI and domain. You could store your person ID (let's say a GUID) in the personUI. Then in the UI class you could have:

public class PersonUi
{
    private Guid personId; // Or UUID for java
    private IPersonService personService;

    ...

    nameTextBox.text = personService.getPersonName(personId);
}

This way you do not have a direct link to your domain from the UI end. All use cases must be channeled through the service.

This service could also be used of course to alter the domain.

To test the integrity of your design you can put the domain in a different package/project and completely remove it as a dependency for your UI layer. The UI layer may reference the service layer which may reference the domain layer.

To communicate changes made to the domain to the UI, you might need to look at an event system. If one input component receives input that changes the domain and these changes must propagate to several other UI components, events will probably be the best way. Just make sure to serve the minimum amount of information in the event args and not the actual domain entity as that will bring you back to your original concern of coupling the UI and domain.

Your final code for the UI component might look like this (excuse my filthy C# conventions):

public class PersonUi implements IPersonNameChangeListener
{
    private Guid personId; // Or UUID for java
    private IPersonService personService;

    ...

    public void userEnteredANewNameThroughUI(String newName)
    {
        personService.setName(personId, newName);
    }

    @Override
    public void onPersonNameChange(Guid personId, String newName)
    {
        if(this.personId != personId)
             return;

        nameTextBox.text = newName;
    }
}

In this last code sample you will notice that your input does not directly affect your output. Instead the change is bubbled up to your domain and communicated back to your UI layer through an event. This means your input and output components are now also independent.

Upvotes: 1

Related Questions