8

David West in his book Object Thinking (chapter 10, section 1, sub-section 2) proposed that in an ideal OO environment, every objects should be capable of presenting themselves upon request; be it to humans (as GUI), non-native components (as JSON and/or XML), or any other interested parties:

Object thinking says that a view (sometimes called an interface) —graphical or otherwise—is a means for an object to communicate with another object and nothing more. The need for a view arises when an object needs to present itself in a “non-native” form to some other object (usually a human being) or application (for example, an XML view for data objects being shared across platforms).

Discovery of the need and the parameters that must be satisfied by a view is manifest in the scenarios in which the object participates. Whenever an object is asked to display itself, it must use a view—a representation—appropriate for the sender of that display message. If, for example, an object is trying to instantiate itself (get a value for itself), it must present a view of itself as an implicit request to a human being (or other service-providing object) for a value. If we are building a GUI that will serve as an intermediary between a software object and a human object, we will use glyphs for display purposes and widgets for interaction purposes.

But which glyphs and widgets need to be included in the GUI ? Only those necessary to complete the scenario or scenarios 4 of immediate interest as the application runs. This perspective is counterintuitive for most developers because it suggests that a GUI be defined from the application out.

As an example, consider a brewery. Off to one side are vats filled with beer. At the a complex production line consisting of bottle washers, filler stations, capping machines, and package assemblers. Above it all is a control station that monitors the brewery and notifies human managers of status and problems. Traditional developers are likely to begin their analysis and design of “a brewery management system” from the point of view of the control panel. This is analogous to designing from the interface in.

Object thinking would suggest, instead, that you consider which object is the prime customer of the brewery and all its myriad machines. On whose behalf does the complex maze of equipment exist? The correct business answer is, of course, “The customer.” But an answer more reflective of object thinking is, “The beer.” All scenarios are written from the perspective of the beer, trying to get itself into a bottle, with a cap, placed in a package, and resident in a truck. The control panel is a passive observer 5 of the state of the brewery. If the beer encounters a problem at some point, it’s the responsibility of the beer to request intervention of the human operators by sending a message to the control panel (or machine-specific control panels) requesting an intervention service.

This perspective will simplify GUI design and, more important, eliminate the host of manager and controller objects that seem to inevitably arise when designing from the control panel’s ( GUI ’s) perspective.

Coming from a beginner in the OO world: should this really be the case?

Having objects that know how to represent themselves surely could reduce the number of controller/manager objects which West repeatedly said in his book an Object Thinker supposedly should try to avoid at all costs. But won't abiding this "rule" break SRP?

Also (if it does turned out to be the case), given a typical implementation in, say, an Android application: How could one achieve this kind of goal? Should every object we create know how to present itself as a View?

  • 3
    SRP doesn't mean what you think it means. SRP means that your "car" object doesn't diagnose pet problems. It doesn't mean that a visual UI element shouldn't be capable of displaying itself. – Robert Harvey Mar 29 '16 at 15:10
  • I see. However you do mention visual UI element. Now, if we were to apply this rule in designing our software, won't the majority of the objects we'll end up creating be visual UI elements? Because most of them will demand an interaction with the user sooner or later, right? – MrHadiSatrio Mar 29 '16 at 15:15
  • 1
    @RobertHarvey I'm not sure how that quote could be seen as supporting an MVC-type pattern. It reads like it's saying it's the class's responsibility to define its interface/"view" to meet its needs, whereas in an MVC pattern, the model would be ignorant of the view displaying it. – Ben Aaronson Mar 29 '16 at 15:56
  • 1
    @ridsatrio Since you are a self-admitted beginner... I suggest you strive to write interfaces that exist to tell an object about something that happened outside of its control rather than methods that tell objects to do things. So methods like "buttonWasClicked" or "pageWillBeDisplayed" are better than "changeState" or "drawInCorner". "Tell don't ask..." tell objects about what's happening rather than asking them to do things. – Daniel T. Mar 30 '16 at 0:23
  • 2
    The author should at one point have stopped writing and thought, "Do I actually want to teach people about OOP by talking about beer that wants to be in a bottle and tells operators when it can't?" I don't see how this is supposed to illuminate any concepts or ideas whatsoever to anyone. – Sebastian Redl Mar 30 '16 at 19:23
12

I think this is one of the hardest things to understand about OO design and honestly, I think a lot of authors are wrong about it and/or don't explain it very well. A lot of people get this wrong and never really figure it out. Let's take an example that's not GUI-based but runs into the same pitfall.

In Java, every object has an equals method. You then have collections types like set and map that depend on this method to determine when objects should be added to the collection or when they are duplicate. This seems like good OO to a lot of people. The problem is that what you end up with is an object (the collection) whose behavior is not determined by it but by the objects that it contains. This is a bit like having the passengers on the bus direct where it should go. What if they disagree? This isn't a theoretical problem, it's a really thorny issue where you basically have to break inheritance to prevent bugs in your program. Take a Shape and a ColoredShape. Is a 2x2 square equal to a 2x2 blue square? Shape says 'yes' and ColoredShape says 'no'. Who's right? The answer depends on what you want to happen in your collection. It might be neither depending on what you are trying to do.

You'll see this come up as a problem again and again. The funny thing is that there's a solution and it's right next door at the Comparable. Objects that implement Comparable have this same conundrum but now they have to not only determine whether they are equal but whether they are bigger than another object. It's really intractable outside a very narrow scope of usage. So we have this other thing called Comparator. It's job is to look at two objects and tell the collection which one is bigger. All of the problems that you have trying to do this in the Comparable object disappear.

I don't know this book and I don't know the author but the example with the beer does not seem helpful at all. How would the beer know whether it should be in a bottle or in a keg and why would it be making that decision? It's job is to taste good and deliver alcohol to the users' bloodstream. Do we really think breweries work this way? "OK beer, should you be in a bottle or in a keg and if it's a bottle, should it be a 25 ounce bottle or a 12 ounce bottle?" What's the beer in this case (no pun intended) anyway? Is it a drop of beer? Maybe this is out of context but I think this gets it wrong or at the very least it's not adding any illumination to this concept.

Having said all of that, there's an approach to building interfaces that I've used that can simplify things and make it more OO. Essentially, you create an interface that defines the abstract actions that you can take to display the object. You might have an interface called Display methods like setTitle or setDescription if you are using the standard Java naming pattern. Then your object would have a method display(Display display) (because three times is the charm!) In this approach, the object doesn't need to understand what the interface is, it could be text, binary, svg, bitmap, whatever and the interface doesn't need to know about the object. In this way an object can "display itself" without needing to know about how the display works. This approach can greatly reduce the number of wrapper classes needed but it can cumbersome if you have complex display requirements that vary by object. You can mix it with standard MVC type approaches to good effect.

  • 2
    Nice answer, and I think it touches on all the relevant issues. – Robert Harvey Mar 29 '16 at 19:54
  • This is a very nice answer indeed. Come to think about it, perhaps your way of enabling objects to draw themselves via a defined interface is the best approach to this matter. This way, objects still hold their right of controlling how they want to be displayed (not by an external controller) but without needing them to learn how a Display would work in its concrete implementation (as they should were they be given a plain JFrame, for example). Thanks. – MrHadiSatrio Mar 30 '16 at 9:10
  • 1
    This answer is awesome and has me reflecting a lot on OOP in general. I've found an ECS to be so much easier to maintain which separates the data and functionality, and partly because it doesn't suffer from that analogy of what you described using objects trying to internally determine what is the correct behavior to compare themselves to something else. – user204677 Feb 2 '18 at 4:25
8

The Single Responsibility Principle doesn't mean that a class does only one thing. It means that a class has a single reason to change.

You're probably thinking of a method, which really does do just one thing.

Taken to it's logical conclusion, your version of SRP would mean that you would never be able to log anything, because logging is a separate responsibility.

It's better to think of a class as a single, well defined subject. You can have several methods that support that subject, and they could all be doing different things.

The most fundamental "display me" method is ToString, which is always a method on the object.


All that said, when we create a UI, we typically encourage Separation of Concerns by providing objects whose sole purpose is displaying data from other objects (i.e. Views).

Perhaps an example is in order. Consider a PHP website, using a View. A simple View might look like this:

<?php
class View
{
    private $model;
    private $controller;

    public function __construct($controller,$model) {
        $this->controller = $controller;
        $this->model = $model;
    }

    public function output(){
        return "<p>" . $this->model->string . "</p>";
    }
}

In PHP, the View always contains an output() function. To get the visual representation of a view, all you have to do is call output(), and you will get a string suitable for display in any modern browser.

If you will notice, the View references an object called model. This is the object that contains the actual data. The View and the Model are in separate objects; this is what establishes the Separation of Concerns.

Separation of Concerns is important for websites, because it is what allows a designer to work on a web page design apart from the programmer.

Further Reading
The MVC Pattern and PHP

  • Alright. But once we have separated the view from the model, is it still the model's job to provide the view? Because that's what I'm getting from the quote above: the object (or model in your vocabulary) should know how to display itself, right? In a sense, say you got a Receipt object in a typical POS software, you would still call Receipt.draw(Canvas) and not ReceiptView.draw(Receipt). – MrHadiSatrio Mar 29 '16 at 16:06
  • 2
    In MVC, it is the Controller's responsibility to choose which view to use. – Robert Harvey Mar 29 '16 at 16:07
  • But controllers object are what exactly being posed as things to avoid in West's perception in Object Thinking (and thus in that quote). The quote explicitly states that the whole idea behind "objects that know how to display themselves" is to avoid "manager and controller objects". – MrHadiSatrio Mar 29 '16 at 16:12
  • That's fine, but I think you're going to have to confine that thinking to objects whose sole purpose is visual display. Views, in other words. The controller doesn't care how the View displays itself; it only cares about which view to use. Also, MVC is not the only possible display paradigm, and others (notably MVVM) work somewhat differently. But the basic principle of Separation of Concerns remains. – Robert Harvey Mar 29 '16 at 16:13
  • Note that the book that you are reading is quite old for a software book (2004). MVC and MVVM had not come into common use yet. – Robert Harvey Mar 29 '16 at 16:17
1

Judging from the quotes you pasted, you are misinterpreting the text.

The author is not saying that every object should be able to present themselves in a UI. This would be impossible, since an object cannot know what UI it will be shown in (in a WinForms app, a linux app using XServer, as a JSON string, as XML, as a PNG image etc).

The point made is that you should write specialized views whose sole responsibility is to display a certain entity. You could for example write a view that renders an object as HTML (as is done by views in MVC applications). You could make a JSON serializer that can turn an object into a JSON string. You could make an object that turns other kinds of objects into PDF reports. It all depends.

The point is, separate the business entity from the visual (or serialized) representation. They are different things and change for different reasons.

  • I've edited my question to elaborate on the quote. – MrHadiSatrio Mar 29 '16 at 15:22
  • 1
    While I admit my answer doesn't feel quite as relevant any more, I don't see what your question has to do with the quote. The quote seems to be speaking more in terms of APIs and interfaces, rather than visual rendering. What parts of an object should be accessible and what messages can it send in order for it to complete it's job in the business domain? – sara Mar 29 '16 at 15:27
  • "If we are building a GUI that will serve as an intermediary between a software object and a human object, we will use glyphs for display purposes and widgets for interaction purposes." Judging by that sentence, I'm pretty sure the quote also implies visual rendering purposes. – MrHadiSatrio Mar 29 '16 at 16:23
  • There is nothing there stating that "the object in question should choose what glyphs and widgets that best represents it for any given context, and should also be responsible for rendering said glyphs and widgets." The object and the thing displaying it aren't necessarily (shouldn't be) the same thing. – sara Mar 29 '16 at 16:28

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.