Strategy(策略)
– 定义所有持的算法的公共接口。context使用这个接口来调用某concreteStrategy定义的算法;
ConcreteStrategy(具体策略)
– 以Strategy接口实现某具体算法;
Context(上下文)
– 用一个ConcreteStrategy对象来配置;
– 维护一个对Strategy对象的引用;
– 可定义一个接口来让Strategy访问它的数据;
继承提供了另一种支持多种算法或行为的方法。你可以直接生
成一个Context类的子类,从而给它以不同的行为。但这会将行为硬行编制到Context中,而将
算法的实现与Context的实现混合起来,从而使Context难以理解、难以维护和难以扩展,而且
还不能动态地改变算法。最后你得到一堆相关的类, 它们之间的唯一差别是它们所使用的算法
或行为。将算法封装在独立的Strategy类中使得你可以独立于其Context改变它,使它易于切换、
易于理解、易于扩展。
3、消除了一些条件语句。
4、实现的选择。Strategy模式提供了用条件语句选择所需的行为以外的另一种选
择。当不同的行为堆砌在一个类中时, 很难避免使用条件语句来选择合适的行为。将行为封装
在一个个独立的Strategy类中消除了这些条件语句。
5、客户必须了解不同的Strategy。Strategy模式可以提供相同行为的不同实现。客户可以根据不同时间/空间
权衡取舍要求从不同策略中进行选择。
6、Strategy和Context之间的通信开销。本模式有一个潜在的缺点,就是一个客户要选择一个合适的Strategy就必须知道这些Strategy到底有何不同。此时可能不得不向客户暴露具体的实现问题。因此仅当这些不同行为变体与客户相关的行为时, 才需要使用Strategy模式。
无论各个ConcreteStrategy实现的算法是简单还是复
杂, 它们都共享Strategy定义的接口。因此很可能某些ConcreteStrategy不会都用到所有通过这
个接口传递给它们的信息;简单的ConcreteStrategy可能不使用其中的任何信息!这就意味着有时Context会创建和初始化一些永远不会用到的参数。如果存在这样问题, 那么将需要在Strategy和Context之间更进行紧密的耦合。
中序遍历:左子树+根节点+右子树在遍历左子树和右子树时,仍然先访问根节点,然后遍历左子树,最后遍历右子树。
后序遍历:左子树+右子树+根节点在遍历左右子树时,仍然先遍历左子树,再遍历根节点,后遍历右子树。
在遍历左右子树时,仍然先遍历左子树,在遍历右子树,后访问根节点。
typedef struct tag_tree_node
{
//节点的数据
char data;
//左子节点指针
struct tag_tree_node* left_child;
//右子节点指针
struct tag_tree_node* right_child;
}tree_node_t;
class show_tree_base_t {
public:
virtual void show_tree(tree_node_t* root) = 0;
void visit(tree_node_t* root);
};
void show_tree_base_t::visit(tree_node_t *node){
}
class show_tree_pre_t : public show_tree_base_t{
public:
virtual void show_tree(tree_node_t* root);
};
void show_tree_pre_t::show_tree(tree_node_t *root){
visit(root);
this->show_tree(root->left_child);
this->show_tree(root->right_child);
}
class show_tree_in_t : public show_tree_base_t{
public:
virtual void show_tree(tree_node_t* root);
};
void show_tree_in_t::show_tree(tree_node_t *root){
this->show_tree(root->left_child);
visit(root);
this->show_tree(root->right_child);
}
class show_tree_post_t : public show_tree_base_t{
public:
virtual void show_tree(tree_node_t* root);
};
void show_tree_post_t::show_tree(tree_node_t *root){
this->show_tree(root->left_child);
this->show_tree(root->right_child);
visit(root);
}
tree_node_t* create_tree(){
}
void delete_tree(tree_node_t* root) {
}
class context_t {
public:
void set_show_strategy(show_tree_base_t* obj) {
m_show_tree_obj = obj;
}
void show(tree_node_t *root) {
if (m_show_tree_obj != nullptr && root != nullptr) {
m_show_tree_obj->show_tree(root);
}
}
private:
show_tree_base_t* m_show_tree_obj = nullptr;
};
int main(int argc, char *argv[])
{
show_tree_pre_t* pre = new show_tree_pre_t;
show_tree_in_t* in = new show_tree_in_t;
show_tree_post_t* post = new show_tree_post_t;
context_t* ctx = new context_t;
tree_node_t *root = create_tree();
//先序遍历
ctx->set_show_strategy(pre);
ctx->show(root);
//中序遍历
ctx->set_show_strategy(in);
ctx->show(root);
//后序遍历
ctx->set_show_strategy(post);
ctx->show(root);
delete pre;
delete in;
delete post;
delete_tree(root);
return 0;
}