C++实现策略模式

URL过滤算法有很多种,例如STL set (内部采用红黑树实现)、哈希和布隆过滤器 (bloom filter)。设计模式中的策略模式指的是一系列可相互替换的算法,正好可以在URL过滤中应用。以下是该模式的实现。
/*
 * url_filter.h
 *
 *  Created on: Apr 27, 2012
 *      Author: joan
 */

/*
 * in this file, we implement Strategy Pattern
 * there are two or more interchangeable algorithms that can be used
 * we select an appropriate one in a context environment
 */

#ifndef URL_FILTER_H_
#define URL_FILTER_H_

#include "../GLOBAL.h"

class filter_interface;

/*
 * a context class, which selects algorithm for us
 */
class url_filter
{
public:
	//url_filter(filter_interface *in):interf(in){};
	void SetFilter(filter_interface *in);
	bool Unvisited(const string &url);
private:
	filter_interface *interf;
};

/*
 * filter algorithm interface
 */
class filter_interface
{
public:
	virtual bool Unvisited(const string &url)=0;
protected:
	static locker flock;
};

/*
 * concrete filter algorithm A
 * it uses set to filter URLs
 */
class filter_set : public filter_interface
{
public:
	bool Unvisited(const string &url);
private:
	static strset urlset;
};

/*
 * concrete filter algorithm B
 * it uses MD5 and ELFhash to filter URLs
 * and we use link address method to solve collision
 */
class filter_hash : public filter_interface
{
public:
	bool Unvisited(const string &url);
private:
	static tinyHashTable htable;
};

/*
 * concrete filter algorithm C
 * it uses bloom filter to filter URLs
 */
class filter_bloom : public filter_interface
{
public:
	bool Unvisited(const string &url);
private:
	static bloom_filter bloomf;
};

#endif /* URL_FILTER_H_ */
源文件:
/*
 * url_filter.cpp
 *
 *  Created on: Apr 27, 2012
 *      Author: joan
 */

#include "url_filter.h"

void url_filter::SetFilter(filter_interface *in)
{
	interf = in;
}

locker filter_interface::flock;

/*
 * if @url has been visited(filtered), return false, else return true
 */
bool url_filter::Unvisited(const string &url)
{
	return interf->Unvisited(url);
}

/*
 * filter set implementation
 */
strset filter_set::urlset;

/*
 * if the insertion into set succeeds, we say @url is unvisited
 */
bool filter_set::Unvisited(const string &url)
{
	pair<ssitr, bool> ret;
	flock.lock();
	ret = urlset.insert(url);
	flock.unlock();

	return ret.second;
}


/*
 * filter hash implementation
 */
tinyHashTable filter_hash::htable;

/*
 * first we get MD5 of @url, then we use ELFhash to hash MD5,
 * then we use link address method to solve collision
 */
bool filter_hash::Unvisited(const string &url)
{
	tinyMD5 urlmd5;
	string urlkey = urlmd5.GetMD5(url);

	flock.lock();
	int ret = htable.insert(urlkey);
	flock.unlock();
	return ret;
}


/*
 * filter bloom_filter implementation
 */
bloom_filter filter_bloom::bloomf;

/*
 * if insertion into bloom succeeds, true is returned
 * remember that wrong judgment may happen, so the insertion of a unvisited URL may fail
 * anyway, a low rate of wrong judgment is tolerable
 */
bool filter_bloom::Unvisited(const string &url)
{
	flock.lock();
	int ret = bloomf.insert(url);
	flock.unlock();
	return ret;
}

你可能感兴趣的:(C++实现策略模式)