unit 1 general introduction

65
Unit 1 General Introduction Summary prepared by Kirk Scott 1

Upload: frayne

Post on 22-Feb-2016

38 views

Category:

Documents


0 download

DESCRIPTION

Unit 1 General Introduction. Summary prepared by Kirk Scott. Design Patterns in Java Part V Extension Patterns Chapter 26 Introducing Extensions. Summary prepared by Kirk Scott. The Introduction Before the Introduction. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Unit 1 General Introduction

1

Unit 1General Introduction

Summary prepared by Kirk Scott

Page 2: Unit 1 General Introduction

2

Design Patterns in JavaPart V

Extension PatternsChapter 26

Introducing Extensions

Summary prepared by Kirk Scott

Page 3: Unit 1 General Introduction

3

The Introduction Before the Introduction

• It seems to me that this chapter really doesn’t make clear what the extension patterns are

• In part, the book uses it to do a little review of specific patterns that have been introduced so far

• That isn’t of too much value• What is interesting, though, is the introduction

of some more object-oriented design principles

Page 4: Unit 1 General Introduction

4

• Concepts like encapsulation come up early in OO design, and recur in this book

• In addition, we have seen many practical applications of interfaces, polymorphism, and dynamic binding in this book

• There was a whole section on the topic of responsibility, and how distributed responsibility is the norm, but responsibility can also be usefully concentrated in some cases

Page 5: Unit 1 General Introduction

5

• In numerous patterns, the related topic of coupling also arose

• Loose coupling is generally desirable• Ideally, objects are independent of each other• Sometimes a change in one will trigger a

change in another

Page 6: Unit 1 General Introduction

6

• Loose coupling might be thought of as meaning fewer connections

• This would mean fewer places where you had to worry about a change in one propagating to another

• As usual, there are also cases where tighter coupling is desirable

Page 7: Unit 1 General Introduction

7

• This chapter adds two major items to the list of object-oriented design principles:

• The Liskov Substitution Principle• The Law of Demeter• It’s not immediately apparent that these concepts are

directly related to any one of the design patterns under consideration

• However, they are interesting in their own right, and draw together some important insights that apply to OO design in general, and might apply to the development of any one design pattern

Page 8: Unit 1 General Introduction

8

Introducing Extensions

• Book material:• In general, extension is based on this idea:• You rarely write code in a vacuum• You have an existing code base and your task is

to add new features, classes, applications to it• In this sense, the term extension basically just

means programming within the context of given code

Page 9: Unit 1 General Introduction

9

• The book’s motivation for introducing general object-oriented design principles at this point is the following:

• As a programmer, extending a code base, it would be helpful to have some rules of thumb to decide whether or not the code you are adding is any good

Page 10: Unit 1 General Introduction

10

• Extension may also refer to specific techniques for adding features to a code base

• In addition to looking at general principles, the book does two other things in this chapter:

• It looks back at some earlier patterns that have an element of extension to them

• It previews some of the extension design patterns that will be covered in the rest of the section

Page 11: Unit 1 General Introduction

11

Principles of Object-Oriented Design

• For people interested in the topic of patterns, the book cites this Web site: www.c2.com

• There is no need to go there for the purposes of this course

• From that page there is a link to a Wiki with a collection of patterns that goes beyond the ones covered in the book

Page 12: Unit 1 General Introduction

12

The Liskov Subsitution Principle (LSP)

• One of the aspects of object-orientation that should be familiar to you is the following:

• A subclass is in an “is-a-kind-of” relationship with its superclass

• In general, a subclass is a more specific kind of the superclass

• At the very least, it has the same set of instance variables, since instance variables can’t (or shouldn’t) be overridden

Page 13: Unit 1 General Introduction

13

• The subclass is made more specific by having more instance variables

• It is also made more specific by overriding methods, if necessary

• In Java, it’s always syntactically possible to have a superclass reference to a subclass object

Page 14: Unit 1 General Introduction

14

• The superclass reference won’t have access to the instance variables and unique methods of the subclass

• However, the superclass reference will have access to any methods inherited by the subclass

• It will also have access to any methods overridden in the subclass

Page 15: Unit 1 General Introduction

15

• The ability to have superclass references is important when defining method parameters in an inheritance hierarchy

• A method defined in a superclass with a superclass explicit parameter doesn’t have to be overridden in the subclass, with the explicit parameter re-typed to the subclass, in order to be used with a subclass explicit parameter

Page 16: Unit 1 General Introduction

16

• The book states that subclasses should be logical, consistent extensions of their superclasses

• Trying to define the meaning of logical and consistent leads to the Liskov Substitution Principle

• The book paraphrases the principle as follows:• “An instance of a class should function as an

instance of its superclass.”

Page 17: Unit 1 General Introduction

17

• As noted, Java expects this and supports it syntactically

• The real question is whether or not the internal logic of classes for a given problem domain agree with this

• The book gives two problematic examples on which are shown on the next overhead

Page 18: Unit 1 General Introduction

18

Page 19: Unit 1 General Introduction

19

• The Machine/UnloadBuffer example illustrates questions that arise in the problem domain

• Superficially, you might want to class UnLoadBuffers with Machines

• However, the book notes the following:• According to the way their factory is set up, you

can’t add tubs to an UnloadBuffer, which implies that you also could not get tubs associated with an UnloadBuffer

Page 20: Unit 1 General Introduction

20

• If all other machines have this characteristic, you have a design problem

• Do you force the implementation of addTub() and getTubs() into each subclass of machine, when all of that code will be duplicate?

• Do you implement the UnloadBuffer class outside of the Machine hierarchy?

• Do you leave the UnloadBuffer in the hierarchy and leave the methods in Machine?

Page 21: Unit 1 General Introduction

21

• The UML diagram shows the last choice, with addTub() and getTubs() overridden in UnloadBuffer

• What should you do if it is not possible to call these methods on an UnloadBuffer, throw an exception?

• This puts the burden on client code to catch exceptions for a faulty design

Page 22: Unit 1 General Introduction

22

• An alternative would be to have the overridden versions of the method do nothing

• This is even worse• What happens to a tub after a call has been

made to add it to an UnloadBuffer?• Does it go into outer space?

Page 23: Unit 1 General Introduction

23

• The point is that this is a bad design, and the problem with the design can be identified as a violation of the Liskov Substitution Principle

• The problem is that it is not possible to use an instance of an UnloadBuffer anywhere that you use an instance of a machine

• The UnloadBuffer class doesn’t seem to be a proper subclass of the Machine class

Page 24: Unit 1 General Introduction

24

• The book continues by observing that it may sometimes be useful to violate the principle

• This seems to be eternally true in software development

• The additional requirement when you do this is to clearly identify the violation

• Justify it• And identify and deal with all possible

consequences

Page 25: Unit 1 General Introduction

25

• In the chapter on bridges/drivers, a somewhat analogous situation arose

• The choice had to do with how many methods you put into an interface

• Did you put a subset of methods in, so that all implementing classes could implement them?

• Or did you put a superset of methods in, forcing some of the implementing classes to have bogus implementations?

Page 26: Unit 1 General Introduction

26

• The second option was more flexible, in the sense that all possible methods were supported in all cases where they were valid

• The shortcoming was that they also existed in cases where they weren’t valid

• As long as the invalid cases didn’t cause any harm—or it was possible to detect and deal with invalid cases in client code, then the advantages might outweigh the disadvantages

Page 27: Unit 1 General Introduction

27

• Challenge 26.1• A circle is certainly a special case of an ellipse,

or is it? Say whether the relationship of the Ellipse and Circle classes in Figure 26.1 is a violation of LSP.

Page 28: Unit 1 General Introduction

28

• Solution 26.1• In mathematics, a circle is certainly a special case

of an ellipse. However in OO programming, an ellipse has certain behaviors that a circle does not. For example, an ellipse may be twice as wide as it is tall; a circle can’t do that. If that behavior is important to your program, a Circle object won’t function as an Ellipse object and will represent a violation of LSP.

Page 29: Unit 1 General Introduction

29

• Note that if you’re considering immutable objects, this may not be apply. This is simply an area in which naïve mathematics is not a smooth fit for the semantics of standard type hierarchies.

Page 30: Unit 1 General Introduction

30

The Law of Demeter (LoD)

• Demeter• From Wikipedia, the free encyclopedia

Page 31: Unit 1 General Introduction

31

• In Greek mythology Demeter (pronounced /dəˈmiːtər/; də-MEE-tər; Greek: Δημήτηρ, Dēmētēr, probably "earth-mother")[1][2] was the goddess of the harvest, who presided over grains, the fertility of the earth, the seasons (personified by the Hours), and the harvest. Though Demeter is often described simply as the goddess of the harvest, she presided also over the sanctity of marriage, the sacred law, and the cycle of life and death. She and her daughter Persephone were the central figures of the Eleusinian Mysteries that also predated the Olympian pantheon.

• Her Roman cognate is Ceres.

Page 32: Unit 1 General Introduction

32

Page 33: Unit 1 General Introduction

33

• The book quotes a paper by Lieberherr and Holland on the Law of Demeter:

• “Informally, the law [of Demeter] says that each method can send messages to only a limited set of objects: to argument objects, to the [this] pseudovariable, and to the immediate subparts of [this].”

Page 34: Unit 1 General Introduction

34

• Stated more explicitly, the law goes like this:• When writing method code, you may be

working with the implicit parameter and an explicit parameter

• You can call methods directly on the implicit parameter

• You can also call methods on the instance variables of the implicit parameter

Page 35: Unit 1 General Introduction

35

• Keep in mind that the method you’re writing is in the class of the implicit parameter, so you have direct access to the instance variables of the implicit parameter

• You can also call methods directly on the explicit parameter

• However, you can’t call methods on the instance variables of the explicit parameter

Page 36: Unit 1 General Introduction

36

• In summary, you’re allowed to call methods on objects that you have a direct reference to

• You shouldn’t be calling methods second-hand• In other words, if you have to call a get

method to get a reference to an instance variable of something, you shouldn’t then be calling a method on that object

Page 37: Unit 1 General Introduction

37

• You may recall that I was complaining about a violation of encapsulation in the last chapter

• In CS 202 it was pointed out that you can avoid some encapsulation violation problems if get methods for instance variables that are references return clones

• On the other hand, in the last chapter the problem was that client code unavoidably retained a reference to an object that had been sent in as a construction parameter to another object

Page 38: Unit 1 General Introduction

38

• In the scenario under consideration for the Law of Demeter, there may be no violation of encapsulation

• Or a formal violation of encapsulation could be fixed by returning a clone

• However, the law still applies, and that’s why it’s not simply a formal violation of encapsulation

Page 39: Unit 1 General Introduction

39

• The book points out that this can be easier to understand if you consider cases that would violate the Law of Demeter

• They set up this scenario• There is a MaterialManager object with a

method X that takes a Tub object (named tub in the book) as an explicit parameter

• Tub objects have a location instance variable

Page 40: Unit 1 General Introduction

40

• A location is a machine, for example• A machine has an instance variable that tells

whether the machine is up or down• In the code for method X, you could write code

like this:• if(tub.getLocation().isUp()){

• …• }

Page 41: Unit 1 General Introduction

41

• According to the Law of Demeter, it’s OK to call tub.getLocation()

• That’s just one level deep into the explicit parameter

• That call returns a reference to the location instance variable of the tub

• The Law of Demeter says that calling a method on that reference is not OK

Page 42: Unit 1 General Introduction

42

• Challenge 26.2• Explain why the expression

tub.getLocation().isUp() might be viewed as unhealthy.

Page 43: Unit 1 General Introduction

43

• Solution 26.2• The expression tub.getLocation().isUp() might

lead to programming errors if there are any subtleties around the value of a tub object’s Location property. For example, the location might be null or might be a Robot object if the tub is in transit. If location is null, evaluating tub.getLocation().isUp() will throw an exception.

Page 44: Unit 1 General Introduction

44

• If the location is a Robot object, the problem may be even worse, as we try to use a robot to collect a tub from itself. These potential problems are manageable, but do we want the ensuing code to be in the method that uses the tub.getLocation().isUp() expression? No. The necessary code may already be in the Tub class! If not, it belongs there. To prevent us from having to recode around the same subtleties in other methods that interact with tubs.

Page 45: Unit 1 General Introduction

45

• The book’s challenge solution is complete and correct

• It might benefit from a summary• If method X deals with tubs, then it would be

nice if it were protected from having to deal with the internals of tubs

• The book’s challenge solution suggests a general approach

Page 46: Unit 1 General Introduction

46

• I offer an alternative approach which is not necessarily good, but which emphasizes the idea of the level to which the code of method X should have to go

• If method X deals with tubs, and is ultimately concerned with whether or not a tub’s location is up or down, then maybe a new method should be added to the Tub class

Page 47: Unit 1 General Introduction

47

• It could be tentatively named something like, isMyLocationUpOrDown()

• Formally, at least, method X could be written without violating the Law of Demeter

• Instead of this:• tub.getLocation().isUp()• You could write this:• tub.isMyLocationUpOrDown()

Page 48: Unit 1 General Introduction

48

• The code for method X is protected from having to know what the interface or internals of the Location class are

• It only has to know the interface for the Tub class, which is the class that it works with directly

Page 49: Unit 1 General Introduction

49

• The book goes on to say that the Law of Demeter is more subtle than this:

• “Expressions of the form a.b.c are bad.”• The law is based on an understanding of things like

coupling and responsibility, where you are actively trying to avoid foreseeable problems that would result if you didn’t follow the law

• As always, there may be cases where you know you are violating the law, but some other consideration causes you to do so

Page 50: Unit 1 General Introduction

50

Removing Code Smells

• The title of this subsection is unfortunate• To the same degree, the content is also unfortunate• The book mentions that some authors have

identified certain signs of poorly written code• They mention one source in particular,

“Refactoring: Improving the Design of Existing Code” by Fowler et al.

• This contains 22 signs that code can be improved by refactoring

Page 51: Unit 1 General Introduction

51

• As for referring to the signs as smells, could you get any more childish?

• The only outcome of that approach that I can foresee is a dialog along these lines:

• “Your code smells.”• “No, your code smells.”• It’s a completely unproductive way of looking

at things

Page 52: Unit 1 General Introduction

52

• If you have to resort to the term “smells” in order to describe what’s wrong, it’s a sign that your analytical or expressive abilities are lacking

• The book has a challenge in this subsection• I refuse to dignify it by including it in the

overheads• It’s useless anyway• There’s no way to answer it unless you’re already

familiar with one of the 22 signs…

Page 53: Unit 1 General Introduction

53

Beyond Ordinary Extensions

• This is the subsection where the authors want to review patterns that have already been given and relate them to the idea of extensions

• They go all the way back to the great-granddaddy of patterns, our friend, Adapter

Page 54: Unit 1 General Introduction

54

• One developer may provide a service and an interface for using it

• Other developers may write the application code that makes use of the service

• The extension point of view may be applied in lots of situations where code writing responsibility is divided among different developers

Page 55: Unit 1 General Introduction

55

• The authors review patterns already given that exhibit extension characteristics by means of the challenge contained in the table on the following overhead

Page 56: Unit 1 General Introduction

56

Page 57: Unit 1 General Introduction

57

• Solution 26.4• One set of solutions is:• [See the following overhead.]

Page 58: Unit 1 General Introduction

58

Page 59: Unit 1 General Introduction

59

• The book now introduces the extension design patterns that will be covered in the remaining chapters by means of the table on the following overhead

Page 60: Unit 1 General Introduction

60

Page 61: Unit 1 General Introduction

61

Summary

• The authors describe code writing as a process of extension followed by refactoring

• Fair enough• I always describe it as copying existing code,

adapting it, and then debugging—repeat as necessary…

• The authors also state that there is no complete, objective technique for assessing code quality

Page 62: Unit 1 General Introduction

62

• The Liskov Substitution Principle provides one guideline for writing good code

• You need to be able to identify and justify and violations of this that might exist in code you write

• The Law of Demeter is another guideline for writing good code

Page 63: Unit 1 General Introduction

63

• The authors summarize this by saying that applying the Law of Demeter reduces dependencies between classes

• This goes back to distributed responsibility and loose coupling as the default ideals for OO code design

• You need to be able to identify and justify and violations of this that might exist in code you write

Page 64: Unit 1 General Introduction

64

• Other authors have identified problems that occur in code design

• They have also identified preferable refactorings• Some of the refactorings are to recognizable

design patterns• Lots of design patterns can be understood as

tools for extending existing pieces of code or coordinating the tasks of different programmers in developing a complete system

Page 65: Unit 1 General Introduction

65

The End