Advanced OO and Design Patterns - OCP - OCA/OCP Java SE 7 Programmer I & II Study Guide (Exams 1Z0-803 & 1Z0-804) (2015)

OCA/OCP Java SE 7 Programmer I & II Study Guide (Exams 1Z0-803 & 1Z0-804) (2015)

Part 2. OCP

Chapter 10. Advanced OO and Design Patterns

CERTIFICATION OBJECTIVES

• Write Code that Declares, Implements, and/or Extends Interfaces

• Choose Between Interface Inheritance and Class Inheritance

• Apply Cohesion, Low-Coupling, IS-A, and HAS-A Principles

• Apply Object Composition Principles (Including HAS-A Relationships)

• Design a Class Using the Singleton Design Pattern

• Write Code to Implement the DAO Pattern

• Design and Create Objects Using a Factory and Use Factories from the API

image Two-Minute Drill

Q&A Self Test

You were introduced to object-oriented (OO) principles in Chapter 2. We will be looking at some more advanced principles here, including coupling and cohesion. You’ll also learn what a design pattern is and dip your toe into the world of patterns by exploring three of them. As a bit of a teaser, a design pattern is a reusable solution to problems. Which will come in handy so you aren’t reinventing new ways to solve common problems.

CERTIFICATION OBJECTIVES

IS-A and HAS-A (OCP Objectives 3.3 and 3.4)

3.3 Apply cohesion, low-coupling, IS-A, and HAS-A principles.

3.4 Apply object composition principles (including HAS-A relationships).

You learned the difference between IS-A and HAS-A in Chapter 2. As a brief review, how many IS-A/HAS-A statements can you write about BeachUmbrella?

image

We can make four statements about BeachUmbrella:

image BeachUmbrella IS-A Umbrella

image BeachUmbrella IS-A SunProtector

image BeachUmbrella HAS-A Stand

image And, of course, as always, BeachUmbrella IS-A Object

In a nutshell, IS-A happens when a class uses inheritance—e.g., when a class extends another class or implements an interface. HAS-A happens when a class has instance variables of a class.

Coupling and Cohesion

We’re going to admit it up front: The Oracle exam’s definitions for cohesion and coupling are somewhat subjective, so what we discuss in this chapter is from the perspective of the exam and is by no means The One True Word on these two OO design principles. It may not be exactly the way that you’ve learned it, but it’s what you need to understand to answer the questions. You’ll have very few questions about coupling and cohesion on the real exam.

These two topics, coupling and cohesion, have to do with the quality of an OO design. In general, good OO design calls for loose coupling and shuns tight coupling, and good OO design calls for high cohesion and shuns low cohesion. As with most OO design discussions, the goals for an application are

image Ease of creation

image Ease of maintenance

image Ease of enhancement

Coupling

Let’s start by attempting to define coupling. Coupling is the degree to which one class knows about another class. If the only knowledge that class A has about class B is what class B has exposed through its interface, then class A and class B are said to be loosely coupled… that’s a good thing. If, on the other hand, class A relies on parts of class B that are not part of class B’s interface, then the coupling between the classes is tighter… not a good thing. In other words, if A knows more than it should about the way in which B was implemented, then A and B are tightly coupled.

Using this second scenario, imagine what happens when class B is enhanced. It’s quite possible that the developer enhancing class B has no knowledge of class A—why would she? Class B’s developer ought to feel that any enhancements that don’t break the class’s interface should be safe, so she might change some noninterface part of the class, which then causes class A to break.

At the far end of the coupling spectrum is the horrible situation in which class A knows non-API stuff about class B, and class B knows non-API stuff about class A—this is REALLY BAD. If either class is ever changed, there’s a chance that the other class will break. Let’s look at an obvious example of tight coupling that has been enabled by poor encapsulation.

image

All nontrivial OO applications are a mix of many classes and interfaces working together. Ideally, all interactions between objects in an OO system should use the APIs—in other words, the contracts of the objects’ respective classes. Theoretically, if all of the classes in an application have well-designed APIs, then it should be possible for all interclass interactions to use those APIs exclusively. As we discussed in Chapter 2, an aspect of good class and API design is that classes should be well encapsulated.

The bottom line is that coupling is a somewhat subjective concept. Because of this, the exam will test you on really obvious examples of tight coupling; you won’t be asked to make subtle judgment calls.

Cohesion

While coupling has to do with how classes interact with each other, cohesion is all about how a single class is designed. The term cohesion is used to indicate the degree to which a class has a single, well-focused purpose. Keep in mind that cohesion is a subjective concept. The more focused a class is, the higher its cohesiveness—a good thing. The key benefit of high cohesion is that such classes are typically much easier to maintain (and less frequently changed) than classes with low cohesion. Another benefit of high cohesion is that classes with a well-focused purpose tend to be more reusable than other classes. Let’s look at a pseudo-code example:

image

Now imagine your manager comes along and says, “Hey, you know that accounting application we’re working on? The clients just decided that they’re also going to want to generate a revenue projection report, oh and they want to do some inventory reporting also. They do like our reporting features, however, so make sure that all of these reports will let them choose a database, choose a printer, and save generated reports to data files….” Ouch!

Rather than putting all the printing code into one report class, we probably would have been better off with the following design right from the start:

image

This design is much more cohesive. Instead of one class that does everything, we’ve broken the system into four main classes, each with a very specific, or cohesive, role. Because we’ve built these specialized, reusable classes, it’ll be much easier to write a new report since we already have the database connection class, the printing class, and the file saver class, and that means they can be reused by other classes that might want to print a report.

CERTIFICATION OBJECTIVE

Object Composition Principles (OCP Objective 3.4)

3.4 Apply object composition principles.

Object composition principles build on IS-A and HAS-A. If you aren’t 100 percent comfortable with the differences between IS-A and HAS-A, go back and reread Chapter 2 before continuing on.

Object composition refers to one object having another as an instance variable (HAS-A). Sometimes, that instance variable might be the same type as the object we are writing. Think about when you get that package from Amazon that is a box containing some bubble wrap, a receipt, and yet another box. That is composition at work. The outer (containing class) box contains an inner (instance) box.

Let’s build out this box example. We want to reuse as much code as possible. After all, the procedure for sealing a box with some tape doesn’t change from box to box. Let’s start with the concept of a Box:

image

Wait. Boxes are simple. Why do we need an interface? We realize there are many types of boxes. There are gift boxes, jewelry boxes, small boxes, large boxes, etc. Now we create a concrete type of Box:

image

GiftBox implements Box by implementing the two methods Box requires. Providing an interface lets us keep the Box logic where it belongs—in the relevant subclasses. And to review, GiftBox IS-A Box.

Now that we’ve figured out Box, it’s time to build a MailerBox:

image

See any problems? That’s right, we’ve duplicated the logic to pack and seal the Box. All two lines of it. Our real Box logic would be a lot longer, though. And when we start manufacturing different types of boxes, we’d have that Box logic all over the place.

One thought is to solve this by having MailerBox extend GiftBox. It doesn’t take long to see the problem here. We would need MailerGiftBox, MailerSmallBox, MailerMediumBox, etc. That’s a lot of classes! And this technique would repeat for other types of functionality we create. Which means we would also need WrappedGiftBox, MailerWrappedGiftBox. Uh oh. We can only extend one class in Java. We can’t inherit both Mailer and GiftBox functionality. Clearly, IS-A isn’t going to work for us here.

Instead, we can use HAS-A. First, we create the interface for our desired functionality:

image

Then we can create the object that is both a Box and Mailer:

image

The first thing to notice is that the logic to pack and seal a box is only in one place—in the Box hierarchy where it belongs. In fact, the MailerBox doesn’t even know what kind of Box it has. This allows us to be very flexible.

Next, notice the implementation of pack() and seal(). That’s right—each is one line. We delegate to Box to actually do the work. This is called method forwarding or method delegation. These two terms mean the same thing.

Finally, notice that MailerBox is both a Box and a Mailer. This allows us to pass it to any method that needs a Box or a Mailer.

Polymorphism

Looking at these classes graphically, we have the following:

image

Think about which of the objects can be passed to this method:

image

GiftBox can because it implements Box. So can MailerBox for the same reason. MailerBox knows how to pack—by delegating to the Box instance. This is why it is important for the composing class to both contain and implement the same interface. Repeating the relevant parts here, we have:

image

You can see the composition part. MailerBox both IS-A Box and HAS-A Box. MailerBox is composed of a Box and delegates to Box for logic. That’s the terminology for object composition.

Benefits of Composition

Benefits of composition include

image Reuse An object can delegate to another object rather than repeating the same code.

image Preventing a proliferation of subclasses We can have one class per functionality rather than needing one for every combination of functionalities.

CERTIFICATION OBJECTIVES

Singleton Design Pattern (OCP Objective 3.5)

3.5 Design a class using the singleton design pattern.

In a nutshell, the singleton design pattern ensures we only have one instance of a class of an object within the application. It’s called a creational design pattern because it deals with creating objects. But wait, what’s this “design pattern”?

What Is a Design Pattern?

Wikipedia currently defines a design pattern as “a general reusable solution to a commonly occurring problem within a given context.” What does that mean? As programmers, we frequently need to solve the same problem repeatedly. Such as how to only have one of a class of an object in the application. Rather than have everyone come up with their own solution, we use a “best practice” type solution that has been documented and proven to work. The word “general” is important. We can’t just copy and paste a design pattern into our code. It’s just an idea. We can write an implementation for it and put that in our code.

Using a design pattern has a few advantages. We get to use a solution that is known to work. The tradeoffs, if any, are well documented so we don’t stumble over problems that have already been solved. Design patterns also serve as a communication aid. Your boss can say, “We will use a singleton,” and that one word is enough to tell you what is expected.

When books or web pages document patterns, they do so using consistent sections. In this book, we have sections for the “Problem,” “Solution,” and “Benefits.” The “Problem” section explains why we need the pattern—what problem we are trying to solve. The “Solution” section explains how to implement the pattern. The “Benefits” section reviews why we need the pattern and how it has helped us solve the problem. Some of the benefits are hinted at in the “Problem” section. Others are additional benefits that come from the pattern.

image

While the exam only covers three patterns, this is just to get your feet wet. Whole books are written on the topic of design patterns. Head First Design Patterns (O’Reilly Media, 2004) covers more patterns. And the most famous book on patterns, Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley Professional, 1994)—also known as “Gang of Four”—covers 23 design patterns. You may notice that these books are over 10 years old. That’s because the classic patterns haven’t changed.

While each book does use a consistent set of sections, there isn’t one common set of names. You will see synonyms used such as “Problem” versus “Motivation.” You will also see additional sections such as “Consequences.” The exam picks simpler patterns so you can use the simpler sections.

When talking about patterns, they are usually presented in a problem/solution format. Then, depending on the level of detail, other sections are added. In this book, each pattern will cover the problem, solution, and benefits.

Problem

Let’s suppose we are going to put on a show. We have one performance of this show and we only have a few seats in the theater.

image

This code prints out true twice. That’s a problem. We just put two people in the same seat. Why? We created a new Show object every time we needed it. Even though we want to use the same theater and seats, Show deals with a new set of seats each time. Which causes us to double-book seats.

Solution

There are a few ways to implement the singleton pattern. The simplest is

image

Now the code prints true and false. Much better! We are no longer going to have two people in the same seat. The bolded bits in the code call attention to the implementation of the singleton pattern.

The key parts of the singleton pattern are

image A private static variable to store the single instance called the singleton. This variable is usually final to keep developers from accidentally changing it.

image A public static method for callers to get a reference to the instance.

image A private constructor so no callers can instantiate the object directly.

Remember, the code doesn’t create a new Show each time, but merely returns the singleton instance of Show each time getInstance() is called.

To understand this a little better, consider what happens if we change parts of the code.

If the constructor weren’t private, we wouldn’t have a singleton. Callers would be free to ignore getInstance() and instantiate their own instances. Which would leave us with multiple instances in the program and defeat the purpose entirely.

If getInstance() weren’t public, we would still have a singleton. However, it wouldn’t be as useful because only static methods of the class Show would be able to use the singleton.

If getInstance() weren’t static, we’d have a bigger problem. Callers couldn’t instantiate the class directly, which means they wouldn’t be able to call getInstance() at all.

If INSTANCE weren’t static and final, we could have multiple instances at different points in time. These keywords signal that we assign the field once and it stays that way for the life of the program.

When talking about design patterns, it is common to also communicate the pattern in diagram form. The singleton pattern diagram looks like this:

image

image

A format called UML (Unified Modeling Language) is used. The diagrams in this book use some aspects of UML, such as a box with three sections representing each class. Actual UML uses more notation, such as showing public versus private visibility. You can think of this as faux-UML.

As long as the method in the diagram keeps the same signature, we can change our logic to other implementations of the singleton pattern. One “feature” of the above implementation is that it creates the Show object before we need it. This is called eager initialization, which is good if the object isn’t expensive to create or we know it will be needed for every run of the program. Sometimes, however, we want to create the object only on the first use. This is called lazy initialization.

image

In this case, INSTANCE isn’t set to be a Show until the first time getInstance() is called. Walking through what happens, the first time getInstance() is called, Java sees INSTANCE is still null and creates the singleton. The second time getInstance() is called, Java sees INSTANCE has already been set and simply returns it. In this example, INSTANCE isn’t final because that would prevent the code from compiling.

image

The singleton code here assumes you are only running one thread at a time. It is NOT thread-safe. Think about if this were a web site and two users managed to be booking a seat at the exact same time. If getInstance() were running at the exact same time, it would be possible for both of them to see that INSTANCE was null and create a new Show at the same time. There are a few ways to solve this. One is to add synchronized to the getInstance() method. This works, but comes with a small performance hit. We’re getting way beyond the scope of the exam, but you can Google “double checked locked pattern” for more information.

You might have noticed that the code for getInstance() can get a bit complicated. In Java 5, there became a much shorter way of creating a singleton:

image

Short and sweet. By definition, there is only one instance of an enum constant. You are probably wondering why we’ve had this whole discussion of the singleton pattern when it can be written so easily. The main reason is that enums were introduced with Java 5 and there is a ton of older code out there that you need to be able to understand. Another reason is that sometimes the older versions of the pattern are still needed.

Benefits

Benefits of the singleton pattern include the following:

image The primary benefit is that there is only one instance of the object in the program. When an object’s instance variables are keeping track of information that is used across the program, this becomes useful. For example, consider a web site visitor counter. You only want one count that is shared.

image Another benefit is performance. Some objects are expensive to create. For example, maybe we need to make a database call to look up the state for the object.

CERTIFICATION OBJECTIVES

DAO Design Pattern (OCP Objective 3.6)

3.6 Write code to implement the DAO pattern.

DAO stands for “Data Access Object.” A DAO is only responsible for storing data. Nothing else. Why can’t we do this in the object with everything else, you ask?

Suppose we have three objects in our program as shown in Table 10-1.

TABLE 10-1 Object Responsibilities

image

Already there is a problem. These classes aren’t cohesive. Remember cohesion? We want each class to have a single purpose. Storing and searching objects in the database is NOT that purpose. Having that database code all over makes it hard to focus on the classes’ core purpose for existing, which is clearly for our entertainment. Since dealing with a database is very common, separating out that responsibility is a pattern—the DAO.

Problem

Let’s drill down into just the Book class. This is the poorly written, noncohesive version. Pay particular attention to the two responsibilities.

image

Counting the getters and setters we didn’t want to bore you with, the Book class is over 50 lines. And it hardly does anything! A real Book class would have a lot more fields. A bookstore needs to tell you when the book was written, the edition, the price, and all sorts of other information. A bookstore also needs to be able to keep track of books somewhere other than a map. After all, we don’t want our bookstore to forget everything when we reboot.

The problem is that our class is responsible for two things. The first is keeping track of being a book. This seems like a good responsibility for a class to have that is named Book. The other is keeping track of storage responsibilities.

A datastore is the name of—wait for it—where data is stored. In the real world, we’d use a database or possibly a file containing the books. For testing, we might use an in-memory database. The map in Book is actually a bare-bones in-memory datastore. As you’ll see in Chapter 15, using a real database would make the Book class MUCH longer.

This is a problem. We want our code to be easy to read and focused on one responsibility.

Solution

The DAO pattern has us split up these two responsibilities. We start by letting our Book class focus on being a book:

image

There can be other methods in Book such as toString(), hashCode(), and equals(). These methods have to do with the Book object. Methods that have to do with a bookstore or database are now gone. Much better. Now we can go on to the data access code:

image

The new InMemoryBookDao class only knows how to do one thing—deal with the datastore. This is such a common technique that it has a name: the single responsibility principle. The method names in the DAO are actually standard. You’ll see them again when you get to Chapter 15.

When everything was in the Book object, we just created a Book and started calling methods. Now that Book and DAO are separate objects, the caller deals with two objects:

image

The new DAO object gets all the calls that have to do with the datastore. Table 10-2 shows why each method call is associated with each class.

TABLE 10-2 DAO Method Call Associations

image

Good so far? The DAO pattern only has one more part. Our datastore is pretty wimpy right now. Every time we restart the program, it forgets what books we have. At some point, we are going to want to change that. But when we do, we want to make it easier for callers to change.

image

Since all the method names in the interface match our existing DAO, all we have to do is have it implement the new interface:

image

And we can use the interface type when declaring the DAO:

image

Wait a minute. We still have InMemoryBookDao in the line of code that instantiates the DAO. It is a bit like writing Collection c = new ArrayList();. It just so happens to be an ArrayList right now, but we could change it at any time. It is a bit like signifying that the surrounding code shouldn’t get too cozy with any particular implementation. We can always change the specific DAO implementation later without changing the interface. And we will learn in the next section how to get rid of even the one reference to InMemoryBookDao.

To review the classes involved in the DAO pattern, we have the following illustration:

image

Now we have three objects, each responsible for one thing. We have the public interface BookDao, which specifies the contract. Next, we have the implementation of that interface, InMemoryBookDao. Finally, we have the Book class itself, which focuses on the object state and any methods related to Book.

image

In addition to making the code easier to read, this pattern makes it easy for us to organize code. We could put all the JavaBeans in one package, the interfaces in another package, and the implementations in still another package. This approach allows us to have one package for in-memory implementations and another for JDBC implementations.

Benefits

To review, the benefits of the DAO pattern are as follows:

image The main object (Book in this case) is cohesive and doesn’t have database code cluttering it up.

image All the database code is in one part of the program, making it easy to find.

image We can change the database implementation without changing the business object.

image Reuse is easier. As the database code grows, we can create helper classes and even helper superclasses.

CERTIFICATION OBJECTIVES

Factory Design Pattern (OCP Objective 3.7)

3.7 Design and create objects using a factory and use factories from the API.

Like the singleton design pattern, the factory design pattern is a creational design pattern. Unlike the singleton, it doesn’t limit you to only having one copy of an object. The factory design pattern creates new objects of whatever implementation it chooses.

Problem

So far, we only have one implementation of our BookDAO called InMemoryBookDao. It isn’t very robust since it only stores objects in memory. We will need to create a version of it that uses JDBC or writes to a file or does something else where we can remember state. We want to be able to change the DAO implementation without having to change the caller code (Student). Remember coupling? This is loose coupling. Interfaces are part of loose coupling, but we want to go a step further.

Solution

The simplest factory we can write while still implementing the pattern is an abstract class and implementation with one method:

image

This is very simple. The Factory is an abstract class with one method. Its implementation simply returns an in-memory DAO. From Student’s point of view, this is all that exists—the Factory class and the BookDao interface. Note that Student no longer has the code new InMemoryBookDao.

In diagram form, here is how our classes fit together:

image

To review, Student only interacts with the two abstract classes Factory and BookDao. All implementation is in the concrete subclasses.

This setup frees us up to change the implementation of FactoryImpl without affecting the caller.

Let’s try an example to show how we can change the factory. Suppose we write a DAO implementation OracleBookDao that uses a real database. We might change FactoryImpl to:

image

Just like that—nothing changes in Student. Yet it starts using the real database implementation. This is good design. A change only needs to be made in one place.

You might be wondering why Factory is an abstract class rather than an interface. It is common with the factory method pattern to work “around” the creation logic, or at least recognize that it might happen later.

As an example here, we could decide that we want to include the test logic check in the superclass so any future subclasses use it:

image

In this case, the superclass Factory has all the common logic, and the subclass FactoryImpl merely creates the relevant object. Notice how the API createDao() hasn’t changed its signature at all despite our extensive changes to the method implementation. That is why we are using the factory pattern. So the caller Student isn’t affected by any changes to our factory and DAO.

image

There are three patterns with factory in their name:

image Factory method This is the pattern we are talking about in this chapter and is on the exam.

image Abstract factory This takes the factory method pattern a bit further and is used to create families of related classes.

image Factory It’s debatable whether this is even a pattern. It’s not in the “Gang of Four” book. However, on the job, when developers say “factory,” they are often referring to a method like
public Foo createFoo() {return new Foo(); } rather than a full-fledged factory method pattern. The method may return Foo or SubclassOfFoo, but it doesn’t have the superclass/subclass relationship for the creator object that the factory method pattern has
.

You might have noticed we didn’t say anything about making the DAO constructors private. In the singleton pattern, we needed to force callers to use getInstance() to prevent multiple copies. The factory pattern is merely a convenience. At times, it is a pretty big convenience. However, callers can still instantiate the DAO directly without breaking our logic, so we let them.

In fact, Oracle uses the factory pattern in the Java API in many places. When we learned how to create a DateFormat, we used DateFormat.getInstance(), DateFormat.getDateInstance(), and other similar factory methods. If you wanted more control over the format string, you could still write new SimpleDateFormat(“yyyy MM”). Oracle leaves the constructor available for when you need it.

Similarly, when we learned how to create a Calendar, we wrote Calendar.getInstance() or Calendar.getInstance(Locale). You will see many more examples of the factory pattern as you explore the Java API.

Benefits

Benefits of the factory design pattern include the following

image The caller doesn’t change when the factory returns different subclasses. This is useful when the final implementation isn’t ready yet. For example, maybe the database isn’t yet available. It’s also useful when we want to use different implementations for unit testing and production code. For example, you want to write code that behaves the same way, regardless of what happens to be in the database.

image Centralizes creation logic outside the calling class. This prevents duplication and makes the code more cohesive.

image Allows for extra logic in the object creation process. For example, an object is time-consuming to create, and you want to reuse the same one each time.

CERTIFICATION SUMMARY


We started the chapter by reviewing the difference between IS-A and HAS-A. To review the review, IS-A is implemented using inheritance, and HAS-A is implemented using instance variables that refer to other objects.

We discussed the OO concepts of coupling and cohesion. Loose coupling is the desirable state of two or more classes that interact with each other only through their respective APIs. Tight coupling is the undesirable state of two or more classes that know inside details about another class, details not revealed in the class’s API. High cohesion is the desirable state of a single class whose purpose and responsibilities are limited and well focused.

Then we built on those concepts and learned about object composition principles. In particular, we learned how to build objects out of other objects. We saw how method delegation and method forwarding prevent the need to duplicate code. For example:

image

Next, we moved on to design patterns. We learned that design patterns are reusable solutions to common problems.

We saw the singleton pattern used to ensure we only have one instance of a given class within the application. We created a private static variable to store the single instance, which we called the singleton. We then created a public static method for callers to get a reference to the instance. Finally, we made the constructor private so no callers can instantiate the object directly.

We also looked at the DAO design pattern. DAO stands for Data Access Object and provides a way to separate database functionality from the main business object. We saw how using an interface allows us to easily change the data access implementation. A DAO interface typically looks like this:

image

Finally, we looked at the factory design pattern as another way of creating objects. We learned how to create an abstract and concrete factory object. We also saw that we could have common logic in the abstract class. For example:

image

image TWO-MINUTE DRILL

Here are some of the key points from each certification objective in this chapter.

IS-A/HAS-A (OCP Objective 3.3)

image IS-A refers to inheritance.

image IS-A is expressed with either the keyword extends or implements.

image IS-A, “inherits from,” and “is a subtype of” are all equivalent expressions.

image HAS-A means an instance of one class “has a” reference to an instance of another class or another instance of the same class.

Coupling and Cohesion (OCP Objective 3.3)

image Coupling refers to the degree to which one class knows about or uses members of another class.

image Loose coupling is the desirable state of having classes that are well encapsulated, minimize references to each other, and limit the breadth of API usage.

image Tight coupling is the undesirable state of having classes that break the rules of loose coupling.

image Cohesion refers to the degree to which a class has a single well-defined role or responsibility.

image High cohesion is the desirable state of a class whose members support a single well-focused role or responsibility.

image Low cohesion is the undesirable state of a class whose members support multiple unfocused roles or responsibilities.

Object Composition Principles (OCP Objective 3.4)

image Object composition takes advantage of IS-A, HAS-A, and polymorphism.

image Object composition prevents proliferation of subclasses by having each class responsible for one thing.

image Object composition delegates to objects to which it “has” to implement functionality.

image The terms method forwarding and method delegation are used interchangeably.

Singleton Design Pattern (OCP Objective 3.5)

image Design pattern is “a general reusable solution to a commonly occurring problem within a given context.”

image Having only one instance of the object allows a program to share its state.

image This pattern might improve performance by not repeating the same work.

image This pattern often stores a single instance as a static variable.

image We can instantiate right away (eager) or when needed (lazy).

DAO Design Pattern (OCP Objective 3.6)

image DAO stands for Data Access Object.

image DAO separates datastore responsibilities from the core responsibilities of the object.

image DAO uses an interface so we can change the implementation.

image DAO is only responsible for database operations. The main object remains cohesive.

image DAO facilitates reuse.

Factory Design Pattern (OCP Objective 3.7)

image Factory is a creational design pattern.

image Factory can create any subclass of an interface or abstract class.

image Factory is an abstract class.

image Factory subclassing allows for multiple factories.

image The factory method return type is an interface or abstract class.

image Factory method implementation returns subclasses of the target object.

image There may be common logic in the abstract class that all factory subclasses share.

SELF TEST

The following questions will help you measure your understanding of the material presented in this chapter. Read all of the choices carefully, as there may be more than one correct answer. Choose all correct answers for each question. Stay focused.

1. Given:

image

Which is true?

A. A H AS-A B and A HAS-A C

B. A H AS-A B and A IS-A C

C. A I S-A B and A HAS-A C

D. A I S-A B and A IS-A C

E. B I S-A A and A-HAS-A C

F. B I S-A A and A IS-A C

2. Which statements are true? (Choose all that apply.)

A. Method delegation relies on IS-A relationships

B. Method forwarding relies on HAS-A relationships

C. The DAO pattern limits you to one instance of the DAO object

D. The singleton pattern relies on IS-A relationships

E. To use object composition, classes must be final

3. Given:

image

Which design pattern or principle is implemented?

A. Coupling

B. DAO

C. Factory

D. IS-A

E. Object composition

F. Singleton

4. Given:

image

Which design pattern or principle is implemented?

A. DAO

B. Factory

C. IS-A

D. Object composition

E. Singleton

5. Given:

image

Which design pattern or principle is implemented?

A. DAO

B. Factory

C. IS-A

D. Object composition

E. Singleton

6. Which design patterns are classified as creational design patterns? (Choose all that apply.)

A. Coupling

B. DAO

C. Factory

D. IS-A

E. Object composition

F. Singleton

7. Which statements indicate the need to use the factory pattern? (Choose all that apply.)

A. You don’t want the caller to depend on a specific implementation

B. You have two classes that do the same thing

C. You only want one instance of the object to exist

D. You want one class to be responsible for database operations

E. You want to build a chain of objects

8. Given:

image

And the following statements:

I – This is a good use of the DAO pattern

II – The DAO needs an interface

III – The DAO is missing a method

IV – The DAO must use a type other than String

Which of these statements are true?

A. Statement I only

B. Statement II only

C. Statement III only

D. Statement IV only

E. Statements II and III

F. Statements III and IV

9. Which is a benefit of the DAO pattern? (Choose all that apply.)

A. Reuse is easier

B. The database code is automatically generated

C. We can change the database implementation independently

D. Your business object extends the DAO pattern to reduce coding

E. You are limited to one DAO object

10. Which are true of design patterns? (Choose all that apply.)

A. Design patterns are chunks of code you can copy into your application unchanged

B. Design patterns are conceptual reusable solutions

C. Design patterns are shortcuts to talking about code

D. There are three design patterns defined for Java

E. You can only use each design pattern once per application

F. Design patterns are libraries you can call from your code

11. Which statement is true? (Choose all that apply.)

A. Cohesion is the OO principle most closely associated with hiding implementation details

B. Cohesion is the OO principle most closely associated with making sure that classes know about other classes only through their APIs

C. Cohesion is the OO principle most closely associated with making sure that a class is designed with a single well-focused purpose

D. Cohesion is the OO principle most closely associated with allowing a single object to be seen as having many types

12. Given:

1) ClassA has a ClassD

2) Methods in ClassA use public methods in ClassB

3) Methods in ClassC use public methods in ClassA

4) Methods in ClassA use public variables in ClassB

Which is most likely true? (Choose only one.)

A. ClassD has low cohesion.

B. ClassA has weak encapsulation.

C. ClassB has weak encapsulation.

D. ClassB has strong encapsulation.

E. ClassC is tightly coupled to ClassA.

SELF TEST ANSWERS

1. image C is correct. Since A extends B, it IS-A B. Since C is an instance variable in A, A HAS-A C.

image A, B, D, E, and F are incorrect because of the above. (OCP Objective 3.3)

2. image B is correct. Method forwarding is an object composition principle and calls methods on an instance variable of an object.

image A is incorrect because method delegation and method forwarding are the same thing. C is incorrect because it is the singleton pattern that limits you to one object. D is incorrect because singleton classes typically don’t have a superclass (other than Object). E is incorrect because there is no such requirement. (OCP Objective 3.4)

3. image F is correct. The singleton pattern is identifiable by the static variable for the single instance and the accessor returning it.

image B is incorrect because there is no interface. The class just happens to have methods update() and delete(), which are similar to those found in a DAO. A, C, D, and E are incorrect because of the above. (OCP Objective 3.5)

4. image D is correct. The object composition principle of method forwarding is shown.

image E is tricky, but incorrect. Although getInstance() is a common name for a method in a singleton, the method doesn’t return a static object. While it does create an object, it isn’t a factory either, since there is no superclass. A, B, and C are incorrect because of the above. (OCP Objective 3.4)

5. image B is correct. Class A is the object we are creating using the factory method. Class G is the abstract superclass for the factory. Not shown is a class implementing class G that actually creates the object.

image A, C, D,and E are incorrect because of the above. (OCP Objective 3.7)

6. image C and F are correct. The factory design pattern creates new objects for each call, and the singleton design pattern creates one object, returning it each time.

image A, B, D, and E are incorrect because of the above. (OCP Objectives 3.5 and 3.7)

7. image A is correct. The factory design pattern decouples the caller from the implementation class name.

image B is incorrect because that would be poor design. C is incorrect because it describes the singleton pattern. D is incorrect because it describes the DAO pattern. E is incorrect because of the above. (OCP Objective 3.7)

8. image B is correct. The Data Access Object pattern uses an interface so callers aren’t dependent on a specific implementation class.

image A, C, D, E, and F are incorrect because of the above. (OCP Objective 3.6)

9. image A and C are correct. The DAO pattern centralizes logic for the data access code, making reuse easier and allowing you to switch out implementations.

image B is incorrect because you still have to code the DAO. D is incorrect because you call a DAO from your business object; you do not inherit from it. E is incorrect because you can have many DAO objects. (OCP Objective 3.6)

10. image B and C are correct. Design patterns are conceptual and design level. You have to code the implementation for each use.

image D is incorrect because there are dozens of patterns defined for Java. Only three of them are tested on the exam, but you should be aware that more exist. E is incorrect because it makes sense to reuse the same pattern. For example, you might have multiple DAO objects. A andF are incorrect because of the above. (OCP Objectives 3.5, 3.6, and 3.7)

11. image C is correct.

image A, B, and D are incorrect. A refers to encapsulation, B refers to coupling, and D refers to polymorphism. (OCP Objective 3.3)

12. image C is correct. Generally speaking, public variables are a sign of weak encapsulation.

image A, B, D, and E are incorrect because based on the information given, none of these statements can be supported. (OCP Objective 3.3)