3

Say we have a user interface with Forms, Buttons and such. Each item has some properties (such as Visible, Enabled, etc.). Who should check on these properties and decide whenever to render the item or not?

  • Parent item: for I := 0 to Count - 1 do if Child[I].Visible then Child[I].Paint

  • Or each item itself: if not Self.Visible then Exit else <<PaintSelf>>

Here, Visibility is just an example - same choice arises with many other properties (GUI, application logic, etc.) when some parent needs to do something with its childs.

The answer is obvious in event-driven model, where event issuer could not possibly know about handlers properties. But what about non event-driven model, where there's a Parent and a list of Childs it manages?

I'm looking for a general guidelines/solution to this case.

1

At least in OO + event driven interfaces:

  • GUI objects, including the window pane itself, have event listeners who are triggered with user actions. Those event listeners call a method which then send messages to other GUI elements (or to themselves).
  • But... once a GUI element receives an message (like myButton.setVisible(false);) it renders itself (obviously lower level calls to the windowing system are made to made this possible).
  • So the "controlling/orchestrating" is on behalf of the main windows and delegated to other controsl as well, for example a radio botton onclick event listener can send a message to a textbox to set itself invisible.
  • The code of actually rendering is inside every item, being each one an instance of a class. Obviusly they are issuing low level calls to a windowing system / rendering engine.
  • I did not had event system in mind and GUI specifically, but okay. So what you say is - we have some Form, it has a bunch of subscribers on it's Repaint event, it generates that event and it does not care which items are enabled or visible, letting items decide on themselves if and how to react to the message. Right? – Kromster Apr 25 '16 at 17:48
  • @KromStern It sends messages to the objects telling them to change their visibility. But other GUI objects can do so also. – Tulains Córdova Apr 25 '16 at 18:21
1

Each item itself

This all should work much alike event-driven system. Parent entity should give orders to its Items, and Items should check with their state to see if and how they can perform that action.

Even if it is as simple as reading 1-2 public properties for the Parent, it is still better for encapsulation to not do so and let Items check their state (which at times can be much more complicated than a single Boolean flag).


TDA principle (Tell-Dont-Ask) backs this up:

Tell-Don't-Ask is a principle that helps people remember that object-orientation is about bundling data with the functions that operate on that data. It reminds us that rather than asking an object for data and acting on that data, we should instead tell an object what to do. This encourages to move behavior into an object to go with the data.

0

Visibility is often something you want to aggregate so you can tell a whole group of objects to hide or show themselves together. Even so it's still best let each object test and paint itself.

I'm a big believer in tell don't ask. To me the object oriented world is divided into behavior objects that tell you nothing about their state, and data objects that are all about the getters.

Behavior objects have no getters. They are encapsulated. They talk to the world by telling other objects to do things and by outputting.

Data objects have getters. They need to exist when behaviors that depends on this data are scattered among multiple objects and those behaviors can't be moved into one object.

An object that can paint itself sounds like a behavior object. So how to share visibility?

Group objects that need to share visibility changes together into collections. Tell them to all change visibility together. Events are a common way to do that. The observer pattern can be used with the assumptions I've made here but is usually depicted observing dataobjects .

  • The question is about "Who is responsible for handling .." rather than "How do I aggregate GUI objects". Could you change your answer to focus on this please? – Kromster Apr 25 '16 at 17:57
  • 1
    If you're treating them like behavior objects they handle themselves since nothing else even knows what's visible. Does that make the focus clear? – candied_orange Apr 25 '16 at 18:59

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.