SE2811
Software Component Design

This is an old version of this course, from Winter 2013-2014. A newer version is avaliable here.

Objective

The objective for this lab is to demonstrate the Composite pattern by grouping shapes in last week's lab.

Outcomes Addressed

Outcomes are the same as last lab.

Overview

Your primary objective in this lab is to allow composites to be treated identically to components. In other words, a Composite should be treated exactly the same as a Shape. You do not necessarily need to implement "transparency" by having a shape implement everything that a composite does -- more on this in the extra credit section. Do not modify the Rectangle or Ellipse classes in this lab.

To the GUI, we will add a new ShapeListUI GUI. (This makes use of a JList -- do you have experience with this?) The ShapeList. The ShapeManager should communicate with both of the UI windows using the Observer pattern. It should send messages to the observers every time its list of shapes changes.

After adding several shapes, the ShapeList should look something like this:

In the ShapeListUI interface, you should be able to select two or more shapes and combine them into a composite shape via the "Combine" button.

However, the actual combining should be handled in the ShapeManager by a createComposite() method. (Because the ShapeManager changes its list, it should then notify the observers that the shapes have changed, and they should respond by updating their dispays.) This list should remove Shapes from the ShapeManager's list and put them into a composite shape, which is added back to the Shape Manager's list.

The decompose method should undo what createComposite does.

Combined shapes should be drawn with a box around them, and display in the ShapeList as a bracketed, colon-deliminted list. After combining shapes, the ShapeList should look something like this:

As required by the Composite pattern, composites can contain any shape, including other Composites, as shown here:

Assignment

As a starting point, add the CompositeShape and ShapeListUI classes, and implement the Observer pattern to communicate between the ShapeListUI and the DrawingProgramUI.

Next, add the createComposite() and deleteComposite() stubs to ShapeManager and ensure these are correctly tied in to the GUI -- that is, they are called when you click the appropriate buttons.

The Decompose button, as you may suspect, is used to delete the selected CompositeShape (more than one can be selected) while removing (not deleting) constituent Shapes from the composite structure. This is a little tricky to implement, as you have to iterate through the CompositeShape you are deleting and re-add it's constituent Shapes to the collection that previously contained the composite. Hint: Everything displayed in the ShapeListUI is an element within the top-level collection of Shapes maintained by the ShapeMangager. Whenever a CompositeShape is selected for decomposition, you just have to iterate through CompositeShape to be decomposed, and add each of its children to the top-level collection before deleting the CompositeShape from the top-level collection.

Refer to the in-code javadoc comments for more details concerning how the methods ShapeListUI should function.

Details

Once the basic program is working, implement the Decorator pattern by adding the necessary abstract & concrete classes.

'A' Credit

7 points are assigned to the following 'extra'? credit activities:

3 pts
As we discussed in class, in the Composite pattern we make a trade-off between transparency and cohesion. Describe how that trade-off influenced your lab. (Use the definition of transparency given by Head First)
4 pts
Implement a solution that achieves an elegent blend of transparency and cohesion. Two solutions that won't get credit: Implementing add/remove methods in all shapes and requiring implicit casts by users (i.e., the UI) of the Shape class. You may want to check your solution with me if it seems similar to either of these.
3 pts
Describe a few things you tried to keep the ShapeList private while keeping the Observer informed
4 pts
Find a solution that keeps the UIs informed without allowing some rookie in the future to edit the shapes from those programs "accidentally"
4 pts
Implement the Singleton pattern in such a way that it is impossible for the shapes to access the Shape Manager, but the GUI components can.
3 pts
Describe your approach clearly.
other
Suggest your own, and I'll post it here. general principle: If the improvement illustrates a pattern, it will be worth 6 pts, with perhaps a bonus point for extending it. If not, it will be worth 3 pts max.

Your lab total cannot go over 100.

Submission Instructions

Same general principles for UML class diagrams:

  • All classes should have at least one connector to another class on the diagram (or else be in separate figures)
  • Useage lines should often be annotated with "creates" or "manages" or "uses" or other such remarks.
  • If a class is used in multiple places, it should have lines to at least the most significant users holding a reference to an instance of the class, or all methods holding an instance of the class, if that is practical.
  • UML is an art. The goal is to communicate structure. Do you get a sense of the structure of your code when you look at your masterpiece?

Report Format

You will submit this lab in report format with included zip through the web form. (So you will submit a pdf and a zip to the webpage.)

Your report should include the following sections:

Include placeholders for the UML diagrams until your code is stable so they reflect the final version.

Introduction

Describe the lab in 1 or 2 sentences for someone who hasn't heard of it (but knows last week's). You can assume that I'm your audience for the rest of the report.

Main Application

Describe how you implemented the observer pattern in the main application. Describe any challenges you overcame in implementing the observer pattern to communicate between UI components. Ideally, ShapeManager will not expose its shape list directly to the UI component to reduce coupling. On the other hand, you may want to send the entire ShapeList "state" in the updates. Or just send incremental updates.

Use a UML diagram to illustrate what you describe in this section.

Composite Pattern

Describe how you implemented the composite pattern. Reference a UML diagram (either from the previous section, or "zoom in" on the relevant classes) and describe how this pattern helped (or hindered) you to organize your code. This may be two to three paragraphs.

Extra Credit Features

List your extra-credit features in a bulleted list.

Extra-credit sub-sections

Include a sub-section for each extra-credit feature or group of related features. The amount of text needed to describe will vary. Include a UML diagram if helpful.

Missing Features

Describe any missing requirements in a bulleted list. Any discussion of these is optional.

Conclusions

Based on this lab, would you use the Composite pattern again (after this class)? "Yes", "no", "maybe yes", and "maybe no" are equally legitimate, just support your answer. (And make it clear whether you chose maybe yes or maybe no by following proper essay style. Ask me for details.)

Acknowledgement

This lab developed by MSOE faculty.