Skip to content
This repository has been archived by the owner on Jul 23, 2018. It is now read-only.

Commit

Permalink
增加了装饰模式,改动了 Farm 的继承体系
Browse files Browse the repository at this point in the history
  • Loading branch information
ecnelises committed Oct 27, 2017
1 parent df1a6b5 commit acb7981
Show file tree
Hide file tree
Showing 17 changed files with 260 additions and 70 deletions.
16 changes: 13 additions & 3 deletions src/Animal.h
@@ -1,12 +1,22 @@
//
// Animal.h
// 动物类的定义,继承自实体类,作为所有动物的基类存在
//
#ifndef ANIMAL_H
#define ANIMAL_H

#include <memory>
#include "Entity.h"

class Animal {
class Animal : public Entity {
public:
virtual ~Animal() = 0;
// 默认的基类析构函数
virtual ~Animal() = default;

// 动物具有繁殖的特征,可以以一个动物作为原型,进行繁殖,实现原型模式
virtual Animal* clone(void) const = 0;

// 基类提供的共同接口,动物死亡后掉落物品
virtual Item* pick(void) = 0;
};

#endif
22 changes: 11 additions & 11 deletions src/Crop.h
@@ -1,19 +1,19 @@
//
// Crop.h
// 作物类,继承自实体类,作为不同作物类型的基类
//
#ifndef CROP_H
#define CROP_H

#include <memory>
#include "Entity.h"

// 作物类
class Crop{
class Crop : public Entity {
public:
enum Status{
germ,
seedling,
mature,
fruit
};
virtual ~Crop() = 0;
virtual void creat(void) = 0;
// 基类的默认析构函数
virtual ~Crop() = default;

// 继承自基类的方法,作物被采摘后会掉落物品
virtual Item* pick(void) = 0;
};

#endif
7 changes: 4 additions & 3 deletions src/MateAdapter.h → src/CropAdapter.h
@@ -1,5 +1,5 @@
#ifndef MATEADAPTER_H
#define MATEADAPTER_H
#ifndef CROP_ADAPTER_H
#define CROP_ADAPTER_H

#include <iostream>
#include "Potato.h"
Expand All @@ -23,4 +23,5 @@ class TtoPMateAdapter : public Potato, private PTatoto {
return new PTatoto();
}
};
#endif

#endif // CROP_ADAPTER_H
6 changes: 6 additions & 0 deletions src/Decorator.cpp
@@ -0,0 +1,6 @@
#include "Decorator.h"

// 默认的装饰器不附加任何操作,原样执行被装饰者的指定动作
void Decorator::act(Decoratee* dec) {
dec->act();
}
24 changes: 24 additions & 0 deletions src/Decorator.h
@@ -0,0 +1,24 @@
//
// Decorator.h
// 装饰器类定义,可以改写一个对象的方法,实现装饰模式
//
#ifndef DECORATOR_H
#define DECORATOR_H

// 具备某种行为的被装饰者
class Decoratee {
public:
virtual void act(void) = 0;
};

// 不是虚基类,仅作为空的装饰器
class Decorator {
public:
// 基类默认的析构函数
virtual ~Decorator() = default;

// 通过持有 Decoratee 对象来灵活地实现 before_action 等操作
virtual void act(Decoratee* dec);
};

#endif // DECORATOR_H
20 changes: 20 additions & 0 deletions src/Entity.h
@@ -0,0 +1,20 @@
//
// Entity.h
// 实体类的定义,实体是所有生物类的共同基类,具备了共同的属性
//
#ifndef ENTITY_H
#define ENTITY_H

class Item;

class Entity {
public:
// 基类默认的虚析构函数
virtual ~Entity() = default;

// 每种实体被消灭之后都会有一个产物
// 这里的产物可以根据实际情况而变更,作为 Item 类的一个抽象工厂而存在
virtual Item* pick(void) = 0;
};

#endif // ENTITY_H
6 changes: 5 additions & 1 deletion src/Farm.h
@@ -1,3 +1,7 @@
//
// Farm.h
// 农场类,农场是栽培作物的地方
//
#ifndef FARM_H
#define FARM_H

Expand All @@ -12,4 +16,4 @@ class Farm : public Scene {
std::list<Animal*> animals;
};

#endif
#endif // FARM_H
7 changes: 5 additions & 2 deletions src/Map.h
Expand Up @@ -6,6 +6,8 @@
#define MAP_H

#include "Scene.h"
#include "Positioned.h"
#include "Player.h"
#include <vector>
#include <memory>

Expand All @@ -26,9 +28,10 @@ class Map {
void iterateScenes(SceneStrategy* strategy);

// 工厂方法,以生成新的场景
void spawnScene(void);
void generateScene(void);
private:
std::vector<std::unique_ptr<Scene>> scenes;
std::vector<Positioned<Scene>> scenes;
Positioned<Player> player;
};

#endif // MAP_H
16 changes: 16 additions & 0 deletions src/Observable.cpp
@@ -0,0 +1,16 @@
#include "Observable.h"
#include "Observer.h"

void Observable::addObserver(Observer* sub) {
observers.push_back(sub);
}

void Observable::removeObserver(Observer* sub) {
observers.remove(sub);
}

void Observable::notifyObservers(void) {
for (auto i = observers.begin(); i != observers.end(); ++i) {
(*i)->getNotified();
}
}
30 changes: 30 additions & 0 deletions src/Observable.h
@@ -0,0 +1,30 @@
//
// Observable.h
// 抽象出发布者的逻辑,实现观察者模式
//
#ifndef OBSERVABLE_H
#define OBSERVABLE_H

#include <list>

class Observer;

class Observable {
public:
// 基类的默认析构函数
// Observable 对 Observer 不构成所有权关系,不结束它们的生命周期
virtual ~Observable() = default;

// 添加一个观察者
void addObserver(Observer* sub);

// 移除一个观察者,如果不存在则无动作
void removeObserver(Observer* sub);

// 向所有的观察者发送消息
void notifyObservers(void);
private:
std::list<Observer*> observers;
};

#endif // OBSERVABLE_H
10 changes: 10 additions & 0 deletions src/Observer.cpp
@@ -0,0 +1,10 @@
#include "Observer.h"
#include "Observable.h"

void Observer::attach(Observable *pub) {
pub->addObserver(this);
}

void Observer::detach(Observable *pub) {
pub->removeObserver(this);
}
23 changes: 16 additions & 7 deletions src/Observer.h
@@ -1,14 +1,23 @@
//
// Observer.h
// 观察者类的定义,实现观察者模式
//
#ifndef OBSERVER_H
#define OBSERVER_H

#include "Subject.h"
class Observable;

class Observer
{
protected:
Subject subject;
class Observer {
public:
virtual void update();
// 增加一个订阅关系
void attach(Observable* pub);

// 移除一个订阅关系
void detach(Observable* pub);

// 事件发生
virtual void getNotified(void) = 0;
};


#endif // !BACKPACKOBSERVER_H
#endif // OBSERVER_H
5 changes: 1 addition & 4 deletions src/Player.h
Expand Up @@ -10,10 +10,7 @@

class Scene;
class PlayerController;

//enum StateType {
// SLEEP, MOVE, EAT, HUNT, GETPACK
//};
class Food;

class Player {
public:
Expand Down
38 changes: 38 additions & 0 deletions src/Positioned.h
@@ -0,0 +1,38 @@
//
// Positioned.h
// 表示有坐标的类模版,将位置属性与类本身逻辑抽离
//
#ifndef POSITIONED_H
#define POSITIONED_H

#include "Point.h"

template<typename T>
class Positioned {
public:
Positioned(const T& val, Point<double> pos) : entity(val), position(pos) {}
~Positioned() = default;

const Point<double>& getPosition() const {
return position;
}

void setPosition(double x, double y) {
position.x = x;
position.y = y;
}

// const 和非 const 两个版本
const T& get() const {
return entity;
}

T& get() {
return entity;
}
private:
T entity;
Point<double> position;
};

#endif // POSITIONED_H
29 changes: 28 additions & 1 deletion src/Scene.cpp
@@ -1,3 +1,30 @@
#include "Scene.h"
#include <cmath>
#include "Decorator.h"

class SceneGenerateDecoratee : public Decoratee {
public:
SceneGenerateDecoratee(Scene* sce) : scene(sce) {}
virtual ~SceneGenerateDecoratee() = default;
virtual void act(void);
private:
Scene* scene;
};

void SceneGenerateDecoratee::act(void) {
scene->realGenerate();
}

Scene::~Scene() {
delete generateDecorator;
}

void Scene::realGenerate(void) {
auto newbie = this->spawn();
entities.push_back(std::unique_ptr<Entity>(newbie));
}

void Scene::generate(void) {
auto dec = new SceneGenerateDecoratee(this);
generateDecorator->act(dec);
delete dec;
}
41 changes: 33 additions & 8 deletions src/Scene.h
@@ -1,25 +1,50 @@
//
// Scene.h
// 场景类,场景是农场、牧场等类型的基类
//
#ifndef SCENE_H
#define SCENE_H

#include "Point.h"
#include "Observable.h"
#include "Decorator.h"
#include <list>
#include <string>
#include <memory>

class Scene {
class Entity;

// 场景应该保持独立,位置信息不在场景内部
class Scene : public Observable {
public:
Scene(Point<double> cord, std::string n) : coordinate(cord), name(n) {}
virtual ~Scene() = default;
// 利用移动语义构造 name,也只需要一次复制,参数没有必要使用 const 引用
Scene(std::string n, Decorator* dec = new Decorator) :
name(n), generateDecorator(dec) {}

const Point<double>& getCoordinate(void) const {
return coordinate;
}
// 基类需要的析构函数
virtual ~Scene();

// 获取名字
const std::string& getName() const {
return name;
}

// 每个场景都是一个抽象的工厂,生产某种类型的生物
void generate(void);

// 生成生物的具体逻辑由子类提供,构成模版方法模式
virtual Entity* spawn(void) = 0;

// 实际生成并添加生物的操作,公开的 generate 函数是装饰器封装之后的方法
void realGenerate(void);
private:
Point<double> coordinate;
// 每个场景都具有一个独立的名字
std::string name;

// 场景对于其中的实体具有所有权关系
std::list<std::unique_ptr<Entity>> entities;

// 装饰器
Decorator* generateDecorator;
};

#endif // SCENE_H

0 comments on commit acb7981

Please sign in to comment.