C++ - 优化if-else-if结构(二):使用设计模式进行优化

18 篇文章 0 订阅
2 篇文章 0 订阅

1、前言

在之前的文章 C++优化if-else-if结构(一) 中介绍了一些关于优化代码中过多if-else-if结构的情况;采用上述的方式是能够进行一定程度的优化,但上述方法并没有采用面向对象的设计方式(OOD)。

上述代码暴违背了面向对象的设计中要求的设计原则:

(1)、单一职责原则:对类来说,一个类应该只负责一项职责;

在上述类的设计中,类 advNumSequence 包含了比较多的职责,比如说 adv_func1、adv_func2、adv_func3等。

(2)、依赖倒置原则:依赖倒置的中心思想是面向接口编程(或者说面向抽象编程);

在上述类的设计中,根本就没考虑面向接口编程。

(3)、开闭原则(OCP):OCP是编程中最基础、最重要的设计原则,它表明类的设计应该对扩展开放,对修改关闭;

在上述类的设计中,如果想要添加新的功能,就只能修改类 advNumSequence 了,显然是违背了 OCP原则。

2、OOD的设计方式

有如下问题:现有不同的动物,每种动物的行走方式和叫声都不一样,请你进行设计,显示不同动物的信息。

最容易想到的做法如下图所示:

使用时的伪代码如下所示:

void ShowAnimalInfo(Animal * pAnimal){
    if pAnimal->type() is "Tiger":
        pAnimal->Walk();
        pAnimal->Roal();
    else if pAnimal->type() is "Frog":
        pAnimal->Jump();
        pAnimal->Quack();
    else if pAnimal->type() is "Snake":
        pAnimal->Crawl();
        pAnimal->Hiss();
    else:
        ...
}

在上述伪代码中中,虽然已经实现了面向接口编程,但是在函数体内,还是要根据if-else-if结构来判断动物类别,并根据不同的类型,来显示不同的信息,这种做法显示仍然是不满足OCP原则的。下面接介绍一个采用设计模式来优化的方法。关于设计模式的概念在此就不多做描述。

3、策略模式

关于“策略模式”,在《设计模式(GOF)》书中的解释如下:

意图(Intent): 定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。

原理类图:

参与者说明:

Strategy: 策略,

  • 定义所有支持的算法的公共接口,Context 使用这个接口来调用某 ConcreteStrategy 定义的算法;

ConcreteStrategy: 具体策略,

  • 以Strategy为接口实现某种具体算法;

Context: 环境上下文,

  • 用一个ConcretetStrategy对象来配置;
  • 维护一个对Strategy对象的引用;
  • 可定义一个接口来让Strategy访问它的数据;

适用场景:

主要适用于以下场景:

  • 许多相关的类仅仅是行为有异。“策略”提供了一种用于多个行为中的一个行为来配置一个类的方法;
  • 需要使用一个算法的不同变体;
  • 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构;
  • 一个类定义了多种行为,并且这些行为在这个类的操作中以 多个条件语句 的形式出现;

注意事项和细节:

4、使用策略模式进行优化

采用策略模式对类进行重新设计,如下所示:

实现代码如下所示:

MoveBehavior:

class MoveBehavior
{
public:
	virtual void Move() = 0;
};

class WalkBehavior: public MoveBehavior{
public:
	void Move(){ cout << "is walk, "; }
};

class JumpBehavior: public MoveBehavior{
public:
	void Move(){ cout << "is jump, "; }
};

class CrawlBehavior: public MoveBehavior{
public:
	void Move(){ cout << "is crawl, "; }
};

CallBehavior:

class CallBehavior {
public:
	virtual void Call() = 0;
};

class RoarBehavior: public CallBehavior{
public:
	void Call(){ cout << "is roar " << endl; }
};

class QuackBehavior: public CallBehavior{
public:
	void Call(){ cout << "is quack " << endl; }
};

class HissBehavior: public CallBehavior{
public:
	void Call(){ cout << "is hiss " << endl; }
};

Animal:

class Animal{
public:
	virtual void Show() = 0;
};

class Tiger : public Animal{
public:
	Tiger(MoveBehavior* move, CallBehavior *call) : move(move), call(call)
	{}
	void Show(){
		cout << "Tiger :";
		move->Move();
		call->Call();
	}
private:
	MoveBehavior *move;
	CallBehavior *call;
};

class Frog : public Animal{
public:
	Frog(MoveBehavior* move, CallBehavior *call) : move(move), call(call)
	{}
	void Show(){
		cout << "Frog :";
		move->Move();
		call->Call();
	}
private:
	MoveBehavior *move;
	CallBehavior *call;
};

Context:

class Context{
public:
	void setAnimal(Animal * animal){ mp_animal = animal; }

	void op(){ mp_animal->Show(); }
private:
	Animal * mp_animal;
};

main:

void main()
{
	//
	Context *con = new Context;

	//创建Tiger
	WalkBehavior *walk1 = new WalkBehavior;
	RoarBehavior *roar1 = new RoarBehavior;
	Tiger *tiger = new Tiger(walk1, roar1);

	con->setAnimal(tiger);
	con->op();

	//创建Frog
	JumpBehavior *jump1 = new JumpBehavior;
	QuackBehavior *quack1 = new QuackBehavior;
	Frog *frog = new Frog(jump1, quack1);

	con->setAnimal(frog);
	con->op();

	delete tiger; delete roar1; delete walk1;
    delete frog ; delete quack1 ; delete jump1 ;
	delete con;

	return;
}

 运行结果如下所示:

此时如果想要添加一个新的Animal对象,只需要添加如下代码(允许扩展)即可:

//定义Snake对象
class Snake : public Animal{
public:
	Snake(MoveBehavior* move, CallBehavior *call) : move(move), call(call)
	{}

	void Show(){
		cout << "Snake :";
		move->Move();
		call->Call();
	}
private:
	MoveBehavior *move;
	CallBehavior *call;
};

//创建Snake
CrawlBehavior *crawl1 = new CrawlBehavior;
HissBehavior *hiss1 = new HissBehavior;
Snake *snake = new Snake(crawl1, hiss1);

con->setAnimal(snake);
con->op();

运行结果

 

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值