upgrade structures and migrate to nextra v4
This commit is contained in:
147
content/CSE332S/CSE332S_L17.md
Normal file
147
content/CSE332S/CSE332S_L17.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# CSE332S Lecture 17
|
||||
|
||||
## Object Oriented Programming Building Blocks
|
||||
|
||||
OOP Building Blocks for Extensible, Flexible, and Reusable Code
|
||||
|
||||
Today: Techniques Commonly Used in Design Patterns
|
||||
|
||||
- **Program to an interface** (last time)
|
||||
- **Object composition and request forwarding** (today)
|
||||
- Composition vs. inheritance
|
||||
- **Run-time relationships between objects** (today)
|
||||
- Aggregate vs. acquaintance
|
||||
- **Delegation** (later...)
|
||||
|
||||
Next Time: Design Patterns
|
||||
|
||||
Describe the core of a repeatable solution to common design problems.
|
||||
|
||||
### Code Reuse: Two Ways to Reuse a Class
|
||||
|
||||
#### Inheritance
|
||||
|
||||
Code reuse by inheriting the implementation of a base class.
|
||||
|
||||
- **Pros:**
|
||||
- Inheritance relationships defined at compile-time - simple to understand.
|
||||
- **Cons:**
|
||||
- Subclass often inherits some implementation from superclass - derived class now depends on its base class implementation, leading to less flexible code.
|
||||
|
||||
#### Composition
|
||||
|
||||
Assemble multiple objects together to create new complex functionality, forward requests to the responsible assembled object.
|
||||
|
||||
- **Pros:**
|
||||
- Allows flexibility at run-time, composite objects often constructed dynamically by obtaining references/pointers to other objects (dependency injection).
|
||||
- Objects known only through their interface - increased flexibility, reduced impact of change.
|
||||
- **Cons:**
|
||||
- Code can be more difficult to understand, how objects interact may change dynamically.
|
||||
|
||||
### Example: Our First Design Pattern (Adapter Pattern)
|
||||
|
||||
**Problem:** We are given a class that we cannot modify for some reason - it provides functionality we need, but defines an interface that does not match our program (client code).
|
||||
|
||||
**Solution:** Create an adapter class, adapter declares the interface needed by our program, defines it by forwarding requests to the unmodifiable object.
|
||||
|
||||
Two ways to do this:
|
||||
|
||||
```cpp
|
||||
class unmodifiable {
|
||||
public:
|
||||
int func(); // does something useful, but doesn’t match the interface required by the client code
|
||||
};
|
||||
```
|
||||
|
||||
1. **Inheritance**
|
||||
|
||||
```cpp
|
||||
// Using inheritance:
|
||||
class adapter : protected unmodifiable {
|
||||
// open the access to the protected member func() for derived class
|
||||
public:
|
||||
int myFunc() {
|
||||
return func(); // forward request to encapsulated object
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
2. **Composition**
|
||||
|
||||
```cpp
|
||||
class adapterComp {
|
||||
unmodifiable var;
|
||||
public:
|
||||
int myFunc() {
|
||||
return var.func();
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Thinking About and Describing Run-time Relationships
|
||||
|
||||
Typically, composition is favored over inheritance! Object composition with programming to an interface allows relationships/interactions between objects to vary at run-time.
|
||||
|
||||
- **Aggregate:** Object is part of another. Its lifetime is the same as the object it is contained in. (similar to base class and derived class relationship)
|
||||
- **Acquaintance:** Objects know of each other, but are not responsible for each other. Lifetimes may be different.
|
||||
|
||||
```cpp
|
||||
// declare Printable Interface
|
||||
// declare printable interface
|
||||
class printable {
|
||||
public:
|
||||
virtual void print(ostream &o) = 0;
|
||||
};
|
||||
// derived classes defines printable
|
||||
// interface
|
||||
class smiley : public printable {
|
||||
public:
|
||||
virtual void print(ostream &o) {
|
||||
o << ":)";
|
||||
};
|
||||
};
|
||||
// second derived class defines
|
||||
// printable interface
|
||||
class frown : public printable {
|
||||
public:
|
||||
virtual void print(ostream &o) {o << ":(";
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
1. **Aggregate**
|
||||
|
||||
```cpp
|
||||
// implementation 1:
|
||||
// Aggregate relationship
|
||||
class emojis {
|
||||
printable * happy;
|
||||
printable * sad;
|
||||
public:
|
||||
emojis() {
|
||||
happy = new smiley();
|
||||
sad = new frown();
|
||||
};
|
||||
~emojis() {
|
||||
delete happy;
|
||||
delete sad;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
2. **Acquaintance**
|
||||
|
||||
```cpp
|
||||
// implementation 2:
|
||||
// Acquaintances only
|
||||
class emojis {
|
||||
printable * happy;
|
||||
printable * sad;
|
||||
public:
|
||||
emojis();
|
||||
~emojis();
|
||||
// dependency injection
|
||||
void setHappy(printable *);
|
||||
void setSad(printable *);
|
||||
};
|
||||
```
|
||||
Reference in New Issue
Block a user