摘抄各类语言设计模式
- 一、继承,封装,多态
- 二、六大设计原则
- 三、创建型模式
- 四、结构型模式
- 五、行为型模式
- 1.策略模式(Strategy Pattern)
- 2.模板模式★(Template Method Pattern)
- 3.观察者模式★(Observer Pattern)
- 4.迭代器模式★(Iterator Pattern)/游标模式(Cursor Pattern)
- 5.责任链模式(Chain of Responsibility Pattern)
- 6.命令模式(Command Pattern)
- 7.备忘录模式(Memento Pattern)
- 8.状态模式(State Pattern)
- 9.访问者模式(Visitor Pattern)
- 10.中介者模式(Mediator Pattern)
- 11.解释器模式(Interpreter Pattern)
一、继承,封装,多态
1.继承性
C
//继承性
// 在设计C语言继承性的时候,我们需要做的就是把基础数据放在继承的结构的首位置即可。
//这样,不管是数据的访问、数据的强转、数据的访问都不会有什么问题
typedef struct _parent
{
int data_parent;
}Parent;
typedef struct _Child
{
struct _parent parent;
int data_child;
}Child;
2.封装性
C
//封装性的意义在于,函数和数据是绑在一起的,数据和数据是绑在一起的
struct _Data;
typedef void (*process)(struct _Data* pData);
typedef struct _Data
{
int value;
process pProcess;
}Data;
3.多态
C
//多态就是说用同一的接口代码处理不同的数据
typedef struct _Play
{
void* pData;
void (*start_play)(struct _Play* pPlay);
}Play;
二、六大设计原则
1.单一职责原则(Single Responsibility Principle,简称SRP)
定义为就一个类而言,应该仅有一个引起它变化的原因。简单来说,一个类中应该是一组相关性很高的函数、数据的封装。
这个原则的意思就是说一个类中功能不要太多,尽量一个类只完成一个功能。
2.里氏替换原则(Liskov Substitution Principle,简称LSP)
定义为所有引用基类的地方必须能透明地使用其子类的对象。
意思是一个用父类能实现功能的地方,用他的子类也可以完成功能。
3.依赖倒置原则(Dependence Inversion Principle,简称DIP)
定义为高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。
这个按字面很难理解,大概的意思是功能实现不能依赖于实体的类,应该依赖于抽象的接口,通过实现接口的方式来实现功能。
4.接口隔离原则(InterfaceSegregation Principles,简称ISP)
定义为客户端不应该依赖它不需要的接口 ,类间的依赖关系应该建立在最小的接口上 。
每个接口所要的实现的功能应该要最小化,只要定义出自己仅需的接口函数就行。
5.迪米特原则(Law of Demeter,简称LOD)
定义为一个对象应该对其他对象保持最少的了解。
这个原则很简单,就是要很好的封装你的类,仅向外界暴露你提供的服务,内部的细节不需要让外面的对象知道。
6.开闭原则(Open Close Principle,简称OCP)
一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
软件的实现完美情况。大概就是说在实现新功能的实话,不需要修改你的代码,只需要拓展代码来实现新的功能。
三、创建型模式
1.工厂模式(Factory Method Pattern)★
C
#define LEATHER_TYPE 0x01
#define RUBBER_TYPE 0x02
Shoe* manufacture_new_shoe(int type)
{
assert(LEATHER_TYPE == type || RUBBER_TYPE == type);
Shoe* pShoe = (Shoe*)malloc(sizeof(Shoe));
assert(NULL != pShoe);
memset(pShoe, 0, sizeof(Shoe));
if(LEATHER_TYPE == type)
{
pShoe->type == LEATHER_TYPE;
pShoe->print_shoe = print_leather_shoe;
}
else
{
pShoe->type == RUBBER_TYPE;
pShoe->print_shoe = print_rubber_shoe;
}
return pShoe;
}
C++
typedef struct _Shoe
{
int type;
void (*print_shoe)(struct _Shoe*);
}Shoe;
oid print_leather_shoe(struct _Shoe* pShoe)
{
assert(NULL != pShoe);
printf("This is a leather show!\n");
}
void print_rubber_shoe(struct _Shoe* pShoe)
{
assert(NULL != pShoe);
printf("This is a rubber shoe!\n");
}
2.抽象工厂(Abstract Factory Pattern)★
C++
//定义水果
typedef struct _Apple
{
void (*print_apple)();
}Apple;
typedef struct _Grape
{
void (*print_grape)();
}Grape;
//抽象
void print_white_apple()
{
printf("white apple!\n");
}
void print_red_apple()
{
printf("red apple!\n");
}
void print_white_grape()
{
printf("white grape!\n");
}
void print_red_grape()
{
printf("red grape!\n");
}
//定义工厂
typedef struct _FruitShop
{
Apple* (*sell_apple)();
Grape* (*sell_grape)();
}FruitShop;
//设计水果店
Apple* sell_white_apple()
{
Apple* pApple = (Apple*) malloc(sizeof(Apple));
assert(NULL != pApple);
pApple->print_apple = print_white_apple;
return pApple;
}
Grape* sell_white_grape()
{
Grape* pGrape = (Grape*) malloc(sizeof(Grape));
assert(NULL != pGrape);
pGrape->print_grape = print_white_grape;
return pGrape;
}
//创建工厂
FruitShop* create_fruit_shop(int color)
{
FruitShop* pFruitShop = (FruitShop*) malloc(sizeof(FruitShop));
assert(NULL != pFruitShop);
if(WHITE == color)
{
pFruitShop->sell_apple = sell_white_apple;
pFruitShop->sell_grape = sell_white_grape;
}
else
{
pFruitShop->sell_apple = sell_red_apple;
pFruitShop->sell_grape = sell_red_grape;
}
return pFruitShop;
}
3.单例/单件模式(Singleton Pattern)★
C
typedef struct _DATA
{
void* pData;
}DATA;
void* get_data()
{
static DATA* pData = NULL;
if(NULL != pData)
return pData;
pData = (DATA*)malloc(sizeof(DATA));
assert(NULL != pData);
return (void*)pData;
}
C++
#include <string.h>
#include <assert.h>
class object
{
public:
static class object* pObject;
static object* create_new_object()
{
if(NULL != pObject)
return pObject;
pObject = new object();
assert(NULL != pObject);
return pObject;
}
private:
object() {}
~object() {}
};
class object* object::pObject = NULL;
int main(int argc, char* argv[])
{
object* pGlobal = object::create_new_object();
return 1;
}
Java
public class Singleton {
private static Singleton Instance;
private Singleton() {
}
public static Singleton getInstance() {
if (Instance == null) {
Instance = new Singleton();
}
return Instance;
}
}
Python
class SingleTon:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(SingleTon, cls).__new__(cls, *args, **kwargs)
return cls._instance
4.建造者模式(Builder Pattern)
C
//建造者模式是对流程本身的一种抽象化处理。
//例如:电脑是由很多部分组成的,每个厂家都只负责其中的一部分,而且相同的组件也有很多的品牌可以从中选择
typedef struct _AssemblePersonalComputer
{
void (*assemble_cpu)();
void (*assemble_memory)();
void (*assemble_harddisk)();
}AssemblePersonalComputer;
//配置intel cpu,samsung 内存、日立硬盘
void assemble_intel_cpu()
{
printf("intel cpu!\n");
}
void assemble_samsung_memory()
{
printf("samsung memory!\n");
}
void assemble_hitachi_harddisk()
{
printf("hitachi harddisk!\n");
}
//配置AMD cpu, kingston内存、西部数据硬盘
void assemble_amd_cpu()
{
printf("amd cpu!\n");
}
void assemble_kingston_memory()
{
printf("kingston memory!\n");
}
void assmeble_western_digital_harddisk()
{
printf("western digital harddisk!\n");
}
5.原型模式(Prototype Pattern)
C
typedef struct _DATA
{
struct _DATA* (*copy) (struct _DATA* pData);
}DATA;
//假设类型data_A
DATA data_A = {data_copy_A};
//定义函数
struct _DATA* data_copy_A(struct _DATA* pData)
{
DATA* pResult = (DATA*)malloc(sizeof(DATA));
assert(NULL != pResult);
memmove(pResult, pData, sizeof(DATA));
return pResult;
};
//使用
struct _DATA* clone(struct _DATA* pData)
{
return pData->copy(pData);
};
C++
//基类
class data
{
public:
data () {}
virtual ~data() {}
virtual class data* copy() = 0;
};
//子类
class data_A : public data
{
public:
data_A() {}
~data_A() {}
class data* copy()
{
return new data_A();
}
};
class data_B : public data
{
public:
data_B() {}
~data_B() {}
class data* copy()
{
return new data_B();
}
};
//使用
class data* clone(class data* pData)
{
return pData->copy();
}
Java
public class WordDocument implements Cloneable {
//文本
private String mText;
//图片名称表
private ArrayList<String> mImages = new ArrayList<String>();
public WordDocument() {
System.out.println("=======WordDocument构造函数=======");
}
@Override
public WordDocument clone() {
try {
WordDocument document = (WordDocument) super.clone();
document.mText = this.mText;
document.mImages = this.mImages;
return document;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
public String getmText() {
return mText;
}
public void setText(String mText) {
this.mText = mText;
}
public ArrayList<String> getmImages() {
return mImages;
}
public void addImages(String mImages) {
this.mImages.add(mImages) ;
}
public void showDocument(){
System.out.println("--------- Word Content Start -----------");
System.out.println("Text :"+mText);
System.out.println("Images list :");
for (String imName : mImages){
System.out.println("image name :"+imName);
}
System.out.println("============= word content end =======");
}
}
//使用
public static void main(String[] args) {
//1. 构建文档对象
WordDocument originDoc = new WordDocument();
//2. 编辑文档,添加图片等.
originDoc.setText("这是一篇文档");
originDoc.addImages("图片1");
originDoc.addImages("图片2");
originDoc.addImages("图片3");
originDoc.showDocument();
WordDocument doc2 = originDoc.clone();
doc2.showDocument();
doc2.setText("这是修改过的Doc2文本");
doc2.showDocument();
originDoc.showDocument();
}
Python
import copy
class Prototype:
def __init__(self):
self._objects = {}
def register_object(self, name, obj):
"""Register an object"""
self._objects[name] = obj
def unregister_object(self, name):
"""Unregister an object"""
del self._objects[name]
def clone(self, name, **attr):
"""Clone a registered object and update inner attributes dictionary"""
obj = copy.deepcopy(self._objects.get(name))
obj.__dict__.update(attr)
return obj
def main():
class A:
pass
a = A()
prototype = Prototype()
prototype.register_object('a', a)
b = prototype.clone('a', a=1, b=2, c=3)
print(a)
print(b.a, b.b, b.c)
if __name__ == '__main__':
main()
#使用
import copy
class A:
def __init__(self):
self.x = 18
self.msg = 'Hello'
class B(A):
def __init__(self):
A.__init__(self)
self.y = 34
def __str__(self):
return '{}, {}, {}'.format(self.x, self.msg, self.y)
if __name__ == '__main__':
b = B()
c = copy.deepcopy(b)
print([str(i) for i in (b, c)])
print([i for i in (b, c)])
四、结构型模式
1.适配器模式(Adapter Pattern)★
C
//定义一个Adapter的数据结构。然后把所有的Adapter工作都由Adaptee来做
typdef struct _Adaptee
{
void (*real_process)(struct _Adaptee* pAdaptee);
}Adaptee;
typedef struct _Adapter
{
void* pAdaptee;
void (*transform_process)(struct _Adapter* pAdapter);
}Adapter;
C++
//充电适配器
class voltage_12v
{
public:
voltage_12v() {}
virtual ~voltage_12v() {}
virtual void request() {}
};
class v220_to_v12
{
public:
v220_to_v12() {}
~v220_to_v12() {}
void voltage_transform_process() {}
};
class adapter: public voltage_12v
{
v220_to_v12* pAdaptee;
public:
adapter() {}
~adapter() {}
void request()
{
pAdaptee->voltage_transform_process();
}
};
2.装饰器模式(Decorator Pattern)★
C
//装饰模式就是那种迭代处理的模式,最经典的地方就是把pObject这个值放在了数据结构里面。
//最重要的两个方面就体现在:prev参数和decorate迭代处理。
typedef struct _Object
{
struct _Object* prev;
void (*decorate)(struct _Object* pObject);
}Object;
void decorate(struct _Object* pObeject)
{
assert(NULL != pObject);
if(NULL != pObject->prev)
pObject->prev->decorate(pObject->prev);
printf("normal decorate!\n");
}
3.代理模式(Proxy pattern)★
C++
typedef struct _PC_Client
{
void (*request)();
}PC_Client;
void ftp_request()
{
printf("request from ftp!\n");
}
void http_request()
{
printf("request from http!\n");
}
void smtp_request()
{
printf("request from smtp!\n");
}
typedef struct _Proxy
{
PC_Client* pClient;
}Proxy;
void process(Proxy* pProxy)
{
assert(NULL != pProxy);
pProxy->pClient->request();
}
4.外观模式(Facade Pattern)
C++
//三种功能
typedef struct _FoodSteet
{
void (*eat)();
}FoodStreet;
void eat()
{
printf("eat here!\n");
}
typedef struct _ShopStreet
{
void (*buy)();
}ShopStreet;
void buy()
{
printf("buy here!\n");
}
typedef struct _BookStreet
{
void (*read)();
}BookStreet;
void read()
{
printf("read here");
}
//聚合三种功能
typedef struct _Plaza
{
FoodStreet* pFoodStreet;
ShopStreet* pShopStreet;
BookStreet* pBookStreet;
void (*play)(struct _Plaza* pPlaza);
}Plaza;
void play(struct _Plaza* pPlaza)
{
assert(NULL != pPlaza);
pPlaza->pFoodStreet->eat();
pPlaza->pShopStreet->buy();
pPlaza->pBookStreet->read();
}
5.桥接模式(Bridge Pattern)
C
//低耦合高内聚
//肉类饺子
typedef struct _MeatDumpling
{
void (*make)();
}MeatDumpling;
//素饺子
typedef struct _NormalDumpling
{
void (*make)();
}NormalDumpling;
//一个饺子买卖的接口
typedef struct _DumplingReuqest
{
int type;
void* pDumpling;
}DumplingRequest;
void buy_dumpling(DumplingReuqest* pDumplingRequest)
{
assert(NULL != pDumplingRequest);
if(MEAT_TYPE == pDumplingRequest->type)
{
return (MeatDumpling*)(pDumplingRequest->pDumpling)->make();
}
else
{
return (NormalDumpling*)(pDumplingRequest->pDumpling)->make();
}
}
6.组合模式(Composite Pattern)
C++
typedef struct _DEV_NODE
{
struct _DEV_NODE* next;
struct _DEV_NODE* child;
void *data;
int (*dev_lookup)(SDEV_NODE *link, funcp process);
}DEV_NODE;
int dev_lookup(SDEV_NODE *link, funcp process)
{
while(NULL != link)
{
process(link);
while(NULL != link->child)
dev_lookup(link->child, process);
link = link->next;
}
}
Java
package composite;
public abstract class Department {
private String name;
public Department(String name) {
this.name = name;
}
public Department() {
}
/**
* 添加
*/
protected abstract void add(Department department);
/**
* 打印
*/
protected abstract void show(int depth);
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//
package composite;
import java.util.ArrayList;
import java.util.List;
public class DinnerDepartment extends Department {
private List<Department> deptList = new ArrayList<Department>();
public DinnerDepartment() {
}
public DinnerDepartment(String name) {
super(name);
}
@Override
protected void add(Department department) {
deptList.add(department);
}
@Override
protected void show(int depth) {
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(new String(sb) + this.getName());
for (Department c : deptList) {
c.show(depth + 2);
}
}
}
//
package composite;
public class HRDepartment extends Department {
public HRDepartment() {
}
public HRDepartment(String name) {
super(name);
}
@Override
protected void add(Department department) {
}
@Override
protected void show(int depth) {
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < depth; i++) {
sb.append("--");
}
System.out.println(new String(sb) + this.getName());
}
}
//
package composite;
public class FinanceDepartment extends Department {
public FinanceDepartment() {
}
public FinanceDepartment(String name) {
super(name);
}
@Override
protected void add(Department department) {
}
@Override
protected void show(int depth) {
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < depth; i++) {
sb.append("--");
}
System.out.println(new String(sb) + this.getName());
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Department root = new DinnerDepartment();
root.setName("北京总公司");
root.add(new HRDepartment("总公司人力资源部"));
root.add(new FinanceDepartment("总公司财务部"));
Department shandongCom = new DinnerDepartment("山东分公司");
shandongCom.add(new HRDepartment("山东分公司人力资源部"));
shandongCom.add(new FinanceDepartment("山东分公司账务部"));
Department zaozhuangCom = new DinnerDepartment("枣庄办事处");
zaozhuangCom.add(new FinanceDepartment("枣庄办事处财务部"));
zaozhuangCom.add(new HRDepartment("枣庄办事处人力资源部"));
Department jinanCom = new DinnerDepartment("济南办事处");
jinanCom.add(new FinanceDepartment("济南办事处财务部"));
jinanCom.add(new HRDepartment("济南办事处人力资源部"));
shandongCom.add(jinanCom);
shandongCom.add(zaozhuangCom);
Department huadongCom = new DinnerDepartment("上海华东分公司");
huadongCom.add(new HRDepartment("上海华东分公司人力资源部"));
huadongCom.add(new FinanceDepartment("上海华东分公司账务部"));
Department hangzhouCom = new DinnerDepartment("杭州办事处");
hangzhouCom.add(new FinanceDepartment("杭州办事处财务部"));
hangzhouCom.add(new HRDepartment("杭州办事处人力资源部"));
Department nanjingCom = new DinnerDepartment("南京办事处");
nanjingCom.add(new FinanceDepartment("南京办事处财务部"));
nanjingCom.add(new HRDepartment("南京办事处人力资源部"));
huadongCom.add(hangzhouCom);
huadongCom.add(nanjingCom);
root.add(shandongCom);
root.add(huadongCom);
root.show(12);
}
}
7.享元模式(Flyweight Pattern)
C
//创建font结构
typedef struct _Font
{
int type;
int sequence;
int gap;
int lineDistance;
void (*operate)(struct _Font* pFont);
}Font;
//定制fontfactory结构
typedef struct _FontFactory
{
Font** ppFont;
int number;
int size;
Font* GetFont(struct _FontFactory* pFontFactory, int type, int sequence, int gap, int lineDistance);
}FontFactory;
//对当前的font判断 若font存在则返回;不存在则创建新font
Font* GetFont(struct _FontFactory* pFontFactory, int type, int sequence, int gap, int lineDistance)
{
int index;
Font* pFont;
Font* ppFont;
if(NULL == pFontFactory)
return NULL;
for(index = 0; index < pFontFactory->number; index++)
{
if(type != pFontFactory->ppFont[index]->type)
continue;
if(sequence != pFontFactory->ppFont[index]->sequence)
continue;
if(gap != pFontFactory->ppFont[index]->gap)
continue;
if(lineDistance != pFontFactory->ppFont[index]->lineDistance)
continue;
return pFontFactory->ppFont[index];
}
pFont = (Font*)malloc(sizeof(Font));
assert(NULL != pFont);
pFont->type = type;
pFont->sequence = sequence;
pFont->gap = gap;
pFont->lineDistance = lineDistance;
if(pFontFactory-> number < pFontFactory->size)
{
pFontFactory->ppFont[index] = pFont;
pFontFactory->number ++;
return pFont;
}
ppFont = (Font**)malloc(sizeof(Font*) * pFontFactory->size * 2);
assert(NULL != ppFont);
memmove(ppFont, pFontFacoty->ppFont, pFontFactory->size);
free(pFontFactory->ppFont);
pFontFactory->size *= 2;
pFontFactory->number ++;
ppFontFactory->ppFont = ppFont;
return pFont;
}
C++
class Flyweight //抽象的享元类
{
public :
virtual void Operator(int i) = 0;
};
class ConcreteFlyweight : public Flyweight //共享的子类
{
public:
void Operator(int i)
{
cout <<"共享的Flyweight: " << i<<endl;
}
};
class UnshareConcreteFlyweight : public Flyweight
{
void Operation(int i)
{
cout << "不共享的Flyweight : " << i << endl;
}
};
class FlyweightFactory //享元工厂
{
private:
map<string, Flyweight*> flyweights; //模块名列表
public:
FlyweightFactory()
{
//这里需要用堆,因为这是给客户程序返回的,如果不用堆,则会返回局部对象的引用
flyweights["x"] = new ConcreteFlyweight();
flyweights["y"] = new ConcreteFlyweight();
flyweights["z"] = new ConcreteFlyweight();//所有的属性为“z”的模块都只对应这个一个实例,这正是享元模式的精髓所在呀
}
Flyweight* GetFlyWeight(string key)
{
if (!flyweights.count(key))
flyweights[key] = new ConcreteFlyweight();
return flyweights[key];
}
map<string, Flyweight*>::size_type CountN()//返回当前可共享的模块数
{
return flyweights.size();
}
};
五、行为型模式
1.策略模式(Strategy Pattern)
C
//策略模式就是统一的方法接口分别对不同类型的数据进行访问
//以播放不同格式的电影为例
typedef struct _MoviePlay
{
struct _CommMoviePlay* pCommMoviePlay;
}MoviePlay;
typedef struct _CommMoviePlay
{
HANDLE hFile;
void (*play)(HANDLE hFile);
}CommMoviePlay;
//统一访问接口
void play_movie_file(struct MoviePlay* pMoviePlay)
{
CommMoviePlay* pCommMoviePlay;
assert(NULL != pMoviePlay);
pCommMoviePlay = pMoviePlay->pCommMoviePlay;
pCommMoviePlay->play(pCommMoviePlay->hFile);
}
void play_avi_file(HANDLE hFile)
{
printf("play avi file!\n");
}
void play_rmvb_file(HANDLE hFile)
{
printf("play rmvb file!\n");
}
void play_mpeg_file(HANDLE hFile)
{
printf("play mpeg file!\n");
}
2.模板模式★(Template Method Pattern)
C
typedef struct _Basic
{
void* pData;
void (*step1) (struct _Basic* pBasic);
void (*step2) (struct _Basic* pBasic);
void (*process) (struct _Basic* pBasic);
}Basic;
//使用
void process(struct _Basic* pBasic)
{
pBasic->step1(pBasic);
pBasic->step2(pBasic);
}
C++
template <typename type>
int compare (type a, type b)
{
return a > b ? 1 : 0;
}
class basic
{
public:
void basic() {}
virtual ~basic() {}
virtual void step1() {}
virtual void step2() {}
void process()
{
step1();
step2();
}
};
class data_A : public basic
{
public:
data_A() {}
~data_A() {}
void step1()
{
printf("step 1 in data_A!\n");
}
void step2()
{
printf("step 2 in data_A!\n");
}
};
3.观察者模式★(Observer Pattern)
C
//提炼共有的object
//如 对话框窗口 菜单窗口 工具栏窗口 这些窗口的 窗口放大、窗口缩小是共有的
typedef struct _Object
{
observer* pObserverList[MAX_BINDING_NUMBER];
int number;
void (*notify)(struct _Object* pObject);
void (*add_observer)(observer* pObserver);
void (*del_observer)(observer* pObserver);
}Object;
//定义观察者
typedef struct _Observer
{
Object* pObject;
void (*update)(struct _Observer* pObserver);
}Observer;
//在observer 创建时把observer 绑定到object上
void bind_observer_to_object(Observer* pObserver, Object* pObject)
{
assert(NULL != pObserver && NULL != pObject);
pObserver->pObject = pObject;
pObject->add_observer(pObserver);
}
void unbind_observer_from_object(Observer* pObserver, Object* pObject)
{
assert(NULL != pObserver && NULL != pObject);
pObject->del_observer(observer* pObserver);
memset(pObserver, 0, sizeof(Observer));
}
//统一更新操作
void notify(struct _Object* pObject)
{
Obserer* pObserver;
int index;
assert(NULL != pObject);
for(index = 0; index < pObject->number; index++)
{
pObserver = pObjecet->pObserverList[index];
pObserver->update(pObserver);
}
}
4.迭代器模式★(Iterator Pattern)/游标模式(Cursor Pattern)
C++
//创建数据容器
typedef struct _Container
{
int* pData;
int size;
int length;
Interator* (*create_new_interator)(struct _Container* pContainer);
int (*get_first)(struct _Container* pContainer);
int (*get_last)(struct _Container* pContainer);
}Container;
//创建迭代器
typedef struct _Interator
{
void* pVector;
int index;
int(* get_first)(struct _Interator* pInterator);
int(* get_last)(struct _Interator* pInterator);
}Interator;
int vector_get_first(struct _Container* pContainer)
{
assert(NULL != pContainer);
return pContainer->pData[0];
}
int vector_get_last(struct _Container* pContainer)
{
assert(NULL != pContainer);
return pContainer->pData[pContainer->size -1];
}
int vector_interator_get_first(struct _Interator* pInterator)
{
Container* pContainer;
assert(NULL != pInterator && NULL != pInterator->pVector);
pContainer = (struct _Container*) (pInterator->pVector);
return pContainer ->get_first(pContainer);
}
int vector_interator_get_last(struct _Interator* pInterator)
{
Container* pContainer;
assert(NULL != pInterator && NULL != pInterator->pVector);
pContainer = (struct _Container*) (pInterator->pVector);
return pContainer ->get_last(pContainer);
}
Java
public static void print(Collection coll){
Iterator it = coll.iterator();
while(it.hasNext()){
String str = (String)it.next();
System.out.println(str);
}
interface Iterator {
public Object next();
public boolean hasNext();
}
class ConcreteIterator implements Iterator{
private List list = new ArrayList();
private int cursor =0;
public ConcreteIterator(List list){
this.list = list;
}
public boolean hasNext() {
if(cursor==list.size()){
return false;
}
return true;
}
public Object next() {
Object obj = null;
if(this.hasNext()){
obj = this.list.get(cursor++);
}
return obj;
}
}
interface Aggregate {
public void add(Object obj);
public void remove(Object obj);
public Iterator iterator();
}
class ConcreteAggregate implements Aggregate {
private List list = new ArrayList();
public void add(Object obj) {
list.add(obj);
}
public Iterator iterator() {
return new ConcreteIterator(list);
}
public void remove(Object obj) {
list.remove(obj);
}
}
public class Client {
public static void main(String[] args){
Aggregate ag = new ConcreteAggregate();
ag.add("小明");
ag.add("小红");
ag.add("小刚");
Iterator it = ag.iterator();
while(it.hasNext()){
String str = (String)it.next();
System.out.println(str);
}
}
}
5.责任链模式(Chain of Responsibility Pattern)
C
//领导类型
typedef struct _Leader
{
struct _Leader* next;
int account;
int (*request)(strcut _Leader* pLeader, int num);
}Leader;
//设置额度
void set_account(struct _Leader* pLeader, int account)
{
assert(NULL != pLeader);
pLeader->account = account;
return;
}
//设置上级领导
void set_next_leader(const struct _Leader* pLeader, struct _Leader* next)
{
assert(NULL != pLeader && NULL != next);
pLeader->next = next;
return;
}
//使用
int request_for_manager(struct _Leader* pLeader, int num)
{
assert(NULL != pLeader && 0 != num);
if(num < 100000)
return 1;
else if(pLeader->next)
return pLeader->next->request(pLeader->next, num);
else
return 0;
}
6.命令模式(Command Pattern)
C
/*
命令模式的目的主要是为了把命令者和执行者分开。老规矩,举个范例吧。
假设李老板是一家公司的头儿,他现在让他的秘书王小姐去送一封信。
王小姐当然不会自己亲自把信送到目的地,她会把信交给邮局来完成整个投递的全过程。
现在,我们就对投递者、命令、发令者分别作出定义。
首先定义post的相关数据。
*/
typedef struct _Post
{
void (*do)(struct _Post* pPost);
}Post;
// Post完成了实际的投递工作,那么命令呢?
typedef struct _Command
{
void* pData;
void (*exe)(struct _Command* pCommand);
}Command;
void post_exe(struct _Command* pCommand)
{
assert(NULL != pCommand);
(Post*)(pCommand->pData)->do((Post*)(pCommand->pData));
return;
}
// 我们看到了Post、Command的操作,那么剩下的就是boss的定义了。
typedef struct _Boss
{
Command* pCommand;
void (*call)(struct _Boss* pBoss);
}Boss;
void boss_call(struct _Boss* pBoss)
{
assert(NULL != pBoss);
pBoss->pCommand->exe(pBoss->pCommand);
return;
}
7.备忘录模式(Memento Pattern)
C
/*
备忘录模式的起源来自于撤销的基本操作。
有过word软件操作经验的朋友,应该基本上都使用过撤销的功能。
举个例子,假设你不小心删除了好几个段落的文字,这时候你应该怎么办呢?
其实要做的很简单,单击一些【撤销】就可以全部搞定了。
撤销按钮给我们提供了一次反悔的机会。
既然是撤销,那么我们在进行某种动作的时候,就应该创建一个相应的撤销操作?
这个撤销操作的相关定义可以是这样的。
*/
typedef struct _Action
{
int type;
struct _Action* next;
void* pData;
void (*process)(void* pData);
}Action;
/*
数据结构中定义了两个部分:撤销的数据、恢复的操作。
那么这个撤销函数应该有一个创建的函数,还有一个恢复的函数。
所以,作为撤销动作的管理者应该包括,
*/
typedef struct _Organizer
{
int number;
Action* pActionHead;
Action* (*create)();
void (*restore)(struct _Organizer* pOrganizer);
}Organizer;
// 既然数据在创建和修改的过程中都会有相应的恢复操作,那么要是真正恢复原来的数据也就变得非常简单了。
void restore(struct _Organizer* pOrganizer)
{
Action* pHead;
assert(NULL != pOrganizer);
pHead = pOrganizer->pActionHead;
pHead->process(pHead->pData);
pOrganizer->pActionHead = pHead->next;
pOrganizer->number --;
free(pHead);
return;
}
8.状态模式(State Pattern)
C
/*
状态模式是协议交互中使用得比较多的模式。
比如说,在不同的协议中,都会存在启动、保持、中止等基本状态。
那么怎么灵活地转变这些状态就是我们需要考虑的事情。假设现在有一个state,
*/
typedef struct _State
{
void (*process)();
struct _State* (*change_state)();
}State;
// 说明一下,这里定义了两个变量,分别process函数和change_state函数。其中proces函数就是普通的数据操作,
void normal_process()
{
printf("normal process!\n");
}
// change_state函数本质上就是确定下一个状态是什么。
struct _State* change_state()
{
State* pNextState = NULL;
pNextState = (struct _State*)malloc(sizeof(struct _State));
assert(NULL != pNextState);
pNextState ->process = next_process;
pNextState ->change_state = next_change_state;
return pNextState;
}
// 所以,在context中,应该有一个state变量,还应该有一个state变换函数。
typedef struct _Context
{
State* pState;
void (*change)(struct _Context* pContext);
}Context;
void context_change(struct _Context* pContext)
{
State* pPre;
assert(NULL != pContext);
pPre = pContext->pState;
pContext->pState = pPre->changeState();
free(pPre);
return;
}
9.访问者模式(Visitor Pattern)
C
/*
访问者模式,听上去复杂一些。
但是,这种模式用简单的一句话说,就是不同的人对不同的事物有不同的感觉。
比如说吧,豆腐可以做成麻辣豆腐,也可以做成臭豆腐。可是,不同的地方的人未必都喜欢这两种豆腐。
四川的朋友可能更喜欢辣豆腐,江浙的人就可能对臭豆腐更喜欢一些。
那么,这种情况应该怎么用设计模式表达呢?
*/
typedef struct _Tofu
{
int type;
void (*eat) (struct _Visitor* pVisitor, struct _Tofu* pTofu);
}Tofu;
typedef struct _Visitor
{
int region;
void (*process)(struct _Tofu* pTofu, struct _Visitor* pVisitor);
}Visitor;
// 就是这样一个豆腐,eat的时候就要做不同的判断了。
void eat(struct _Visitor* pVisitor, struct _Tofu* pTofu)
{
assert(NULL != pVisitor && NULL != pTofu);
pVisitor->process(pTofu, pVisitor);
}
// 既然eat的操作最后还是靠不同的visitor来处理了,那么下面就该定义process函数了。
void process(struct _Tofu* pTofu, struct _Visitor* pVisitor)
{
assert(NULL != pTofu && NULL != pVisitor);
if(pTofu->type == SPICY_FOOD && pVisitor->region == WEST ||
pTofu->type == STRONG_SMELL_FOOD && pVisitor->region == EAST)
{
printf("I like this food!\n");
return;
}
printf("I hate this food!\n");
}
10.中介者模式(Mediator Pattern)
C
/*
中介者模式,听上去有一点陌生。但是,只要我给朋友们打个比方就明白了。
早先自由恋爱没有现在那么普遍的时候,男女之间的相识还是需要通过媒婆之间才能相互认识。
男孩对女方有什么要求,可以通过媒婆向女方提出来;当然,女方有什么要求也可以通过媒婆向男方提出来。
所以,中介者模式在我看来,就是媒婆模式。
*/
typedef struct _Mediator
{
People* man;
People* woman;
}Mediator;
// 上面的数据结构是给媒婆的,那么当然还有一个数据结构是给男方、女方的。
typedef struct _People
{
Mediator* pMediator;
void (*request)(struct _People* pPeople);
void (*process)(struct _Peoplle* pPeople);
}People;
// 所以,这里我们看到的如果是男方的要求,那么这个要求应该女方去处理啊,怎么处理呢?
void man_request(struct _People* pPeople)
{
assert(NULL != pPeople);
pPeople->pMediator->woman->process(pPeople->pMediator->woman);
}
// 上面做的是男方向女方提出的要求,所以女方也可以向男方提要求了。毕竟男女平等嘛。
void woman_request(struct _People* pPeople)
{
assert(NULL != pPeople);
pPeople->pMediator->man->process(pPeople->pMediator->man);
}
11.解释器模式(Interpreter Pattern)
C
typedef struct _Interpret
{
int type;
void* (*process)(void* pData, int* type, int* result);
}Interpret;
//
#define DIGITAL_TYPE 1
#define LETTER_TYPE 2
#define BOTTOM_LINE 3
//数字解释器
void* digital_process(void* pData, int* type, int* result)
{
UINT8* str;
assert(NULL != pData && NULL != type && NULL != result);
str = (UNT8*)pData;
while (*str >= '0' && *str <= '9')
{
str ++;
}
if(*str == '\0')
{
*result = TRUE;
return NULL;
}
if(*str == '_')
{
*result = TRUE;
*type = BOTTOM_TYPE;
return str;
}
if(*str >= 'a' && *str <= 'z' || *str >= 'A' && *str <= 'Z')
{
*result = TRUE;
*type = LETTER_TYPE;
return str;
}
*result = FALSE;
return NULL;
}
//字母解释器
void* letter_process(void* pData, int* type, int* result)
{
UINT8* str;
assert(NULL != pData && NULL != type && NULL != result);
str = (UNT8*)pData;
while (*str >= 'a' && *str <= 'z' || *str >= 'A' && *str <= 'Z')
{
str ++;
}
if(*str == '\0')
{
*result = TRUE;
return NULL;
}
if(*str == '_')
{
*result = TRUE;
*type = BOTTOM_TYPE;
return str;
}
if(*str >= '0' && *str <= '9')
{
*result = TRUE;
*type = DIGITAL_TYPE;
return str;
}
*result = FALSE;
return NULL;
}
//下划线解释器
void* bottom_process(void* pData, int* type, int* result)
{
UINT8* str;
assert(NULL != pData && NULL != type && NULL != result);
str = (UNT8*)pData;
while ('_' == *str )
{
str ++;
}
if(*str == '\0')
{
*result = TRUE;
return NULL;
}
if(*str >= 'a' && *str <= 'z' || *str >= 'A' && *str <= 'Z')
{
*result = TRUE;
*type = LETTER_TYPE;
return str;
}
if(*str >= '0' && *str <= '9')
{
*result = TRUE;
*type = DIGITAL_TYPE;
return str;
}
*result = FALSE;
return NULL;
}