Abstract factory creation
create similar hierarchies
struct OrcFactory : ArmyFactory {
Fighter* createFighter () override {
return new OrcFighter;
}
Officer* createOfficer () override {
return new OrcOfficer;
}
}
struct OrcBlacksmith : Blacksmith {
Weapon* createWeapon () override {
return new OrcWeapon;
}
}
struct OrcBuilder {
void setWeapon (Weapon weapon) {
orcWeapon = weapon;
}
void setArmor (Armor armor) {
orcArmor = armor;
}
Orc build () {
return Orc (orcWeapon, orcArmor);
}
}
wizard-like object creation
struct OrcBuilder : Armorer, Builder {
Builder* setArmor (Armor armor) override { // Armorer
orcArmor = armor;
return static_cast <Builder*>(this );
}
Orc build () override { // Builder
return Orc (orcWeapon);
}
}
Lazy initialization creation
create object only when it is needed
struct Castle {
Castle () : kitchen (nullptr );
private:
Kitchen& getKitchen () {
if (!kitchen) {
kitchen = createKitchen ();
}
return *kitchen;
}
}
struct Kingdom {
static Kingdom& get (Name name) {
static map<Name,Kingdom> kingdoms;
return kingdoms[name];
}
}
struct OrcObjectMother {
Orc createAngry () {
return Orc (State::Angry);
}
Orc createWounded () {
Orc orc;
orc.setHealth (90 );
return orc;
}
}
store and reuse expensive objects
struct Museum {
Artifact& acquire ();
void release (Artifact& returned);
private:
set<Artifact> all;
set<Artifact*> taken;
}
create objects by copying prototype
struct Monster {
virtual Monster* clone () = 0;
}
struct MonsterFactory {
Monster* create (Type type) {
return prototypes[type]->clone ();
}
private:
map<Type, Monster*> prototypes;
}
Resource acquisition is initialization (RAII) creation
make object responsible for its resources
struct OrcShaman {
OrcShaman () {
ManaSource::addLeacher (this );
}
~OrcShaman () {
ManaSource::removeLeacher (this );
}
}
struct Earth {
static Earth& instance () {
static Earth earth;
return earth;
}
int getRadius () const {
return radius;
}
private:
Earth ();
int radius;
}
many instances with single state
struct Earth {
Earth ();
int getRadius () const {
return Earth::radius;
}
private:
static int radius;
}
Abstract document structure
dynamically manage properties
struct MonsterDocument {
void set (Type, Value);
Value get (Type);
}
struct Orc : MonsterDocument, Armed {
Weapon weapon () override { // Armed
return Weapon (get (Type::Weapon));
}
}
struct OrcTypeAdapter : Monster, Orc {
void attack () override {
Orc::smash ();
}
}
struct OrcObjectAdapter : Monster {
void attack () override {
orc.smash ();
}
}
separate interface and implementation changes
struct Fighter : Soldier {
Fighter (Creature* impl);
void attack () override {
impl->attackImpl ();
}
}
struct Orc : Creature {
void attackImpl () override ;
}
treat composite object same way as single
struct Kingdom : Area {
double square () override {
return sum (owned, Area::square ());
}
void addArea (Area*) override ;
private:
set<Area*> owned;
}
dynamically add/remove behavior to object
struct Walled : public Town {
Walled (Town* decorated);
int strength () override {
return decorated->strength () + 10 ;
}
}
Town* castle = new Walled (new Town ());
Event aggregator structure
gather all events in one place
struct Aggregator {
void subscribe (Subscriber*);
void publish (Event event) {
each (subscribers,
Subscriber::handle (event));
}
}
officer.subscribe (fighter);
officer.publish (AttackEvent ());
Extension object structure
provide additional interface without inherritance
struct Kingdom {
Kingdom (Capital* capital);
Capital* getCapital () {
return capital;
}
}
single interface for several subsystems
struct Army {
void attack () {
officers->makeOrders ();
fighters->followOrders ();
shamans->prey ();
}
}
many similar objects with shared state
struct Forge {
Weapon craft (Type type) {
return Weapon (stats[type]);
}
private:
map<Type, WeaponStats*> stats;
}
Front controller structure
handle all requests in one place
struct Controller {
void handle (Request request) {
getProcessor (request.type )
.process (request);
}
Processor getProcessor (RequestType);
}
struct Orc : Agressive {
}
if (dynamic_cast <Agressive*>(monster))
monster->attack ();
if (dynamic_cast <Defensive*>(monster))
monster->guard ();
group connected functions
struct ConsoleModule {
void prepare ();
void unprepare ();
static ConsoleModule& instance ();
void print (Variant);
variant scan ();
}
partially simulate object behaviour for testing
struct Shaman {
Spell* castSpell () {
openSpellbook ();
Glyph* glyph = findSpell ();
return glyph->cast ();
}
}
struct ShamanMock {
Spell* castSpell () {
return new MightySpell ();
}
}
add behaviour to existing interface
struct GuardedArmoryProxy : Armory {
GuardedArmory (Armory* armory);
void enter (Orc& orc) override {
if (looksFriendly (orc))
armory->enter (orc);
else
logFailure (orc);
}
}
Service locator structure
ease and cache service discovery
struct OrcIntelligence {
static Area locate (Army army) {
if (!lastSeen.contains (army)) {
lastSeen[army] = lookFor (army);
}
return lastSeen[army];
}
private:
map<Army, Area> lastSeen;
}
integrate many modules in complex strategy
struct Intelligence {
void updateDisposition () {
// gather knowledge from sources
each (scouts, Source::update (map));
// process knowledge
correctConflicts (map);
// configure sources
killLiars (scouts);
}
private:
Blackboard map;
set<Source*> scouts;
}
Chain of responsibility behavior
unknown concrete handler for concrete request
struct OrcFighter : RequestHandler {
OrcFighter (RequestHandler* next);
void handle (Request req) override {
if (req.type == Type::Attack) {
attack ();
// more logic
if (++req.done > 10 ) return ;
}
if (next) next->handle (req);
}
}
hold all required data to perform/abort event
struct Move : Command {
Move (Army army, Area from, Area to);
void execute () override {
from.removeArmy (army);
to.addArmy (army);
}
void abort () override {
to.removeArmy (army);
from.addArmy (army);
}
}
provide functionality via composition part
struct OrcFighter {
Size weaponSize () const {
return weapon.size ();
}
}
Dependency injection behavior
use constructed dependency
struct OrcFighter {
OrcFighter (AbstractArmor* armor);
void hit (Damage damage) {
health -= armor->reduce (damage);
}
}
dynamically enable/disable code branches
struct OrcFighter {
void attack () {
if (FeatureToggle::isOn (Stealth)){
hiddenAttack ();
}
else {
simpleAttack ();
}
}
}
Intercepting filter behavior
add pre/post-processing to requests
struct FilterManager {
FilterManager (Target* target);
void handle (Request request) {
each (filters,
Filter::handle (request));
target->deliver (request);
}
private:
list<Filter*> filters;
}
handle AST of domain specific language
struct Plus : Expression {
Plus (Expression& left, Expression& right);
Value interpret () override {
return left.interpret ()
+ right.interpret ();
}
}
traverse container without knowing its structure
struct OrcIterator {
OrcIterator& operator ++ (); // next
Orc& operator -> (); // value
bool operator != (const OrcIterator&) const ;
}
for (OrcIterator it = army.begin (),
end = army.end (); it != end; ++it) {
it->attack ();
}
hide objects interacion details
struct OrcTrainingCamp {
void train (Orc& old, Orc& young) {
young.raiseSkill (old.skill ());
}
}
save/restore object’s state
struct Orc {
Memento state () {
return Memento {this ->health };
}
void restore (Memento memento) {
this ->health = memento.health ;
}
class Memento {
int health;
friend class Orc ;
}
}
multiple method calls in one expression
struct Orc {
Orc& setName (Name name) {
this ->name = name;
return *this ;
}
Orc& setWeapon (Weapon);
}
Orc orc = Orc().setName (" Named" )
.setWeapon (Sword());
specific object for empty (null) behaviour
struct FakeOrc : Orc {
void attack () override {}
}
Orc* makeNewOrc () {
if (!reachedLimit ()) return new Orc;
return new FakeOrc;
}
notify subscribers about publisher events
struct OrcCampObserver : Observer {
void notify (Event& event) override {
each (orcs, Orc::handle (event));
}
}
struct OrcCamp : Observable {
void addObserver (Observer) override ;
void dinnerTime () {
each (observers,
Observer::notify (DinnerEvent ()));
}
}
add behaviour to other classes
struct Blacksmith {
void sharpenWeapon (Fighter*);
}
filter of validate objects with dynamic rules
struct BySkill : Specification {
bool check (Orc& orc) override {
return orc.gotSkill (Sneak);
}
}
void recruit (Orc& orc) {
auto filter = BySkill ().and (ByMana ());
if (filter.check (orc)) {
assignForImportantMission (orc);
}
}
behavior depends on finite internal states
struct Orc {
void fear () {
setState (new ScaredState (this ));
}
void attack () {
state->attack ();
}
}
struct ScaredState : OrcState {
void attack () override {
owner->flee ();
}
}
use group of interchangeable algorithms
struct Orc {
void attack () {strategy->attack ();}
private:
AttackStrategy* strategy;
}
struct Defensive : AttackStrategy {
void attack () override {
raiseShield ();
swordAttack ();
}
}
override only part of algorithm
struct Orc {
virtual Target* chooseTarget ();
virtual hitTarget () = 0;
void stepBack ();
void attack () {
auto target = chooseTarget ();
hitTarget (target);
stepBack ();
}
}
unified processing of different types
struct Dragon {
void eatImpl (Food);
Food makeFood (Orc);
Food makeFood (Dwarf);
template <class T >
void eat (T t) {
eatImpl (makeFood (t));
}
}
apply operation on object’s elements
struct ArmyMeleePower : Visitor {
void visit (Melee& orc) override {
this ->power += orc.power ();
}
void visit (Ranged& orc) override {}
}
struct Melee : Visitable {
void accept (Visitor& visitor) override {
visitor.visit (*this );
}
}
separate execution and invocation threads
struct ActiveObject {
void addCommand (Command command) {
this ->commands << command;
}
~ActiveObject () {
thread thread ([this ]() {
each (commands, Command::exec ());
}
thread.join ();
}
}
non-blocking method call in remote thread
struct Shaman {
void resurrect (Creature& dead) {
Finder& remote = astral.soul (dead);
if (!remote.isReady ()) drink ();
Soul& soul = astral.takeSoul (remote); // blocks
dead.revive (soul);
}
}
struct Barracks {
Fighter* trainRecruit () {
AutoLock lock;
if (!gotRecruits ()) return {};
return train (takeRecruit ());
}
void addRecruit (Recruit recruit) {
AutoLock lock;
addRecruit (recruit);
}
}
synchronize several properties
template <class T > struct Property <T> {
void bind (Property<T>* other);
void set (T value) {
preventInfiniteRecursion ();
other->set (value);
}
}
house.isWarm.bind (&heater.isOn);
ordered appendable chain of verified transactions
struct OrcHistorian : BlockchainNode {
bool addLegend (Legend legend) {
if (!verify (legend)) return false ;
bool accepted = all (others, &OrcHistorian::addLegend (legend))
if (accepted) writeLegend (legend);
return accepted;
}
private:
list<OrcHistorian> others;
}
Double-checked locking async
reduce locking overhead for conditional
struct Tavern {
bool close () {
if (state != Empty) return false ;
// be sure in interested case
AutoLock lock;
if (state == Empty) state = Closed;
}
}
struct Barracks {
Fighter* trainRecruit () {
while (true ) {
if (AutoLock lock, gotRecruits ())
return train (takeRecruit ());
wait ();
}
}
void addRecruit (Recruit recruit) {
AutoLock lock;
addRecruit (recruit);
}
}
pipleine of sync/async messaging channels
struct Channel {
void put (Message* message);
Message* get ();
}
struct Forge : Pipe {
void craft (Message* iron, Message* crafter);
}
Tavern ().when (minesChannel).and (craftersChannel).do (Forge::craft);
block if resource is busy
struct Tavern {
void enter () {
lock.acquire (); // blocks if busy
++customers;
lock.release ();
}
void leave () {
lock.acquire (); // blocks if busy
--customers;
lock.release ();
}
}
allow conditional access to guarded resourse
struct Tavern {
void enter () {
lock.acquire ();
while (isFull ()) {
monitor.wait (lock, queue1); // release on sleep, acquire on wake
}
++customers;
lock.release ();
}
void leave () {
AutoLock lock (this ->lock )
--customers;
monitor.wakeOne (queue1);
}
}
gather async requests and send to async handlers
struct Forge {
void exec () {
each (mines, Mine::startDig (), static_cast <OnDone> (Forge::craft));
}
void craft (Iron iron) {
nextCrafter ()->asyncCraft (iron, static_cast <OnDone> (::deliver));
}
}
gather async requests and send to sync handlers
struct Forge {
void exec () {
while (true ) {
for (Iron& i: getAllReadyIron ()){
craft (i);
}
waitForMoreIronReady (timeout);
}
}
void craft (Iron iron) {
::deliver (nextCrafter ()->craft (iron));
}
}
allow concurrent reads, but exclusive writes
struct Tavern {
list<Customer> customers () const {
rwLock.readAcquire (); // allow many
auto result = customers;
rwLock.readRelease ();
return result;
}
void addCustomer (Customer customer) {
rwLock.writeAcquire (); // allow one
customers << customer;
rwLock.writeRelease ();
}
}
control resource usage time
struct Forge : Scheduler {
void requestAnvil (Crafter user) {
plan.add (user);
}
void exec () {
while (true ) {
Crafter& current = anvil.user ();
if (!current.isFinished ()) {
current.pause ();
plan.add (current);
}
Crafter& next = plan.takeNext ();
anvil.setUser (next);
waitForNextEvent (plan);
}
}
}
execute task in idle thread from pool
using Staff = Thread;
struct Tavern {
void addVisitor (Visitor visitor) {
queue << new ServeEvent (visitor);
if (gotIdle ()) processQueue ();
}
void processQueue () {
while (Staff* staff = nextIdle ()) {
if (Event* e = queue.takeNext ())
staff.run (e);
else break ;
}
}
}
Active record architecture
manupilate single row in database
struct Orc {
void save () {
run (" insert into orcs values(?,?)" , id, name);
}
void remove () {
run (" delete from orc where id = ?" , id);
}
static Orc* find (Name name);
}