0

In MFC, certain mechanisms provided allow the programmer to bypass modularity and encapsulation and information hiding, arguable the most desirable features of an Object Oriented framework.

One (of many) examples is Owner Drawn controls: you can choose to either implement DrawItem in a child control subclass and do all of that control's drawing in that subclass, making it appear more modular:

class CustomButton: CButton{
     // --- Lots of stuff, DECLARE_DYNAMIC etc

     virtual void DrawItem(LPDRAWITEMSTRUCT lpdis){
          // Drawing code for this button in the button's subclass
     }
};

...or you can choose handle the WM_DRAWITEM message in a parent Window class via OnDrawItem

class MainFrame: CFrameWnd{
     // --- Lots of stuff, DECLARE_DYNAMIC etc

     CustomButton button; 

     afx_msg void OnDrawItem(LPDRAWITEMSTRUCT lpdis, UINT id){

          if(id == CUSTOM_BUTTON_ID){     
               // Drawing code for this button in the button's subclass
          }
     }
};

In the later situation, the drawing of the control is outside of the control subclass, meaning that the concept that "OOP data structures tend to carry their own operators around with them" is undermined.. right?

So my question is: which one is considered 'best practice'? There must be a reason that the second one exists - can anyone suggest a circumstance in which undermining modularity would be a better option?

Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
user965369
  • 5,413
  • 13
  • 33
  • 47
  • This question not really for stackoverflow as it is really just trolling for opinions. You can choose how you use MFC. And the word tend does not mean always. – Richard Chambers Oct 26 '12 at 19:11
  • Sorry, didn't realise I wasn't allowed to ask debate sparking questions.. – user965369 Oct 26 '12 at 19:19
  • all opinions are valid, most of them are wrong in various degrees because they are all simplifications. And that includes this opinion that I have just written. – Richard Chambers Oct 26 '12 at 19:23
  • 1
    I interpreted this as a question about modularity rather than the usage of MFC. My interpretation could be wrong, of course... – ryan0 Oct 26 '12 at 19:32
  • This question involves the Windows messaging architecture and how Windows messages are propagated between the various parent and child windows. MFC is a skin over that underlying platform and the result is there are lots of ways you can shortcut MFC where the skin is pretty thin and the bone shows through. The questioner already knows a proper, main stream use of MFC encapsulating the DrawItem functionality into the window that is doing the drawing. On the other hand there may be times when doing the drawing in the parent is a valid approach though I can not think of one at the moment. – Richard Chambers Oct 26 '12 at 20:02
  • No ryan0 is right its a question geared more towards modularity and its best practices (and in this case, where they are not realised). – user965369 Oct 26 '12 at 21:04
  • question rephrased so as to be less open ended everyone! – user965369 Oct 27 '12 at 12:25

2 Answers2

1

This question seems to be asking when is it reasonable to have a parent object that contains one or more child objects to handle messages meant for the child rather than just passing the message on to the child letting the child handle it instead.

The specific example is with MFC window classes in which a window object that contains other window objects (button in this case) is processing a draw message rather than just passing the message on to the child to process.

The basic answer would be it depends. There may be cases where you are composing a window object and as part of that you are over riding the drawing behavior of child controls in order to change the look of the child controls. For instance if you have a set of buttons whose look you want to change based on information in the parent window, you may want to over ride the drawing of the child controls in order to change the appearance.

This would be similar to having a button object which allows multiple different types of looks by allowing a parent window to provide a drawing object to the child control. The result would be that the child would have a default drawing behavior which the parent would over ride by providing a drawing object.

See this article in wikipedia on the Strategy pattern or this article on Strategy pattern with side links for other patterns which provides a brief discussion on this sort of programming problem. Another example might be the Chain of Responsibility pattern.

In this specific example, rather than the parent providing a drawing description object to the child to use, the parent is instead just intercepting the drawing messages and doing the drawing itself.

If changing the look of a child control can be done without affecting the other functionality of the child control then this would not be a bad approach though it could be confusing to the programmer who is doing maintenance or other changes. However this kind of over riding behavior can be seen in other instances such as window clipping in which the drawing of some window component is clipped so that any part of the component that would be outside of the window area is not drawn.

So the approach of having the parent object intercept and handle messages targeting a child object of the parent provides a great deal of flexibility in allowing various parents to change a specific behavior of the child depending on what the parent is wanting to accomplish.

However this flexibility does have a price.

Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
-1

It would be suboptimal OOP if, in the second situation, CUSTOM_BUTTON_ID were some data used internally by the control. This would violate the concept of information hiding as defined by David Parnas (http://www.cs.umd.edu/class/spring2003/cmsc838p/Design/criteria.pdf). If the internal information changes, the parent window will be affected by the change and will itself need to be changed to match. This is how information hiding facilitates modularity; it keeps data bundled with the thing that needs it (and hides it from those that don't).

Based on comments this is a bad example, because there is no violation of information hiding going on, since CUSTOM_BUTTON_ID is actually data that is contained and used by the parent window, not the control. The drawing of the control is still done within the control; the parent window just calls the control's Draw method.

ryan0
  • 1,482
  • 16
  • 21
  • 1
    That's not close. The ID is used by the parent to distinguish its child controls and assigned in the parent's code when it creates the controls. The button itself doesn't care about the actual value. The ID is the "Observable" object reference in the GoF Observer pattern, can't get more oopy than that. – Hans Passant Oct 26 '12 at 20:59
  • Hans, what's the GoF Observer Pattern? I'm interested now:) – user965369 Oct 26 '12 at 21:06
  • @HansPassant sorry, i was speaking generically about modularity without knowing how MFC works internally. I will delete my answer if people want me to. It does make sense that a GUI framework like MFC would utilize Observer (among other patterns). – ryan0 Oct 26 '12 at 21:17
  • http://en.wikipedia.org/wiki/Software_design_pattern and the Gang of Four design patterns book is http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612 though you might find this one from Head First http://www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124 more accessible. – Richard Chambers Oct 26 '12 at 21:22
  • @ryan0, why don't you take another try at it first. – Richard Chambers Oct 26 '12 at 21:23
  • @user965369, why don't you rework your question and title so that it is more about using MFC in a modular, encapsulating, object oriented fashion. – Richard Chambers Oct 26 '12 at 21:27
  • @RichardChambers could you edit it for me please? I think its a really interesting topic and I would love to hear the community's range of opinions but I can never seem to work these questions properly without sparking some sort of anger :( – user965369 Oct 26 '12 at 21:35
  • @user965369, the major focus of stackoverflow is specific, bounded technical questions. So a question like, "how to draw odd shaped buttons with MFC rather than standard Windows look" is the kind of technical question that is what stackoverflow is all about. The idea is to avoid emotionally charged words such as "undermine" or to seek opinions rather than specific answers or at least approaches to a technical problem. I am not sure what it is that you are wanting to ask however this is not the place for open ended questions on subjects that people have written entire books about. – Richard Chambers Oct 26 '12 at 21:56
  • @RichardChambers I've rephrased as you suggested. – user965369 Oct 27 '12 at 12:54