Design Patterns in Java Chapter 13 Flyweight Summary prepared by Kirk Scott 1.

Slides:



Advertisements
Similar presentations
CS 350 – Software Design The Bridge Pattern – Chapter 10 Most powerful pattern so far. Gang of Four Definition: Decouple an abstraction from its implementation.
Advertisements

Singleton vs utility class  at first glance, the singleton pattern does not seem to offer any advantages to using a utility class  i.e., a utility class.
Overview of Data Structures and Algorithms
Composition CMSC 202. Code Reuse Effective software development relies on reusing existing code. Code reuse must be more than just copying code and changing.
Chapter 3 Stoichiometry.
Chapter 10 THINKING IN OBJECTS 1 Object Oriented programming Instructor: Dr. Essam H. Houssein.
CS 106 Introduction to Computer Science I 04 / 11 / 2008 Instructor: Michael Eckmann.
Chapter 8 Inheritance Part 2. © 2004 Pearson Addison-Wesley. All rights reserved8-2 Outline Creating Subclasses Overriding Methods Class Hierarchies Inheritance.
Inheritance Inheritance Reserved word protected Reserved word super
The Bridge Pattern.. Intent Decouple an abstraction from its implementation so that the two can vary independently Also known as: Handle/Body.
More Interfaces, Dynamic Binding, and Polymorphism Kirk Scott.
Liang, Introduction to Java Programming, Sixth Edition, (c) 2007 Pearson Education, Inc. All rights reserved Chapter 1 Object-Oriented.
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
Design Patterns in Java Appendix D UML at a Glance Summary prepared by Kirk Scott 1.
Interfaces. In this class, we will cover: What an interface is Why you would use an interface Creating an interface Using an interface Cloning an object.
CS 106 Introduction to Computer Science I 11 / 15 / 2006 Instructor: Michael Eckmann.
Aalborg Media Lab 23-Jun-15 Inheritance Lecture 10 Chapter 8.
Classes, Encapsulation, Methods and Constructors
Chapter 13: Object-Oriented Programming
What Is a Factory Pattern?.  Factories are classes that create or construct something.  In the case of object-oriented code languages, factories construct.
Design Patterns in Java Chapter 18 Prototype Summary prepared by Kirk Scott 1.
Liang, Introduction to Java Programming, Seventh Edition, (c) 2009 Pearson Education, Inc. All rights reserved Chapter 12 Object-Oriented Design.
Singleton Christopher Chiaverini Software Design & Documentation September 18, 2003.
Lecture 18 Page 1 CS 111 Online Design Principles for Secure Systems Economy Complete mediation Open design Separation of privileges Least privilege Least.
Design Patterns in Java Chapter 21 Template Method Summary prepared by Kirk Scott 1.
Recap (önemli noktaları yinelemek) from last week Paradigm Kay’s Description Intro to Objects Messages / Interconnections Information Hiding Classes Inheritance.
4.1 Instance Variables, Constructors, and Methods.
Unit 4 Prototype Summary prepared by Kirk Scott 1.
Unit 4 Prototype Summary prepared by Kirk Scott 1.
Design Patterns in Java Chapter 1 Introduction Summary prepared by Kirk Scott 1.
Unit 18 Strategy Summary prepared by Kirk Scott 1.
CSCI-383 Object-Oriented Programming & Design Lecture 13.
Chapter 9 Object-Oriented Software Development F Software Development Process F Analyze Relationships Among Objects F Class Development F Class Design.
Chapter 2 Introducing Interfaces Summary prepared by Kirk Scott.
Unit 12 Flyweight Summary prepared by Kirk Scott 1.
The Factory Patterns SE-2811 Dr. Mark L. Hornick 1.
Design Patterns Gang Qian Department of Computer Science University of Central Oklahoma.
Design Patterns CS 124 Reference: Gamma et al (“Gang-of-4”), Design Patterns.
Appendix D UML at a Glance Summary prepared by Kirk Scott 1.
© 2004 Pearson Addison-Wesley. All rights reserved September 12, 2007 Encapsulation ComS 207: Programming I (in Java) Iowa State University, FALL 2007.
Design Patterns in Java Part II Responsibility Patterns Chapter 7 Introducing Responsibility Summary prepared by Kirk Scott 1.
Chapter 10 Defining Classes. The Internal Structure of Classes and Objects Object – collection of data and operations, in which the data can be accessed.
Factory Method Explained. Intent  Define an interface for creating an object, but let subclasses decide which class to instantiate.  Factory Method.
Unit 21 Factory Method Summary prepared by Kirk Scott 1.
Inheritance. Inheritance is a fundamental object-oriented design technique used to create and organize reusable classes Chapter 8 focuses on: deriving.
Designing Classes CS239 – Jan 26, Key points from yesterday’s lab  Enumerated types are abstract data types that define a set of values.  They.
Interfaces About Interfaces Interfaces and abstract classes provide more structured way to separate interface from implementation
Inheritance CSI 1101 Nour El Kadri. OOP  We have seen that object-oriented programming (OOP) helps organizing and maintaining large software systems.
M1G Introduction to Programming 2 3. Creating Classes: Room and Item.
Chapter 16 UML Class Diagrams 1CS6359 Fall 2012 John Cole.
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
Inheritance and Class Hierarchies Chapter 3. Chapter Objectives  To understand inheritance and how it facilitates code reuse  To understand how Java.
Singleton Pattern. Problem Want to ensure a single instance of a class, shared by all uses throughout a program Context Need to address initialization.
In this class, we will cover: Overriding a method Overloading a method Constructors Mutator and accessor methods The import statement and using prewritten.
M1G Introduction to Programming 2 2. Creating Classes: Game and Player.
1 Lecture Material Design Patterns Visitor Client-Server Factory Singleton.
Summary prepared by Kirk Scott
Summary prepared by Kirk Scott
Summary prepared by Kirk Scott
Design Patterns in Java Chapter 23 Strategy
03/10/14 Inheritance-2.
Chapter 11 Object-Oriented Design
Summary prepared by Kirk Scott
More Interfaces, Dynamic Binding, and Polymorphism
Chapter 3: Using Methods, Classes, and Objects
Chapter 17 Abstract Factory
Overriding Methods & Class Hierarchies
Outline Anatomy of a Class Encapsulation Anatomy of a Method
Encapsulation September 13, 2006 ComS 207: Programming I (in Java)
CS 112 Programming 2 Lecture 02 Abstract Classes & Interfaces (2)
Presentation transcript:

Design Patterns in Java Chapter 13 Flyweight Summary prepared by Kirk Scott 1

The book states that most typically just one object will hold a single reference to another object As a result, any change to the “held” object will be a result of a call made in the holding object If this is the case, the holding object knows what’s been done There is no need to inform any other objects 2

On the other hand, some objects may be referred to by many other objects Alternatively, a single object may be referred to many times by one other object Put another way, one or more clients will want to share access to the object This is a responsibility pattern because now many references/many clients are potentially responsible for making changes to the object This is shared responsibility Also, potentially many client reference/many clients have to be informed of a change 3

The authors offer this scenario for sharing Suppose that in a text management system there is a single object for each printable character Then a book may contain thousands of references to individual instances of the character class Also, there may be many books overall, each containing multiple references to instances of the character class 4

In this scenario it is the individual character objects that are the flyweights They are shared among different books and each book will have multiple references to them What characteristics the flyweights have and how to manage them are at the heart of the design pattern 5

Book definition: The intent of the Flyweight pattern is to use sharing to support large numbers of fine- grained objects efficiently. Comment mode on: I believe that it would be preferable to say “large numbers of references to fine-grained objects”, although there may also be a large number of objects 6

Immutability Part of the introductory discussion mentioned the idea that if a shared object is changed, then potentially all clients should be notified Stated another way, a single action by one client can potentially affect many other clients This kind of dependence among the clients can be an undesirable kind of coupling Also, trying to notify many clients of changes can be onerous 7

Although it may diminish the usefulness of flyweights in certain applications, the problem can be solved by making the flyweights immutable This means that their implementation contains no method that allows them to be changed by a client References to them may be dropped New instances with new values may be created But an existing object cannot be changed You are familiar with immutability through the Java String class 8

Challenge 13.1 Provide a justification of why the creators of Java made String objects immutable, or argue that this was an unwise restriction. 9

An argument for the immutability of strings: In short, this is the book’s answer: Strings are frequently shared In other words, they are sort of like system supplied flyweights Therefore, to solve the flyweight problem, it was a good thing to make them immutable 10

Comment mode on: The book also touches on this argument, but not very clearly When you have objects with String instance variables, how should you write the get methods for them? In reality, you should return a clone It violates encapsulation to return a reference However, this problem is solved if the reference returned is immutable 11

An argument against the immutability of strings: In short, this is the book’s answer: By definition, making strings immutable makes it impossible to change them This is an artificial limitation on strings that doesn’t apply to most other objects This means Java is less flexible and contains special cases that you have to learn The authors observe that no language can completely protect the programmer from programming difficulties or making mistakes If that’s the purpose of immutability, it’s a fool’s errand 12

Extracting the Immutable Part of a Flyweight The starting point for this discussion is that we’re going to assume that if we use the Flyweight design pattern, the flyweights are going to be immutable The previous discussion explained why that is a desirable design choice The point of this section is that you have a design with lots of shared references which are not flyweights You want to refactor to a design that uses flyweights 13

Along with any other changes to the code, this will require redesigning the class with many references to it as a(n immutable) flyweight The goal is to extract out the immutable part of the class That will be the flyweight which has many references to it The rest of the class will have to be handled in a different way 14

The book bases its example on chemicals In a fireworks factory, the ingredients are chemical in nature In the non-flyweight design, the ingredients are referred to as substances The following UML diagram shows the substance class 15

16

The Substance class has instance variables for name, symbol, atomicWeight, and grams A digression on terminology: The instance variables symbol and atomicWeight suggest that we’re talking about chemical elements An element has a symbol and an atomic weight 17

For what it’s worth, the following information is given by Wikipedia: The IUPAC definition [1] of atomic weight is: [1] An atomic weight (relative atomic mass) of an element from a specified source is the ratio of the average mass per atom of the element to 1/12 of the mass of an atom of 12 C. 18

It becomes apparent that the authors want to refer to chemical compounds as well as elements When they refer to a symbol, they don’t just mean a single symbol for an element They also mean the chemical formula for a compound Technically, they might also have referred to molecular weight, which is the equivalent for compounds of atomic weight for elements 19

In any case, some of the instance variables identify and give characteristics of chemical elements and compounds The instance variable gram is different Grams are a measurement of mass (what we poor benighted users of the English system think of as weight) In other words, grams are a measurement of a quantity of something 20

In short, the Substance class tells both what something is and how much of it there is Such a class invites decomposition into two parts The “what it is” part could be immutable The “how much of it is there” part would be mutable 21

The Substance class has get and set methods for its instance variables It also has a computed getMoles() method that returns the number of moles (6.02 x molecules (Avogadro’s number of molecules) in a given mass of an element or compound The next overhead shows how an instance of the Mixture class is based on having references to instances of the Substance class 22

23

In the fireworks setting there could be many different mixtures that have to be modeled or represented This means that there would be many references to instances of the Substance class The instances of the substance class would differ according to the number of grams The information about a particular chemical element or compound would not differ 24

Challenge 13.2 Complete the class diagram in Figure 13.3 to show a refactored Substance2 class and a new, immutable Chemical class. 25

26

Solution 13.2 You can move the immutable aspects of Substance—including its name, symbol, and atomic weight—into the Chemical class, as Figure B.17 shows. 27

28

Solution 13.2, continued The Substance2 class now maintains a reference to a Chemical object. As a result, the Substance2 class can still offer the same accessors as the earlier Substance class. Internally, these accessors rely on the Chemical class, as the following Substance2 methods demonstrate. [See the next overhead.] 29

public double getAtomicWeight() { return chemical.getAtomicWeight(); } public double getGrams() { return grams; } public double getMoles() { return grams / getAtomicWeight(); } 30

Sharing Flyweights Extracting the immutable part of a class in order to create flyweights is just part of the task involved in applying the Flyweight pattern The book refers to creating a “flyweight factory” This is a foreshadowing of future chapters 31

The underlying idea is that there should be only one instance of a flyweight containing a certain set of values If this is the case, then applications can’t just create instances of the flyweight class willy- nilly The flyweight factory class controls the creation of flyweights and making them available for sharing by clients 32

For the chemical example the book proposes a ChemicalFactory class It will contain a static method that will return a reference to a chemical given its name Internally the factory class can store the different chemicals in a hash table, for example 33

Notice two things about this scenario First The flyweight isn’t a singleton—there are multiple instances of it However, there can be no duplicate instances In other words, no two instances of a flyweight should test equal for contents 34

Second There is an implementation similarity between the flyweight and the mediator Recall that one of the example of the use of the Mediator design pattern was maintaining relational integrity This was accomplished in part by wrapping a hash table in a class and then storing individual items as entities in the hash table 35

Not only is the similarity structural In a real sense the flyweight factory is a specific example of the mediator pattern It maintains the list of chemicals It is responsible for making the chemicals available for sharing by client code The UML diagram on the next overhead illustrates the relationships between the ChemicalFactory class and the Chemical class 36

37

Next the book shows code for the ChemicalFactory class The book makes use of what it calls a static initializer Basically this can be summarized as a block of code that is used to initialize an instance variable In this example there is an instance of HashMap and it is filled with instances of the chemical class 38

It would be possible to put the static initialization code into a constructor for a class that had instances Since the one method of interest in the ChemicalFactory class is static, its methods are not called on an instance 39

Another side note is this: An alternative to a class containing only static items would be a singleton class You would have to create the one instance of the singleton and then call real methods on that instance Partial code for the ChemicalFactory class is shown on the following overheads 40

import java.util.*; public class ChemicalFactory { private static Map chemicals = new HashMap(); static { chemicals.put("carbon", new Chemical("Carbon", "C", 12)); chemicals.put("sulfur", new Chemical("Sulfur", "S", 32)); chemicals.put("saltpeter", new Chemical("Saltpeter", "KN03", 101)); //... } public static Chemical getChemical(String name) { return (Chemical) chemicals.get(name.toLowerCase()); } 41

Developers should not create their instances of the chemical class They should only use the chemicals in the ChemicalFactory class Enforcing this discipline can be accomplished by controlling access to the Chemical class 42

Challenge 13.3 How can you use the accessibility of the Chemical class to discourage other developers from instantiating Chemical objects? 43

Solution One way that won’t work is to make the Chemical constructor private. That would prevent the ChemicalFactory class from instantiating the Chemical class Comment mode on: This is not a solution 44

2. To help prevent developers from instantiating the Chemical class themselves, you could place Chemical and ChemicalFactory classes in the same package and give the Chemical class’s constructor default (“package”) access. Comment mode on: To be charitable, this is a weak solution. Lame might be a better word 45

You can prevent client code from creating instances of the Chemical class by making it an inner class of the ChemicalFactory class Note that client code would have to use the qualified class name when referring to an instance of the inner class You are familiar with this notation An example is shown on the next overhead 46

ChemicalFactory.Chemical c = ChemicalFactory.getChemical(“saltpeter”); 47

The book suggests a refinement on this plan Let the inner class be named ChemicalImpl, short for ChemicalImplementation Let there be an interface named Chemical Let the inner class implement the interface Then internal to the factory, instances of ChemicalImpl are created 48

The getChemical() method of the factory is defined to return a reference of type Chemical Client code works with references of type Chemical In this way, the client never has to refer to the actual ChemicalImpl class The client never has to use a qualified name 49

As far as the client knows, it is simply dealing with chemicals It doesn’t have to know that chemicals are created as instances of a separate, inner class known as ChemicalImpl The Chemical interface is shown on the next overhead It simply has in it the accessor methods associated with chemicals all along 50

public interface Chemical { String getName(); String getSymbol(); double getAtomicWeight(); } 51

Challenge 13.4 Complete the following code for ChemicalFactory2.java Comment mode on: The given incomplete code is kind of long Since I always just show the answer anyway, I’m skipping the incomplete code and just going to the answer, which is on the following overheads 52

Note: If you’re making ChemicalImpl an Inner Class, Why Not Make it Private? import java.util.*; public class ChemicalFactory2 { private static Map chemicals = new HashMap(); class ChemicalImpl implements Chemical { private String name; private String symbol; private double atomicWeight; ChemicalImpl(String name, String symbol, double atomicWeight) { this.name = name; this.symbol = symbol; this.atomicWeight = atomicWeight; } 53

public String getName() { return name; } public String getSymbol() { return symbol; } public double getAtomicWeight() { return atomicWeight; } public String toString() { return name + "(" + symbol + ")[" + atomicWeight + "]"; } 54

static { ChemicalFactory2 factory = new ChemicalFactory2(); chemicals.put("carbon", factory.new ChemicalImpl("Carbon", "C", 12)); chemicals.put("sulfur", factory.new ChemicalImpl("Sulfur", "S", 32)); chemicals.put("saltpeter", factory.new ChemicalImpl("Saltpeter", "KN03", 101)); //... } public static Chemical getChemical(String name) { return (Chemical) chemicals.get(name.toLowerCase()); } 55

Summary The Flyweight pattern supports the sharing of one instance by many clients In the early discussion the book made it sound like immutability was a good idea The example illustrated immutability The book now states clearly that a flyweight class should be immutable When refactoring, part of the process is extracting the immutable part 56

The creation of instances of the flyweight should be created in a factory class The factory class should also manage the sharing of the flyweights An inner class (possibly with an interface) gives the factory a suitable level of control over the creation of instances of the flyweight A static method can be used to return references to the (immutable) flyweight objects 57

If the flyweight and the factory are correctly set up, you achieve these goals: Concretely, shared access is enabled This shared access is safe and foolproof Clients can’t create instances of their own 58

In a broader sense, the refactoring accomplishes this: You avoid a proliferation of many instances of a class More specifically, you avoid having many references to instances of a class More specifically yet, you avoid having shared references to mutable classes 59

By not having shared references to mutable classes, you avoid the problem that many clients would be coupled A change to the shared object by one of the clients would affect all of them Without the flyweight solution you would be confronted with the problem of how to notify/update all of the clients 60

The End 61