关于适配器模式,简单的理解就是进行接口转换,使提供服务的程序能适应不同的环境。
一个库或一段代码对外提供了接口,这个接口的表达方式有可能并不为某些调用者所接受。但换一种表达方式这个接口则能很好的适应新的要求。
一个简单的程序 来自 <thinking in C++>
程序会生成Fibonacci 序列,接口就是简单的返回 int型。
fibonacci_generator.h
#ifndef _FIBONACCI_GENERATOR_H_
#define _FIBONACCI_GENERATOR_H_
class FibonacciGenerator
{
private:
int m_N;
int m_Val[2];
public:
FibonacciGenerator();
int operator()();
int count();
};
#endif
fibonacci_generator.cpp
#include "fibonacci_generator.h"
FibonacciGenerator::FibonacciGenerator() : m_N(0)
{
m_Val[0] = 0; m_Val[1] = 1;
}
int FibonacciGenerator::operator()()
{
int nResult = 0;
nResult = m_N > 2 ? m_Val[0] + m_Val[1] : m_N > 0 ? 1 : 0;
++m_N;
m_Val[0] = m_Val[1];
m_Val[1] = nResult;
return nResult;
}
int FibonacciGenerator::count()
{
return m_N;
}
main.cpp
这里是调用者,调用者使用for循环来简单的调用 int 型的接口。
#include <iostream>
#include "fibonacci_generator.h"
using namespace std;
void main()
{
FibonacciGenerator fb;
int i = 0;
for (i = 0; i < 20; i++)
cout << fb.count() << " : " << fb() << endl;
cin >> i;
}
加入适配器模式后 的 示例程序 。。。 。。。
在运行过程中,调用者希望使用迭代器来处理此数列,来得到更简洁的表达方式。这里对原来的Fibonacci生成程序不做改动,只是单独加了一个适配器类。
fibonacci_adapter.h
#include "fibonacci_generator.h"
#include <iostream>
using namespace std;
#ifndef _FIBONACCI_ADAPTER_H_
#define _FIBONACCI_ADAPTER_H_
class FibonacciAdapter
{
private:
FibonacciGenerator m_Fb;
int m_nLen;
public:
FibonacciAdapter(int nSize): m_nLen(nSize) {};
class iterator;
friend class iterator;
class iterator : public std::iterator<std::input_iterator_tag, FibonacciAdapter, ptrdiff_t>
{
private:
FibonacciAdapter &m_FbAdapt;
public:
typedef int value_type;
iterator(FibonacciAdapter &fb) : m_FbAdapt(fb){}
bool operator == (const iterator&) const
{
return m_FbAdapt.m_Fb.count() == m_FbAdapt.m_nLen;
}
bool operator != (const iterator& x) const
{
return !(*this == x);
}
int operator *() const
{
return m_FbAdapt.m_Fb();
}
iterator& operator ++()
{
return *this;
}
iterator operator ++(int)
{
return *this;
}
};
iterator begin(){return iterator(*this);}
iterator end(){return iterator(*this);}
};
#endif
main 函数中采用了新的迭代器的调用方式
main.cpp
此时调用者中没有了for循环,这里使用了std::copy 从第一个元素迭代到最后一个元素,最重要的是我们原来的fibonacci_generator 类没有发生任何的变化。
#include <iostream>
#include <iterator>
#include "fibonacci_adapter.h"
using namespace std;
template<typename Iter>
void PrintSequence(Iter first, Iter last, const char* nm = "",
const char* sep = " ",
std::ostream& os = std::cout)
{
if(nm != 0 && *nm != '/0')
os << nm << ": " << sep;
typedef typename std::iterator_traits<Iter>::value_type T;
std::copy(first, last, std::ostream_iterator<T>(std::cout, sep));
os << std::endl;
}
void main()
{
int i = 0;
FibonacciAdapter fb_adpt(20);
PrintSequence(fb_adpt.begin(), fb_adpt.end(), "initial: ", " ");
cin >> i;
}