-
Notifications
You must be signed in to change notification settings - Fork 0
Adapter State
Folder: 10-adapter-state
Intent. Convert the interface of one class into the interface a client expects, so two classes that were not designed to work together can cooperate.
How this code does it. AdapterClass.cpp has a LegacyRectangle whose interface is wrong for the client: it takes corner coordinates and draws through oldDraw. The client wants a Square interface with draw, size, and resize. SquareAdapter bridges the gap. This is the class form of the pattern: the adapter inherits the target Square publicly and the adaptee LegacyRectangle privately. Its draw forwards to oldDraw, size computes the side from the stored corners, and resize calls the rectangle's move. The client only ever sees a Square*.
classDiagram
class Square {
<<interface>>
+draw()* void
+size()* int
+resize(int)* void
}
class LegacyRectangle {
+oldDraw() void
+move(int, int, int, int) void
+getBottomRightX() int
}
class SquareAdapter {
+draw() void
+size() int
+resize(int) void
}
Square <|-- SquareAdapter : implements
LegacyRectangle <|-- SquareAdapter : adapts (private inheritance)
Intent. Let an object change its behavior when its internal state changes, so it looks like the object changed class. Each state is its own object; the context delegates to whichever state it currently holds.
How this code does it. zork.cpp is a small process scheduler. A Process holds a State* and forwards every action (dispatch, block, suspend, exit, unblock) to it. The concrete states Ready, Running, and Blocked each implement only the transitions that make sense for them, and each transition swaps the process to the next state by calling changeState. The states are singletons reached through a static instance, so all processes share one object per state. The main runs a queue of processes and drives them through random transitions until every process has exited.
classDiagram
class Process {
-State* state_
-int pid_
+dispatch() void
+block() void
+changeState(State*) void
}
class State {
<<interface>>
+dispatch(Process*) void
+block(Process*) void
+unblock(Process*) void
+report()* string
}
class Ready {
+instance() State*$
+dispatch(Process*) void
}
class Running {
+instance() State*$
+block(Process*) void
+suspend(Process*) void
+exit(Process*) void
}
class Blocked {
+instance() State*$
+unblock(Process*) void
}
Process o-- State : delegates to current
State <|-- Ready
State <|-- Running
State <|-- Blocked
g++ -std=c++17 10-adapter-state/AdapterClass.cpp -o adapter
./adapter # prompts for an initial and a new size
g++ -std=c++17 10-adapter-state/zork.cpp -o scheduler
./schedulerBoth programs are course demos that I studied and ran; the folder also keeps the scheduler's sample output. Pairing them on one page is my choice, since the two patterns sit close together: the adapter changes an interface, the state changes behavior behind a fixed interface.
Data structures & STL
Design patterns