Object-Oriented Design… A Revisit - Advanced ActionScript 3: Design Patterns, Second Edition (2015)

Advanced ActionScript 3: Design Patterns, Second Edition (2015)

Chapter 11. Object-Oriented Design… A Revisit

In Chapter 4, I made use of object-oriented analysis to reveal some of the many objects that you will be working with to achieve a successful solution for the Outerlite micro site. If you recall, the chapter concluded without commencing the second phase of the inception process, known as object-oriented design. While you were able to properly analyze your system without any knowledge of design patterns, lacking such information is not practical when determining a proper design.

It was imperative to end that chapter without delving into specifics until you had a better understanding of how these objects can communicate. This can help you maximize your abilities to build an architecture that is well constructed. Only now, with more tools in your toolbox, are you ready to continue with the object-oriented design phase.

Recap

Object-oriented analysis makes use of understanding a problem domain to reveal various objects that are required to solve such a problem. By assessing user flow and client requirements, you are able to gain further insight into added objects and how they will be utilized within your system. The multiple passes of a system during analysis allows for a problem domain to be broken into many smaller problem domains, making it easier to grasp and work with.

Analysis does not always reveal all of the objects that will be used in an application. Many objects may be discarded and additional objects may be required to facilitate existing objects and their associations. What analysis does well is reveal aspects of the big picture in the form of smaller problem domains.

During the object-oriented design phase, your goal will be to finalize all required objects, evaluate their behaviors within their system, and, lastly, to determine their collaborations within the system. You’ll begin with the initially devised list of found objects from the OOA phase ofChapter 4.

Initially Identified Objects

1. Shell

a. Site Loader

2. Site

a. Blurb

b. Navigation

1. Product

2. Scenic

3. Footer

c. Scenario Image XML

d. Scenic Gallery

1. Scenario XML

2. Image Pre-loader

3. Photo

4. Information Call out

i. Info photo

a. Information XML

b. Progress Bar

c. Scenic Description

e. Product Image XML

f. Product Gallery

1. Product XML

2. Interior Navigation

i. Buy Now

ii. Previous

iii. Next

3. Image Pre-loader

4. Product Image

5. Specs

i. Description

ii. Available colors

iii. Available sizes

iv. Buttons

g. Footer

1. Contact Us

2. Store Locator

3. Mailing List

4. Privacy Policy

5. Terms & Conditions

6. Buttons

As the list shows, there are many objects required for each particular problem. While your thorough analysis revealed these objects, you may have duplicates that would be unnecessary in OOP. It’s wise to note that not every duplicate will share a common name, and, likewise, not all objects that have a duplicate name will possess a similar behavior.

In order to properly reveal duplicates in your system, which would be irrelevant, you must properly establish appropriate names for each object that reflect their distinct behaviors in the system. Of course, as of this moment you have not documented any behaviors and therefore will need to do so as well.

Candidate Classes

While the list of objects you found from your object-oriented analysis is not incredibly extensive, this will not always be the case. Depending on the project, you may find yourself working with hundreds of objects. When working with such an extensive number of objects, it becomes difficult to envision so many theoretical objects. For this reason, it’s very convenient to work with what is known as class responsibility/collaborations cards (CRC cards, for short). Unfortunately, CRC cards are not something you can purchase; you actually produce your own utilizing index cards.

The convenience of a CRC card is that you can work with something that is tangible and can be manipulated. Since the time required to create them is minimal, should an object no longer be required by your application, you can easily throw a card away.

Ultimately, a CRC card represents a class, and, as the name suggests, the CRC models the class’s name, responsibility, and its collaborations with other objects. The standard outline of a typical CRC card can be seen in Figure 11-1.

image

Figure 11-1. CRC card

For the moment, you’re not as concerned with a class’s collaborations as you are with its responsibilities and class name. Eventually, you’ll come back to its collaborations. The boundaries of the card represent the class’s encapsulation, where its attributes and behaviors safely reside. The reverse side of the card is available to write in any available interface to which its collaborations of the system can message.

Making use of the CRC card and the currently identified objects, you can elaborate on the responsibilities of each object. Spend a moment to conceive an appropriate name to reflect such behaviors. Figures 11-2 through 11-17 show the CRC cards for your objects.

image

Figure 11-2. Shell object from the identified objects

image

Figure 11-3. Loader object from the identified objects

image

Figure 11-4. Site object from the identified objects

image

Figure 11-5. Blurb object from the identified objects

image

Figure 11-6. Product object from the identified objects

image

Figure 11-7. Added object of the Product Navigation

image

Figure 11-8. Product Gallery object from the identified objects

image

Figure 11-9. Image Preloader object from the identified objects

image

Figure 11-10. Product Image object from the identified objects

image

Figure 11-11. Description object from the identified objects

image

Figure 11-12. Available Colors object from the identified objects

image

Figure 11-13. Interior Navigation object from the identified objects

image

Figure 11-14. Scenic Navigation object from the identified objects

image

Figure 11-15. Added object required by ScenicNavigation

image

Figure 11-16. Information Call Out object from the identified objects

image

Figure 11-17. Footer object from the identified objects

These CRC cards represent the defined class names and responsibilities of each object, without regard to buttons such as “Contact Us” and “Store Locator” for brevity. Assigning appropriate names and behaviors assists in the realization that each object can act as its own problem domain, revealing new objects.

Elimination Phase

Chapter 4 made use of an iterative process to analyze your main problem. However, that is not the sole means of determining objects within a system. Various texts suggest writing a story about the entire user flow of the site, extracting all nouns as possible objects and all verbs as possible methods among the objects. Once all objects have been considered, the process of elimination begins. I’m not as much a fan of this process as I am of the Spiral Method, as I believe repetition is beneficial to the thought process.

Due to your due diligence in the analysis phase, you are fortunate that you don’t have many immediate objects that should be eliminated. You do, however, possess on your list objects that will be required as data but not to be used as classes within your application. The objects up for elimination are the following: Scenario Image XML, Scenario XML, Product Image XML, and Product XML.

With the removal of these XML files, you are left with only candidate classes for which you will devise appropriate collaborations.

Collaborations

All classes are written to fulfill a responsibility. Occasionally, a class is capable of fulfilling such responsibility on its own. In more elaborate systems, classes are written to communicate with other classes and/or objects to fulfill a single responsibility required by a client. It can then be said that each class/object collaborates to fulfill a single responsibility and may require several classes or objects to do so.

Finding collaborations is rather simple, as you already know the responsibilities of each object. What is left is to conceive which objects, if any, are required to aid each other in fulfilling such responsibilities.

As an example, let’s assign the appropriate collaborations, if any, to your Shell object, as shown in Figure 11-18.

image

Figure 11-18. Scenic Navigation object from the identified objects

It is hard to dispute how SiteLoader will assist the responsibility of Shell, but it’s more difficult at a glance to see how Outerlite does; yet the two do in fact collaborate. To better reveal appropriate collaborations, you can make use of class diagrams to demonstrate the associations among the collaborative objects. Making use of the collaborations aspect of the CRC card is yet another step in ensuring that all objects will fulfill a role within an application. If no objects collaborate with an object, and the same object requires no collaborators of its own, then the object does not belong within your system. See Figures 11-19 through 11-28.

image

Figure 11-19. Loader object from the identified objects

image

Figure 11-20. Site object from the identified objects

image

Figure 11-21. Blurb object from the identified objects

image

Figure 11-22. Product object from the identified objects

image

Figure 11-23. Added object of the Product Navigation

image

Figure 11-24. Product Gallery object from the identified objects

image

Figure 11-25. Image Preloader object from the identified objects

image

Figure 11-26. Product Image object from the identified objects

image

Figure 11-27. Description object from the identified objects

image

Figure 11-28. Available Colors object from the identified objects

The ColorPallette’s responsibility reveals the need for a new object, ColorSample. ColorSample will be responsible for representing a singe color to be presented by the ColorPallette. Figure 11-29 makes note of ColorSample’s responsibilities and collaborators. Figures 11-30 through 11-34 show other relationships.

image

Figure 11-29. Inclusion of a necessary object ColorSample

image

Figure 11-30. Interior Navigation object from the identified objects

image

Figure 11-31. Scenic Navigation object from the identified objects

image

Figure 11-32. Added object required by ScenicNavigation

image

Figure 11-33. Information Call Out object from the identified objects

image

Figure 11-34. Footer object from the identified objects

Understanding such collaborations and their associations will further your understanding of how objects connect within the system. There are five main associations: Is a part of, Has-a, Is-a, Knows of, and Depends upon. As you may recall from Chapter 4, I covered each association except for Depends upon, which is a concept you might remember from the Observer pattern (Chapter 8).

Diagramming

You can make use of the Unified Modeling Language (UML) to further elaborate on your collaborations. Remember that there are various diagrams that can assist in describing object collaborations, but this book is only concerned with class diagrams.

Figures 11-35 through 11-37 illustrate your associated objects with the use of UML. One thing to note is the addition of the AbstractView object to which all objects extend. Its purpose will provide default behavior and allow polymorphism among all views.

image

Figure 11-35. High-level diagram of your object collaborations

image

Figure 11-36. Magnified image of your product collaborations

image

Figure 11-37. Magnified image of your scenic collaborations

These objects that you have devised are used as both visual representation of a user’s actions, as well as visual elements with which a user can interact, making them a user interface. To bridge the gap between the user and the application, you know that you can utilize the MVC. Due to the dependencies of these objects and the actions of a user, you can funnel all requests into a localized model to which all subscribing views can respond accordingly. Figure 11-38 represents the inclusion of the Model View Controller to your application.

image

Figure 11-38. Collaborations managed with the MVC pattern

As discussed in Chapter 10, the Controller and the Views work together to maintain the synchronizations among the model. Each View will possess a Controller, which will be responsible for interpreting user interactions and translating them to meaningful input among the model, where state dependent views and controllers can remain synchronized upon notifications from the model. AbstractView, as the superclass to each visual element, allows a Model and Controller to be present.

One dependency that will not be able to be fulfilled by the Model will be the linear succession of the ProductSubNavigation. You know that ProductSubNavigation will allow users to continue to browse the Outerlite product line in a linear fashion with regards to the currently viewed product. It should be apparent that you need to maintain a chosen index by the user to continue to iterate successively either forwards or backwards within a collection, but such data is not a client requirement but rather a design requirement and therefore likely to change.

Therefore, the ProductSubNavigationController will be responsible for translating the index of a collection in a manner that reflects the appropriate direction as chosen by the View, as well as updating the Model with the updated index. You can use an iterator to make use of such functionality. As the user has two ways to navigate the collection, the index of the iterator must remain synchronized to the currently selected index. It will also be the role of the ProductSubNavigationController to ensure this.

The ProductNavigationController is responsible for populating the ProductThumbs from the ProductCollection. As a user may expect the order of their sequence to be the expected order of the ProductSubNavigation, it will be wise to make use of the same iterator to maintain consistency among the ProductCollection. Therefore, it will be the responsibility of the ProductNavigationController to populate the products with the assistance of an iterator (see Figure 11-39).

image

Figure 11-39. ProductSubNavigationController and ProductNavigationController instantiating an Iterator among the ProductCollection

It may also be useful to utilize an iterator to populate the scenic navigation. Of course, with an iterator you have to have a collection, which is something you don’t currently have with your list of objects. Therefore, you have to take this into account, which also means you will need to devise a way to obtain these collections (see Figures 11-40 through 11-43).

image

Figure 11-40. ProductCollection added to your objects

image

Figure 11-41. ScenicCollection added to your objects

image

Figure 11-42. ProductIterator added to your objects

image

Figure 11-43. ScenicCollection added to your objects

With any inclusion of a new object, it’s best to devise their collaborations, if any. Likewise, if they are collaborators of any other objects within the system, such collaborations should be noted.

As you may recall, you had four XML files in the original list, which you removed from your objects, but they will still be utilized once you determine whether you load them in as one XML file or two. Your model will maintain these collections along with the current index where the appropriate data can be obtained.

The Creative Direction

At this moment the implementation phase is almost in sight. There is just one last thing that needs to be done: you need to know the design vision. You have, up to this point, constructed the framework of your application and separated the functionality from the form. Therefore, you are now ready to sprinkle in the details that are the most likely to change and close the chapter on object-oriented analysis and design until your next project.

Implementation

As you can witness from the class diagrams, your application is taking form right before your eyes. You can just about see the big picture of how everything will work together. However, an application does not run on schematics, but rather code. So where does all of this conceptualizing, diagramming, analyzing, and designing get you? It allows you to become familiar with the ins and outs of the application as if you’d been using it for years, even before the application has been constructed. This can only come from proper analysis and design. Having an understanding of the objects, structure, collaborations etc, allows you to truly have an intimate understanding of the code before a single line is written. This is the reason you can take charge as a team leader or be involved with any such changes that arise.

Before you can begin writing code, there’s one last area that must be conceived. This area is the methods, which allow for such collaborations among your objects. What methods must an object possess? What are the return types that are utilized? Such signatures need to be considered.

At this point, you need to take your prior knowledge and all you have learned from this book and apply it here. It is from here that you need to travel on your own.

Chapter Summary

Object-oriented design, object-oriented analysis, and implementation are three entirely separate phases. You may often be tempted to condense all phases into one in haste, but as they say “haste makes waste.” The goal of object-oriented design is to ensure that all objects during implementation are necessary, not redundant—and reusable as well. It also adds more structure in a team environment when each member needs to divide and conquer. Only proper design can come from proper analysis, and only proper implementation can come from proper design. Also, any changes during the phase of implementation can be better combated, as you have already determined the structure for the entire application.