Implications of Perspective in Teaching Objects ... - Semantic Scholar

2 downloads 288 Views 73KB Size Report
Jun 29, 2005 - tity. [8, p. 39]. (m) Model elements in Java programs are called objects.[1, p. ..... [10] Jia, X. Object-Oriented Software Development Using Java.
Implications of Perspective in Teaching Objects First and Object Design Henrik Bærbak Christensen Department of Computer Science – University of Aarhus 8200 Aarhus N – Denmark

[email protected] ABSTRACT There are an increasing number of books published on the important topics of “object-oriented programming” and “object-oriented design” for use in education. However, object-orientation can be viewed from a number of different perspectives—each perspective having its benefits and liabilities. A perspective has a strong influence on the kind of designs students can and will produce, the kind of domains that are easy or difficult to analyze, and the kind of frame of reference in which design techniques are understood and applied. In this paper we argue that most books make an implicit choice of perspective with the unfortunate effect that our students leave our courses with limited design abilities. We present a coarse-grained classification, discuss implications of perspective in a teaching context, and illustrate consequences using a small case study. Our main point is that teachers should be aware of the different perspectives, and that all perspectives are important for students to achieve high quality designs.

Categories and Subject Descriptors D.1.5 [Software]: Object-oriented Programming; D.2 [Software]: Software Engineering; D.2.2 [Software]: Design Tools and Techniques; K.3 [Computing Milieux]: Computers and Education

General Terms Design

Keywords Design patterns, objects, object-oriented design, role, responsibility-driven design

1.

INTRODUCTION “Your design is not really object-oriented . . . ”

Many students have received this discouraging statement as evaluation of a design exercise. And you have probably as teacher either made this statement to students or at least felt the urge to do so.

The counter question from the students that we fortunately do not get that often is: “Then what is an object-oriented design?” Just as the discussion of “what is an object?” has been going on for a long time without really getting to a consensus, there are numerous answers to the question “what is object-oriented design?” In practice, judging a design as either OO or not is a complex interplay between exact science, experience and craftsmanship, and personal taste. From some point of view, the exact borderline may seem a rather irrelevant discussion (if the software meets user expectations then who cares?) but as teaching professionals we have to be more careful and use at least qualitative assessments that will allow us to make statements as the one above: “not objectoriented”. The first contribution of the present paper is to make teachers aware that there are indeed several perspectives on what objects are and thus what object-oriented design embodies and that these perspectives often delimit the kind of designs that we teach and delimit the kind of systems our students are able to produce. Second, we provide a coarse grained classification of perspectives that we have encountered in objects-first teaching books as well as other design books. Third, we illustrate by a small example how choice of perspective may derive quite different designs for the same set of requirements. Finally, we have identified one of the perspectives as superior when it comes to explaining design patterns and frameworks.

2. WHAT ARE OBJECTS? Researching for this paper, we took a look at definitions in a random selection of recent objects-first teaching books and other design books and found this small collection of object definitions. The (l), (m), (r)-prefixes classify perspective as explained in detail below.

(l) A class definition encapsulates its objects’ data and actions. [16, p. 61] (l) An object is a program construction that has data (that is, information) associated with it and that can perform certain actions. [17, p. 17] (l) A class definition describes the behavior and attributes of typical instances of that class. [2, p. 36]

Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. ITiCSE’05, June 27–29, 2005, Monte de Caparica, Portugal. Copyright 2005 ACM 1-59593-024-8/05/0006 ...$5.00.

(l) An object is defined by a class, which can be thought of as the data type of the object. [14, p. 62] (l) An object is characterized by its state, behavior, and identity. [8, p. 39] (m) Model elements in Java programs are called objects.[1, p. 4]

(m) Java objects model objects from a problem domain. [3, p. 3] (r) The best way to think about what an object is, is to think of it as something with responsibilities. [18, p. 16] (r) An object-oriented program is structured as a community of interacting agents called objects. Each object has a role to play. Each object provides a service or performs an action that is used by other members of the community. [6, p. 9]

representation in model [10, p. 20] thus coupling the model centric and language centric perspective. A similar notion can be found in Kafura [11, p. 17].

3.

TEACHING OBJECTS AND DESIGN

Does the perspective influence how we teach objects and how students program and design? Of course! Designing any object-oriented system poses the fundamental questions: What objects do we need? What behaviors are required? How do we distribute behavior over the set of objects? Even in inLooking over these perspectives there seems to be three predomitroductory object design the students must face this challenge. The nant perspectives on what an object is. We will denote these: landifferent perspectives offer different guidelines and mindsets, and guage centric perspective (l), model centric perspective (m), and will ultimately lead to different design proposals. responsibility centric perspective (r) respectively. The first two perspectives focus predominately on the static asThe focus of the language centric perspective is classes and obpects: classes in the language centric world and model parts in jects as concrete building blocks for building software. The emphathe model centric world. It is therefore not surprising that examsis is on the internal structure: fields and methods. Thus it is inherples, design processes, and rules take their starting point here. The ently a compile-time or static view—the definition speaks in terms general agenda is A) find the objects (classes, fields) and their reof what we see in our editor: stuff like int x; and public lations (inheritance, association, aggregation) and B) define their void foo() { ...} . The implicit aspect of this view is that behaviors (methods). An experienced software developer will use an object is an entity in its own right—the definition is closed and a more implicit and fluent design agenda—but inexperienced stuany object can be understood in isolation—you simply enumerate dents are left with little choice but to stick to the proposed agenda. the fields and methods and you are done. The advantage of this The implication is that the structural, static, aspects are laid out first perspective is of course that it is very concrete, closely related to (classes and their relations) and the next challenge is to “distribute” the programming language level, and therefore relatively easy to behavior over this fixed landscape. understand at an introductory level. The disadvantage is, however, The model centric perspective offers the guideline to view comthat it remains relatively silent about how to structure the collaboputation as simulation of a model, and usually the model is an ration and interplay between objects, the dynamics, and this is typabstraction of part of the real world. This works fine for, say, ically where the hard challenges of design lie. Thus the perspective an order-entry system, a library system, boat-rental, and numeroffers little guidance in the process of designing any realistic sysous other real-world entity oriented systems. However, there are tem. It is the perspective that is most prominent in our little survey also many domains where this guideline provides little help. As a of text books. recurring example, how do you structure the graphical user interThe model centric perspective perceives objects as parts in a face for a system? What is the real-world part that the GUI must wider context namely a model. This view has roots tracing back to the Simula tradition of simulation, Scandinavian object-orientation [15], simulate? GUIs are purely computational aspects over and above the real world domains and as such cannot drive the object design as well as the Alan Kay notion of computation as simulation [12]. process. Here the program execution is a simulation of some part of the The focus in the responsibility centric view is on abstracting the world, and objects are perceived as the model’s parts. The perspecdynamics. As noted by Budd: “Why begin the design process with tive is often explained through analogies to other models like toy an analysis of behavior? The simple answer is that the behavior of railways, traffic simulations, computer games, etc. This perspeca system is usually understood long before any other aspects.” [6, tive stresses objects as entities in a larger context (they are parts of p. 51]. Thus this perspective in a way reverses the agenda: first a model) as opposed to the self-contained language centric definiidentify responsibilities, group them into roles, define the collabotion. This naturally leads to a strong focus on what the relations are ration patterns between roles, and then identify the objects that can between the parts: association, generalization, composition. Dyplay these roles. namics is an inherent part of the concept simulation and the explicit Budd calls it the “what/who cycle” in that the activity needed guideline for designing object interaction is to mimic real world or (what) is determined before we assign it to someone (who). The model interactions. Many books, however, put their emphasis on model centric perspective can thus be recast as the opposite: a parts and relationships much more than on interactions. “who/what cycle”. This “what/who” kind of analysis, while perIn the responsibility centric perspective a program’s dynamics is haps new to some in a programming context, is often seen in orthe primary focus as evident in descriptions like: interacting comganizational settings. Cumbersome or error prone processes ofmunity of objects, their responsibilities to the community. Here the ten result in reorganizations where new roles and responsibilities central concepts are ‘role’ and ‘responsibility’ and thus the couare identified first, and people are assigned to these second. As pling to behavior in contrast to static elements like objects or model a simple example a pre-school kindergarten had the problem that parts. The distinction between responsibility and behavior is imthe teachers were constantly interrupted in their activities with the portant: Behavior is the concrete actions taken by objects while children to answer the phone, deliver messages from parents, fetch responsibility is the more abstract “obligation to fulfill request” meals, etc. They responded by defining a new role, the flyer, whose through any number of concrete behaviors. This perspective can responsibility it was to answer all phone calls, bring all the meals, be traced back to the focus on responsibilities in the CRC cards [5] etc. Thus all other teachers were relieved of these tasks and allowed and the later responsibility-driven design [20]. One may see the reto pay attention to the children without interruptions. The teachers sponsibility perspective as an extension of the model centric view then made a schedule taking turns on having the role as flyer. with an important shift of focus: from a focus on model parts to a The role concept is inherently linked to “loose-coupling” in a focus on the simulation/dynamical aspects. software design context. A role based design decouples specific Some authors are explicit about perspectives. Jia lists two deobjects from the roles they may play in the design. This way, roles finitions of an object as either interpretation in the real world or

may be played by different objects over the life-time of the execution; and a single object may play several roles (as is often the case for persons in small organizations). In languages like Java this is realized by concrete classes implementing several interfaces.

3.1

Teaching guidelines

To aid students in making responsibility centric designs, we give them two guidelines. The first guideline is to try to complete the following statement: There must be an object that is responsible for . . . and keep on doing so until all requirements of the specification are covered. This changes the focus from objects/parts towards the dynamics and roles in the system. Needless to say, it is not easy for the students to hit the right level of abstraction! As an example from the backgammon case in the next section, students’ answers may be very programming oriented like “there must be an object that is responsible for implementing the ‘move’ method”—in the other end of the spectrum answers are at a too high level like “there must be an object that is responsible for handling the backgammon game”. The second guideline is to think of the program execution as an organization having managers, experts, workers, etc. This requires the students to think in terms of the interplay and collaboration between roles. It is related to the metaphor design principle known from eXtreme Programming [5]. Note that this guideline is actually a model centric perspective: the program execution simulates an organization.

4.

CASE STUDY: BACKGAMMON

As a case to ground the previous discussion and show some perspective implications we will outline an exercise that has been serving a ‘programming in the large’ course as mandatory exercise for some years. The case is designing a partial implementation of the board game Backgammon. In the discussion below, we will focus on the backgammon domain and ignore the graphical user interface, AI, etc. Backgammon in itself is less interesting but is used here as representative of behavior oriented systems as opposed to real-world entity oriented systems—i.e. the challenge and complexity is in designing the behavioral aspects (handling who’s turn it is, validation of legal moves, etc) much more than in finding and relating the entities (checkers, dice, etc.) Note that our intention in this section is to demonstrate that the responsibility centric perspective will produce a superior design with respect to the qualities of maintainability and flexibility as quality yardstick for behavior oriented systems. The intention is not to champion one perspective over the others, rather the intention is to show that ideally students and designers should master several perspectives and be able to combine and switch between perspectives. In some situations the model centric perspective is most fruitful and in others the responsibility centric, and in crafting the program the mastery of the language centric perspective is of course fundamental.

4.1

Model centric design

The model centric perspective tells us to make a model of part of the world. Backgammon seems ideal because the physical parts are easily identifiable: checkers, points, board, dice, player, etc. Figure 1 is a plausible design of model parts (classes) and their relationships (relations). It is essentially a conceptual diagram as defined by Fowler [7]. It is also very simple, almost mechanical, to translate this diagram into working object-oriented source code

Figure 1: A plausible design using a model perspective.

in, say, Java. Of course, the above diagram is not the ultimate truth, indeed every year we engage in discussions with students over whether this or that relation is proper, if the bar is really a specialization of point or this is unnecessary, whether to include rules as a concept, etc. Nevertheless most discussions are derivations from the above. Now comes the tricky part, however, namely to get the behavior distributed in a ‘nice’ way over this collection of classes. The primary idea of computer backgammon is to serve as a referee, thus a fundamental challenge is validation of moves. Backgammon has a well-defined set of rules that defines whether a given move is legal or not. Basically the roll of the two dice dictates how far a player may move his checkers: rolling a (3,6) means he can move one checker 3 points towards his home base, and one checker 6 points. However, there are a lot of special rules: If a player has checkers in the bar, these must be put back into play before any checkers on the board are allowed to move; red’s checkers cannot move to points where black has two or more checkers located; etc. Thus to validate if a move is legal the algorithm must access state that naturally reside in the point, checker, die, board, player, and bar abstractions. None of these abstractions are the “natural born” place to host the behavior. The result is that behavior easily ends up being spread thinly over the set of classes. Such a proposal is characterized by tight coupling: to validate a move almost all objects in this design will be involved; and low cohesion: every object has some part of the validation but validation itself is not a cohesive whole. As a consequence, the maintainability [4] of the proposed design is poor. For instance, there are numerous variants of the backgammon game: Acey-ducey, Tapa, etc. The board looks the same, same number of checkers, two players, a set of dice—but the rules of movement, turn taking, and entry and exit of checkers on the board are different. To implement such variants, every class must be inspected and changed and a global overview must be kept to avoid introducing defects in the system. To implement a system where validations may be changed dynamically at run-time is even more cumbersome. Of course, the presented design may be improved while keeping in line with the model centric view. One may add a “referee” concept that handles turn handling, move validation, etc. This object, however, will show a strong tendency towards a procedural design as almost all behavior will end up here. This is also known as the blob anti-pattern. Another possibility is to add a “rule set” concept that may contain individual rules for turn handling, validation, dice rolling, etc. The problem here is that e.g. turn handling is behaviorally very different from move validation. Yet another possibility

is to introduce concepts like “turn” and “move” but these are by nature events and thus transient.

4.2

Responsibility centric design

How will a design look like if we take a responsibility centric perspective? We use our rule-of-thumb: There must be an object that is responsible for . . . to generate a list more or less like this: 1. There must be an object that is responsible for validation of moves. 2. There must be an object that is responsible for handling the dice: rolling and knowing the die values. 3. There must be an object that is responsible for handling the board: moving and knowing the position of checkers. 4. There must be an object that is responsible for keeping track of turns: number of moves left and which player is in turn. You may come up with other lists but the main point is that we have started with behavior in abstract terms and still not decided on any particular assignment to concrete classes. This is the “what” cycle, next comes the “who” cycle. A radical design proposal, outlined in Figure 2, is simply to create special purpose objects just to fulfill these responsibilities. This is what Larman denotes the pure fabrication responsibility assignment pattern [13]—objects are made up simply to serve responsibilities. Interestingly Larman describes pure fabrication as a “when we’re desperate” kind of pattern [13, p. 421]. Using the responsibility centric perspective, there is absolutely nothing desperate about this kind of assignment—but Larman’s statement may be interpreted as the realization that the model centric perspective has to give up in certain situations. This design basically defines a role (expressed as an interface) for each of the coarse grained responsibilities defined above. Like in an organization where the work of individuals must be concerted and coordinated we have a ‘manager’ role: the Backgammon abstraction becomes the manager and falls out as the mediator pattern that does the coordination. This has a number of consequences. First, insisting that a given responsibility is the sole responsibility of a single object and no other objects must be involved is radical, and is in somewhat conflict with the normal OO agenda of “keeping data and behavior together”. As an example consider the “MoveValidator” role. If validating moves is confined to this object then we must accept that the board does not make any validation at all. The counter argument may be that board is really the object that knows checker positions, so why is this not the proper place to put partial, simple, validation like the obvious rule that a checker cannot be moved to a point that contains two opponent checkers, etc.? We will address this concern shortly. The elegance of this design is that backgammon variants are typically expressed in terms of new rules for what constitutes a legal move. By objectifying validation we have essentially introduced the strategy pattern. The game instance forwards move validation to the validation object; and changing the rule set is thus a matter of changing the object this forwarding goes to. The object that is responsible for interaction with the user can be interpreted as a Facade pattern and as a Mediator pattern coordinating the work of the interior objects. A natural facade method like ‘move’ can be realized like:

Figure 2: A plausible design using a responsibility perspective.

public boolean move(Location from, Location to) { boolean valid = getMoveValidator().isValid(from, to,); if (valid) { getBoard().move(from, to); [...] } return valid; }

The point here is: how would this code look like if the board object had partial responsibility for validating the move? Well, the above code could not be made this simple because the method would have to ask more objects before deciding to actually make the move. Even worse is the situation where the Board.move returns a boolean indicating that the move was not accepted. Then the two would be fighting over the responsibility with the obvious threat of code duplication and misunderstandings. Finally, there is actually no problem in the Board having a responsibility to provide partial validation as long as this service is provided as a separate behavior de-coupled from the Board’s move method. An example is a method that tests whether the location the user wants to move to is blocked by the opponent. This way the MoveValidator may call this method or not. Indeed, there are backgammon variants where locations cannot be blocked, and thus the move validator for this variant can simply avoid using this method.

5.

DISCUSSION

The backgammon case above may leave the reader with the impression that the agenda of this paper is to agitate for the responsibility centric perspective as a better perspective on object-oriented programming. This is not so. The point is that all perspectives have

their natural area of applicability, and if we are not aware of these and do not expose students to them it has consequences for what kind of design problems we deal with, what problems our students can tackle and how our students learn to think about design and programming. Ultimately, our focus and perspective will mark and skew the software our students will produce for many years after they leave our institutions. Another important message is that text-books typically have an implicit perspective that is not always obvious. Awareness of this is important for us as teaching professionals in order to broaden the discussion. Having said this, however, we must confess a bias towards the responsibility centric approach as a strong extension to the model centric approach. We have ourselves been deeply rooted in the model centric tradition but have during the last five years had strong focus on topics like design patterns and frameworks that strive for highly flexible and reusable software. It thus became more and more pressing to understand how these techniques could be explained by the model centric view. The problem was that it proved difficult to find this fit. We ended up talking about the benefits of the model centric perspective first, introducing patterns as ‘programming tricks’ later, but concerning the link between the two, the message to students was something along the lines of “model centric cannot stand alone”. For instance, the observer pattern is simply difficult to understand as “parts of a model” or “simulation of the real world”. Yet the observer pattern is an ideal solution to a recurring problem. In the responsibility centric perspective, however, the observer pattern is easy to explain: the ‘subject’ is a simply a role some object must play and the role defines the responsibilities of keeping data and notify observers when the data change. Similar, the ‘observer’ is a role that other objects may play. In a double-observer chain, used in e.g. JHotDraw [9], one object even plays both roles. This observation is strengthened by research in knowledge engineering where the notion of role is argued to be as fundamental as that of object and relationship [19]. Another important observation is that design patterns seem to appear naturally in responsibility oriented designs. In model centric designs, patterns often have to be ‘engineered into’ the design to achieve flexibility. In responsibility centric design, behaviors are already much more factored out, leading to especially behavioral and creational patterns coming rather naturally: “There must be an object responsible for validating moves” = strategy, “There must be an object responsible for creating a particular backgammon variant” = abstract factory, etc. Perhaps, the model centric perspective makes good application designs whereas the responsible centric perspective makes good framework designs. . .

6.

CONCLUSION

In this paper we have discussed and classified various perceptions of what object-oriented programming is and argued how this inevitably influences the designs we make and present to our students. We have used a small example to illustrate how perspective may drive a design in different directions with consequences for the resulting design’s qualities. Our main points are that we as teaching professional must be aware of the perspective that is often very implicit in text-books: that the perspective delimits the problem areas that we and our students can tackle successfully; and that awareness of the different perspectives augments our abilities as designers. We have found that engineering techniques like design patterns and frameworks are difficult to match with the model centric per-

spective and found a better fit in the responsibility centric perspective. We therefore find it important to consider this perspective in courses that introduce and analyze patterns and frameworks. We have found that instead of engineering patterns into model centric designs the responsibility centric perspective has a tendency to produce designs where patterns appear naturally instead.

Acknowledgements Thanks to Bruce J. Klein and the anonymous reviewers for comments. The Center for Pervasive Computing, AUFF grant F-2003FLS-1-22, supported this research.

7.

REFERENCES

[1] Arnow, D., and Weiss, G. Introduction to Programming Using Java: An Object-Oriented Approach, 2nd ed. Addison-Wesley, 2000. [2] Barnes, D. J. Object-Oriented Programming with Java - An Introduction. Prentice Hall, 2000. [3] Barnes, D. J., and Kolling, M. Objects First with Java: A Practical Introduction Using BlueJ, 2nd ed. Prentice Hall, 2005. [4] Bass, L., Clements, P., and Kazman, R. Software Architecture in Practice, 2nd Ed. Addison-Wesley, 2003. [5] Beck, K. eXtreme Programming Explained. Addison-Wesley, 2000. [6] Budd, T. An Introduction to Object-Oriented Programming. Addison-Wesley, 2002. [7] Fowler, M. UML Distilled, 2nd Edition. Addison-Wesley, 1999. [8] Hortsmann, C. Object-Oriented Design and Patterns. Wiley, 2004. [9] JHotDraw. http://jhotdraw.sourceforge.net/. [10] Jia, X. Object-Oriented Software Development Using Java. principles, patterns, and frameworks. Addison-Wesley, 2002. [11] Kafura, D. Object-Oriented Software Design and Construction with Java. Prentice Hall, 2000. [12] Kay, A. Microelectronics and the Personal Computer. Scientific American 237, 3 (1977), 230–244. [13] Larman, G. Applying UML and Patterns, 3rd ed. Prentice Hall, 2005. [14] Lewis, J., and Loftus, W. Java Software Solutions: Foundations of Program Design. Addison-Wesley, 2003. [15] Madsen, O. L., Møller-Pedersen, B., and Nygaard, K. Object-Oriented Programming in the BETA Programming Language. Addison Wesley, 1993. [16] Morelli, R. Java, Java, Java: Object-Oriented Problem Solving. Prentice Hall, 2000. [17] Savitch, W. Java: An Introduction to Computer Science and Programming. Prentice Hall, 2001. [18] Shalloway, A., and Trott, J. R. Design Patterns Explained: A New Perspective on Object-Oriented Design, 2nd ed. Addison-Wesley, 2004. [19] Steimann, F. On the representation of roles in object-oriented and conceptual modelling. Data & Knowledge Engineering 35 (2000), 83–106. [20] Wirfs-Brock, R., and McKean, A. Object Design – Roles, Responsibilities, and Collaborations. Addison-Wesley, 2003.