我们一般在客户端会留统一接口从而动态选择我们设计的API
#include<iostream>
#include<functional>
#include<map>
using namespace std;
template<typename T>
class abstractsort
{
public:
virtual void sort(T *p,int begin,int end)=0;
};
template<typename T>
struct _less
{
bool operator()(const T &a,const T &b)
{
return a<b?1:0;
}
};
template<typename T>
struct _greate
{
bool operator()(const T &a,const T &b)
{
return a>b?1:0;
}
};
bool lesscmp(int a,int b)
{
return a<b?1:0;
}
typedef bool (*l)(int,int);
template<typename T,class cmp>
class bubble:public abstractsort<T>
{
cmp cmp_;
bubble &operator=(const bubble &);
bubble(const bubble &);
public:
bubble(cmp c);
void sort(T *p,int begin,int end);
};
template<typename T,class cmp>
bubble<T,cmp>::bubble(cmp c):cmp_(c)
{
}
template<typename T,class cmp>
void bubble<T,cmp>::sort(T *p,int begin,int end)
{
for(int i=begin;i<end;i++)
for(int j=begin;j<end;j++)
{
if(cmp_(p[i],p[j]))
std::swap(p[i],p[j]);
}
}
template<typename T>
void print(T *p,int begin,int end)
{
for(int i=begin;i<end;i++)
std::cout<<p[i];
}
template<typename T,class cmp>
class quick:public abstractsort<T>
{
cmp cmp_;
quick &operator=(const quick&);
quick(const quick &);
int partion(T *p,int begin,int end);
void Sort(T *p,int begin,int end);
public:
quick(cmp c);
void sort(T *,int begin,int end);
};
template<typename T,class cmp>
quick<T,cmp>::quick(cmp c):cmp_(c)
{
}
template<typename T,class cmp>
int quick<T,cmp>::partion(T *p,int begin,int end)
{
T x=*(p+begin);
while(begin!=end)
{
while(begin<end&&cmp_(x,p[end]))end--;
if(begin<end)
{
p[begin++]=p[end];
}
while(begin<end&&!cmp_(x,*(p+begin)))begin++;
if(begin<end)
{
p[end--]=p[begin];
}
}
p[begin]=x;
return begin;
}
template<typename T,class cmp>
void quick<T,cmp>::sort(T *p,int begin,int end)
{
end--;
Sort(p,begin,end);
}
template<typename T,class cmp>
void quick<T,cmp>::Sort(T *p,int begin,int end)
{
if(begin<end)
{
int i=partion(p,begin,end);
Sort(p,begin,i-1);
Sort(p,i+1,end);
}
}
enum level{Bubble,Quick,Null};
/*template<template<typename T1,typename cmp>class T,class Id>
class Sort
{
//T<T1,cmp> *p;
typedef T<T1,cmp> *(*FUN)(cmp c);
typedef std::map<Id,FUN> m;
m m_;
T *creat(const Id &id)
{
typename m::const_iterator i=m_.find(id);
if(i!=m_.end())
{
return (i->second)();
}
return NULL;
}
Sort &operator=(const Sort&);
Sort(const Sort&);
public:
bool registers(const Id &id,FUN fun){return m_.insert(std::make_pair(id,fun)).second;}
bool unregisters(const Id &id){return m_.erase(id)==1;}
//Sort(Id &id){p=creat(id);}
void sort(T1 *a,int begin,int end)
{
//p->sort(a,begin,end);
}
};*/
template<typename T,typename T1>
class Sort
{
T *p;
Sort &operator=(const Sort&);
Sort(const Sort&);
public:
template<class cmp>
Sort(level e,cmp c)
{
switch(e)
{
case Bubble:
p=new bubble<T1,cmp>(c);
break;
case Quick:
p=new quick<T1,cmp>(c);
break;
}
p->sort(a,begin,end);
}
Sort(T *a):p(a){}
void sort(T1 *a,int begin,int end){p->sort(a,begin,end);}
};
int main()
{
int a[10]={0,1,2,3,4,5,6,12,7,8};
_greate<int> l_;
Sort<abstractsort<int>,int> s1(new quick<int,l>(lesscmp));
s1.sort(a,0,10);
print<int>(a,0,10);
}
上面代码质量虽然略差,但已经给出一个接口Sort,构造函数设计成两种模式,简单工厂和策略,简单工厂在这里的优势是可以通过标示符选择,而策略的优势是有新的排序类继承抽象,客户端代码不用改动,而简单工厂需要在switch加语句,这是面向对象要避免的。策略模式弱点是需要具体的选择,以一个mfc程序为例,我们选择下拉框容易获得下拉框的ID,通过ID对应实际操作,而策略模式无法做到这点。如何能让两者结合,我想了很久,最近看到c++设计新思维中泛化的工厂模式刚好能解决这个问题。
在c里这个问题变得异常简单
typedef void (*Sort)(void *,int,int);
static void bubbles(void *p,int begin,int end);
static void quicks(void *,int,int);static Sort s[]={bubbles,quicks};
函数指针数组,甚至没有任何的模式
在c++用function和bind也能秒了模式