This is a draft for weekly, detailed outcomes for SWE 2410. It was based on
the slide decks used by Dr. Hasker in Spring, 2025, and generally captures
the main point on each slide or group of two or three slides. Some
material may be off by a week either direction, and there may be
mistakes. See the course notes for additional detail.
The overall structure of the course, with Bloom’s Taxonomic level in parentheses:
- Choosing classes to capture in designs: domain-driven development (Analysis)
- Understanding requirements vs. design
- Understanding classes using RIBS: Responsibilities, Identity, Behavior,
and State
- Using UML class and sequence diagrams to capture designs (Application)
- Using UML at requirements, design, and implementation levels
- Coupling and cohesion as it relates to OO designs (Analysis)
- Design patterns: capturing common solutions (Application)
- What is a design pattern?
- Key design principles related to patterns:
- DRY: Don’t Repeat Yourself
- Programming to interfaces rather than implementations
- Classes should be open to extension, closed to modification
- Liskov Substitution Principle
- Applying MVC to structure projects
- Implementing several design patterns: Strategy, Observer, Decorator, Command
- Thread-based programming (Understanding)
- What are threads
- How
synchronize
can control concurrent access to shared memory
- Cloud computing concepts (Remembering)
- Cloud patterns (Applying)
- Additional design patterns (Understanding)
- Coverage of well-known patterns with the additional goal of illustrating
how patterns would be presented (see next bullet)
- Currently covered: Adapter, Facade, Composite, Factory
- Optional: Proxy, Iterator
- Student presentations of a pattern with illustrating code
- This is a group project worth 10% of their grade
- Groups are created midterm, and class and lab time is allocated for additional work
- Bloom’s level: Analyzing the pattern
- Practical impact: experience presenting technical material
Note that many of these topics are introduced early and reiterated
throughout the course. In addition, the course has a heavy empahsis on
using Git and participating in small teams (2–4 students) on projects.
Week 1: Motivating design, Introduction for Strategy Pattern
- The phases of software development as presented in the waterfall
model: requirements, design, implementation, verification,
maintenance
- This model was limited because it provided little support for
refinement, but it does capture that requirements feed into design
and design feeds into implementation
- Keywords: requirements capture what (the system does) and design captures how (the system fulfills requirements)
- Functional requirements and key non-functional requirements such as
speed, security, and robustness
- Key aspects of design considered in this course: efficiency,
maintainability, and testability
- Object-oriented designs as more flexible than procedural designs
- Key theme in the course: remove if statements, especially ones based on
values which are passed to a method because that introduces strong
coupling, heavy testing requirements
- Do not use
instanceof
in this course
- Solution-space classes vs problem-space (domain) classes
- Using nouns to identify domain classes, verbs to identify methods
- Basic git operations: clone, pull, commit, push
- Preferred git practices in this course:
- Commit and push often, pull often
- Do not use branches
- Using a
.gitignore
file
- A first pattern: Strategy (in week 2 if just one lecture in week 1)
- Goal of Strategy Pattern: remove large multi-branch if statement
covering different, disjoint cases
- Understand the implementation details of applying the Strategy
Pattern to a particular problem
- Identify the elements of a pattern: name, problem, solution w/
diagram, benefits, costs
- Using simple inheritance instead of the Strategy Pattern and
possible consequences
- Patterns generally improve system design, but the costs may be too
high in some cases
Week 2: Design principles, RIBS
- The principle that elements in containers should not typically refer back
to the container because it means the object can be in just one container
and the containers and elements must always be used together in projects
- How the Strategy pattern violates this principle
- Explain the principle of Extend, don't Modify (also called the
Open-Closed Principle)
- Explain why, in many contexts, composition is preferred to inheritance
- Refreshing students on basic class diagram notation: classes, attributes,
methods, associations, generalization, role names, stereotypes
- Identify and make use of appropriate connectors in UML class diagrams
that illustrate generalization (Java extends), realization (Java
implements), composition, and usage, along with labeling connectors to
indicate navigability (arrows), multiplicity (numbers), and end roles
(attribute names)
- Using language to capture relationships: has-a for directed
associations, needs-a for composition, and is-a for generalization.
- The distinction between domain classes (classes in the problem space) and
solution classes (classes that are particular to an implementation)
- Using nouns and verbs as a first cut on classes, methods, but needing to
go beyond this because there are many nouns that don’t work
- Capturing a class’s responsibilities, avoiding doit, system, and action
classes
- Identifying responsibilities for classes.
- Describing state and behavior in classes.
- How identity distinguishes between simple information about
another object (such as the date something was made vs. the item that was
made on that date).
- RIBS: Using responsibility, identity, behavior, and state to distinguish
between objects that made good classes and items that may be
out-of-scope, simple attributes, or otherwise captured without using
classes.
- Additional guidelines: avoiding abbreviations, using singular names,
following standards, and following the Liskov Substitution Principle.
- The need to over-communicate when working in teams on projects (since
lab 2 involves teamwork)
- Discuss sequence diagrams and their goal: capture sequences of events for
particular scenarios
Week 3 and 4: Coupling, Cohesion
- Cohesion as a limited set of responsibilities for a system component and
the need for high cohesion
- Coupling as the interactions between components with a goal of low coupling
so changes in one component are unlikely to introduce changes in another
- Worst form of coupling: content coupling: breaking the encapsulation
provided by the language
- Common coupling: not using information hiding to keep different
components from modifying data without using an interface
- Control coupling: passing control data and the logic that creates
- Stamp coupling: passing more data than you need, especially when there are
no domain concepts to help constrain scope
- Data coupling, the goal: well-defined interfaces
- The fact that “no coupling” is not the goal since that would mean the
components might as well be in different projects
- Coincidental cohesion as just combining items randomly and its causes from
unnecessary rules (no more than 10 lines in a module) or maintenance
- Logical cohesion as a result of control coupling or a desire to just put
all of the hard problems in one place (violating the principle of solving
problems by breaking them down)
- Temporal cohesion: operations only linked by the time they are done,
especially when all of the operations are “in-line”
- Procedural cohesion: inline operations linked by just their sequence
- Communicational cohesion: doing multiple things in a component simply
because they all process the same data, especially for loops
- Hierarchies of coupling and cohesion: particularly avoiding content
coupling, coincidental cohesion, and logical cohesion
- Experience with creating domain level class diagrams in Enterprise
Architect
Week 5: Decorator Pattern
- Explain the context, intent, and motivation of the Decorator Pattern
- The inadequacy of using float and double to compute monetary amounts.
- List the principal attribute defined within the abstract class that
defines an Abstract Decorator which concrete decorators extend
- Illustrate how the sequence diagram captures how a decorator works
- Explain and apply the paradigm of the Favor Composition over Extend
principle with respect to the Decorator Pattern
- Describe how the Decorator Pattern is applied in the java.io package
to various Java I/O classes, such as OutputStream, FileOutputStream,
FilterOutputStream, along with the corresponding InputStream-related classes
- Apply the Decorator Pattern to implement a FilterOutputStream-based
or FilterInputStreambased I/O concrete decorator class that
manipulates the data within an output or input stream
- In lab, apply the Decorator Pattern to extend the behavior of graphical
objects
Week 6: Observer Pattern
- Explain the context, intent, and motivation of the Observer Pattern
- Discuss how the observer pattern is about observing either events or an
event causing a state change in an object.
- State the two principal interfaces comprising the Observer Pattern
- List the principal methods defined by the Observer and Subject interfaces
- Implement the principal methods of the each interface in concrete classes
- Describe the specific consequences (advantages/disadvantages) of the
Observer Pattern
- Identify candidate applications that could implement the Observer Pattern
- Apply the Observer Pattern to a specified application
- Discuss push vs. pull to transmit data to observers.
- Typically: First midterm
Week 7: MVC
- Present the Model/View/Controller (MVC) pattern:
- Introduce the concept of a mental model and point out that the level of
detail that’s appropriate depends on how the model is used.
- MVC is needed because we need to break large software systems into pieces
and we often need to process information from multiple viewpoints.
- The model is typically the domain classes in a project (augmented with
appropriate containers).
- Explain the simple MVC model in which the user acts on a controller which
updates the model. Changes in the model trigger changes in the view.
- Discuss the alternative MVC application in which the user manipulates
the view, that sends events to a controller, the controller updates the
model, and the view refreshes based on model changes. This is a better
fit with web-based systems.
- Point out that when updating the view, it is typically easier to update
all of it than to try to make minimal changes because it improves
consistency.
- Discuss the challenges: that it is not necessarily clear what system
functionality belongs to the model, view, or controller. However, the
advantage of improved modularity means that as long as the team is
consistent, the specific answer to these questions do not matter.
- Start the discussion of the Command pattern:
- In-class activity: reverse-engineer sequence diagrams for an application
of the Command Pattern (before students are presented with the pattern).
- Lab: implementing the Observer Pattern
Week 8: Command Pattern
- Discuss the Command Pattern:
- Motivate the pattern by explaining excise in software systems: actions
the user is forced to take that do not contribute to their goals.
- Discuss forms of excise in software: user interface excise, training
wheels, computer excise, and confirmation prompts.
- Undo as a solution to confirmation prompts.
- How undo can be implemented by saving and restoring a system’s complete
state, but that does not scale when the system stores a lot of data.
- Moving operations into Command objects with execute and unexecute
operations so each individual operation can be done and undone.
- Creating a command history class to track what operations need to be
undone and redone.
- Illustrating the Command Pattern on a simple, GUI system.
- Explain why the system must purge the undo history when the user does
a fresh operation.
- Discuss how command objects capture the parts of the system that was changed
by an operation so that can be undone.
- Point out that developers must define the granularity of command objects
and that sequences of commands can be grouped together to make a larger
command (implementing macros).
- Using the Command Pattern (without undo operations) to create a common
interface to each operation so a different team can be assigned to each.
- Define a program execution as starting a main thread which then starts other
threads, and the program terminates when all threads terminate.
- Explain how to create threads using the Runnable interface, lambdas, and
through timers.
- Explain that the GUI environment (say, JavaFX) creates a UI thread.
- Lab: Applying the Command Pattern to a simple calculator
Week 9: Threads
- Define a process as having its own memory space, execution priority,
credentials, and one or more threads.
- Illustrating simple, multi-threaded applications with Runnable and a lambda
expression.
- Explain that when threads start, there is no implied sequencing between
the different threads, and that this is necessary to maximize efficiency
for thread execution.
- Illustrate that with shared memory, multithreading can result in unexpected
results such as adding two numbers giving the wrong sum.
- Using
join
to wait on a thread, and how this is not a solution to the
concurrency problem because it basically makes programs single-threaded.
- Using synchronized methods and synchronization on an object to implement
monitors in Java.
- Explain that
Platform.RunLater
is needed to ensure code does not change
data that is being displayed by the JavaFX runtime at the same time it is
being displayed.
- Discuss the issue that too much control reduces the advantage of
multi-threaded programming, but too little results in the sorts of errors
presented earlier.
- Lab: Starting presentation projects: having teams pick a pattern to present,
verbalize the key idea they will try to get across during their discussion,
and outlining a project that will illustrate the pattern and the key idea.
Week 10: Cloud Computing
- Motivating cloud computing and defining it as “a model for convenient,
on-demand network access to a shared pool of configurable resources.”
- Discussing what it means for a resource to be virtual.
- Identifying the key issues for cloud developers: virtual resources,
servers going offline at any moment, and message delivery not being
guaranteed.
- Comparing different ways to provide cloud services: a single machine,
containers, and Functions as a Service (FaaS).
- Defining the concept of an API and explaining how cloud services typically
implement a defined API along with the related terms: API endpoint,
API key, and GET and POST.
- Using JSON when transmitting data in the cloud.
- Introducing AWS Lambda as a simple implementation of FaaS, including how
to write, start, and use a Lambda.
- Features of Lambdas: limited compute time and other resources and the
fact that you pay just for execution.
- The cold start problem and how it affects latency, and using provisional
concurrency to provide quick response for users.
- How AWS Step Functions allows ensures lambdas do not have to wait on
each other or external events while capturing basic record processing rules.
- Using the Pub/Sub model (pattern) with channels to connect publishers to
subscribers, and how this model is both similar to and different from
the Observer Pattern.
- How Pub/Sub addresses the basic cloud developer issues: virtual resources,
allowing computers to go offline, message transmission not being predictable.
- Using Pub/Sub for asynchronous processing, and not applying it when there
is no need for scaling, when synchronous communication is required, or to
implement streaming services.
- Using the Singleton Pattern to provide global access to a single, shared
instance of an object.
- Lazy vs. eager initialization of objects and reasons why each are useful
for the Singleton Pattern.
- How multithreading is a problem for lazy initialization with the Singleton
pattern, and why
sychronized
does not provide a good solution.
- Lab: experience with multi-threaded, concurrent access to shared data
structures and how
synchronized
provides a solution.
Week 11: Midterm, Cloud Computing
- Typically have a midterm this week, so the lecture time is devoted to
completing previous discussions and reviewing for the in-class midterm.
- Lab: Implementing a simple API based on AWS Lambda
Week 12: Cloud Computing
- Using the Competing Consumers Pattern to communicate between producers and
consumers when only one consumer is to process each message.
- Benefits of Competing Consumers and reasons to not use the pattern.
- Using databases in the cloud to shared data between lambdas.
- Lab (2 weeks): Implementing a service through Competing Consumers and
a cloud database.
Week 13: Additional patterns: Adapter, Facade
- Discuss how the Adapter Pattern is used to enable changing from a legacy
library to a new library.
- Point out how the Adapter Pattern relies on interface classes to simplify
the transition: program to an interface, not an implementation.
- Applying the Adapter Pattern to a simple example.
- The Adapter Pattern is a structural pattern with advantages and disadvantages.
- Using the Facade pattern to simplify an APIs interface.
- Showing how the Facade pattern can be used to structure a multi-step
operation, including showing how this is captured through a sequence diagram.
- Using Facade to introduce layers, but the cost of doing so being that the
additional layers can be confusing for new developers.
- Possible work day for end-of-semester presentation projects.
- Lab: complete the competing consumers lab
Week 14: Composite, Factory
- Using the Composite Pattern to provide a consistent interface between
elements of a collection and the collection as a whole.
- Transparent vs. opaque Composites
- The Liskov Substitution principle and the fact that opaque composites
follow this principle
- Often the only need to distinguish between elements and composites is
when constructing objects, making opaque very useful.
- Instances of the Composite Pattern in JavaFX libraries.
- Using the Static Factory Method Pattern to provide a consistent interface
for creating objects, and how combining this with a method to write
objects achieves simple serialization.
- Combining the Static Factory Method Pattern and Strategy to implement
a basic system.
- Using the Simple Factory Pattern to add class-based programming to
factory methods.
- Using the more general Factory Pattern for defining interfaces for ways
to create objects.
- How the Factory Pattern (and its relatives) improves coupling and cohesion.
- Lab: finalize presentation
Week 15: Presentations, Final
- Complete discussion on any remaining patterns.
- Optional: covering the Iterator, Proxy patterns.
- Optional: word day preparing for presentations
- Review for final
- lab: Presentations