设计模式之策略模式(面向接口编程)

本文探讨了面向实现编程的弊端,如代码冗余和变更性弱,并介绍了面向接口编程的概念,通过策略模式实现行为的接口化和动态更改。在鸭子类的例子中,飞行和叫声行为被抽象为接口,不同鸭子类通过实现接口实现行为多样化。测试类展示了在运行时动态修改鸭子飞行行为的能力,遵循了多用组合、少用继承的设计原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面向实现编程的弊端

举一个简单的动物界的例子,我们需要写一段代码,包含以下要素:鸭子类,鸭子的若干子类,实现一些方法。
惯用的编程思路
1、写一个鸭子类Duck,写几个方法,比如鸭子飞行的方法fly(),鸭子叫的方法quack()。
2、写鸭子的子类,比如绿头鸭MallardDuck,继承Duck类。
3、在子类中重写以上两个方法。
这种编程思路的弊端
1、代码冗杂
在代码量少且代码稳定不变更的情况下似乎不会有什么问题,在实际运行程序时,也是完全不会出错的。但是,假设我们把鸭子的数量增加,增加到一万种鸭子类,我们是不是要重写一万次方法呢?显然这是很费事费力的。另外,假设我们要调用一万次fly()方法,是不是要写一万次调用的程序呢?即:对象名.fly() 。这也会导致代码的冗杂。
2、变更性弱
假设当你下定决心去写那一万种鸭子类,并且快要写完的时候,老板和你说,这个fly()方法不应该这样写,需要改一下,你是不是就要崩溃了,代码几乎是死的,没法变更!
简单分析:这种类型的代码属于硬代码,不仅写的时候代码量繁杂,而且写完后,几乎是没法动的,自然不能适应现在软件需要不断更新版本的要求,需要我们转变编程思路。

面向接口编程的引入

我们一个个地解决这些问题。
1、解决代码冗杂的问题:减少代码量的最好方式就是相同代码的复用,假设一万种鸭子中,有一部分鸭子的fly()方法(行为)是一致的,那么我们可以试着去减少它重复的书写。fly()既需要满足被多处复用的要求,又需要满足可以被特殊地实现的要求,于是我们可以把这种飞行的行为单独地拿出来,使它脱离鸭子类,写一个接口flyBehavior,让fly()方法成为它的成员方法,fly()方法在这里是一种抽象方法,实例化必须改写内容。然后,我们可以写若干子类继承flyBehavior接口,实现行为方法fly(),然后在需要用的时候实例化调用就可以了。似乎这还没有解决一万次调用方法的代码冗杂问题,一万个对象,一万个对象名.fly()肯定是不现实的,我们希望的duck.fly()。解决的方法是在创建对象的时候让子类对象向上转型为父类,通过父类的引用去调用被子类重写后的方法,那么这个问题也解决了。
2、解决变更性弱的问题:这个问题其实已经被上述方法解决,我们修改fly()方法的内容,只要在相应的行为类中修改就可以了,操作起来很方便。其他行为如quack()行为也可以作为接口。除此之外,我们还可以做一些别的事情,比如实现鸭子飞行行为的动态更改,只要在鸭子类中写一个set方法,修改flyBehavior的引用,使得flyBehavior调用不同的fly()方法,实现在程序运行中多态修改飞行参数以及飞行姿态。
小结:以上就体现了面向接口编程的特点:
1、反复被使用的行为被抽象为接口,利用接口的多实现使得行为多实现。
2、行为的反复重写变为了对已经实现的行为的多次调用。
3、父类对象调用子类方法体现了自动转型的思想。
4、实现了多态。

面向接口编程实践

1、Duck类

public abstract class Duck {
   
   
	 FlyBehavior flyBehavior;
	 QuackBehavior quackBehavior;	 
	 /**
	  * 鸭子的外观
	  */
	 public abstract void display();	 
	 /**
	  * 鸭子的身份
	  */
	 public void isDuck()
	 {
   
   
		 System.out.println("我是鸭子");
	 }	 
	 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值