APP下载

装饰设计模式的教学过程研究

2020-08-17朱红梅王鲁

现代信息科技 2020年9期
关键词:设计模式教学过程重构

朱红梅 王鲁

摘  要:针对软件各种设计模式的定义不容易被透彻理解和灵活应用的问题,文章以装饰设计模式为例介绍其教学过程,深入解析装饰设计模式的动机,通过教学案例引入具体问题,从一般实现代码中发现存在的问题,经过分析和重构得出装饰设计模式的结构和要点,使学生对装饰设计模式有更深入的理解,达到让学生日后可以灵活使用该模式的目的。

关键词:设计模式;装饰设计模式;重构;教学过程

中图分类号:TP312;G642.0      文献标识码:A 文章编号:2096-4706(2020)09-0101-03

Teaching Process Research of Decorator Design Pattern

ZHU Hongmei,WANG Lu

(College of Information Science and Engineering,Shandong Agricultural University,Taian  271018,China)

Abstract:Aiming at the problem that the definitions of various software design patterns is not easy to be fully understood and flexibly applied,this paper takes Decorator Design Pattern as an example for teaching process design. The motivation of decoration design pattern is deeply analyzed. A specific problem as teaching case is introduced. From the general implementation of the example existing problems is found. The structure and key points of the decorator design pattern is gotten through analysis and reconstruction,through which the students have a deeper understanding of the decorator design pattern and achieve the purpose of flexible use of it.

Keywords:design pattern;decorator design pattern;reconstruction;teaching process

0  引  言

軟件设计模式是指在软件开发中经过验证并用于解决在特定环境下、重复出现的、特定问题的解决方案,体现了思想级别的成果复用[1]。由于对现代软件产品的通用性、扩展性、复用性要求越来越高,软件开发过程中需求的不断变化和深入使得人们越来越重视软件设计模式。装饰(Decotator)设计模式,也称包装模式,是软件设计模式中的一个重要的设计模式,GoF给出的定义是动态地给一个对象添加一些额外的职责,就扩展对象的功能来说,装饰设计模式比生成子类更为灵活[2]。从定义上来看,初学者很难把握。为达到帮助学生真正理解装饰设计模式的教学目标,教师应成为教学中的导航者、学生学习的帮助者与引路人[3],培养学生从专业的角度来评价设计方案,引导学生领悟优秀设计案例的构思过程[4]。每种模式都有自身独特的应用场景[5],在教学过程中就不能简单给出设计模式的定义和结构图,要求学生照图写代码,而是深入解析装饰设计模式的动机,通过实例引入具体问题,通过对实例的分析和重构得出装饰设计模式的结构和要点。

1  装饰设计模式的出发点

在面向对象软件设计中,很自然就会想到使用继承来扩展对象的功能,由于继承破坏封装,提高了子类与父类之间的耦合性,随着扩展功能的增多子类也会增多,扩展功能的组合也会导致出现各种组合的子类,进而引发子类的膨胀。因此,过度地使用继承来扩展对象的功能存在一定的缺陷。

装饰设计模式的目的就是为了在动态扩展对象功能的同时,避免扩展功能的增多带来子类激增,从而将功能扩展这种变化所导致的影响降为最低。

2  教学案例设计

2.1  实例

人来自不同地区,如北京、上海,不同地区的人又有各种特性,描述人及其特性。如果有特性:高和富,则有组合:高、富、高富等共3个特性描述;用继承实现的结构图如图1所示。如果增加1个特性:帅,则描述一个人可以有组合:高、富、帅、高富、高帅、富帅、高富帅等共7个特性描述。

一般实现:

abstract class Person{ //公共基类

String name;

public abstract void desc();

};

//主体类

class Beijinger extends Person{

public void desc() { System.out.println(name+" 是北京人"); }

};

class Shanghaier extends Person{

public void desc() { System.out.println(name+" 是上海人"); }

};

//扩展类

class highBeijinger extends Beijinger{

public void desc() { super.desc(); System.out.println(" 是高个人"); }

};

class richBeijinger extends Beijinger{

public void desc() { super.desc(); System.out.println(" 是富人"); }

};

class highrichBeijinger extends Beijinger{

public void desc() { super.desc(); System.out.println(" 是高個富人"); }

};

class HighShanghaier extends Shanghaier{……};

class RichShanghaier extends Shanghaier{……};

class highrichShanghaier extends Shanghaier{……};

public class program {

public static void main(String[] args){

highBeijinger hc = new highBeijinger(); hc.setName("Zhangsan");

richBeijinger rc = new richBeijinger(); rc.setName("Lisi");

hc.desc(); rc.desc();

}

}

假设n是地区的个数,m是特性个数,则用继承实现描述人及其特性需要的类的个数是:1+n+n*()=1+n*2m

如果n=2,m=2(高、富),则需要定义1+2*22=9个

类;如果n=2,m=3(高、富、帅),则需要定义1+2*23= 17个类。可见,用继承来扩展对象的功能会导致子类数量的急剧膨胀。虽然这种分析非常直观,但是如果就此直接引入装饰设计模式,学生难以理解。这就需要把一般实现的代码通过重构引出装饰设计模式。

2.2  分析问题重构代码

分析1:观察一般实现的代码可以发现,随着需求的变化,使用继承得到的扩展使子类急剧增多,同时充斥着大量重复代码。这时候的关键是划清责任,以“高”为例说明用组合/聚合代替继承的实现:

class highBeijinger{

Beijinger person; //用聚合代替继承

public void desc() { person.desc();System.out.println(" 是高个人"); }

public highBeijinger(Beijinger person) { this.person = person; }

};

class highShanghaier {

Shanghaier person; //聚合代替继承

public void desc() { person.desc();System.out.println (" 是高个人"); }

public highShanghaier (Shanghaier person) { this.person = person; }

};

分析2:当一个变量的声明类型都是某个基类(Person)的子类(Beijinger,Shanghaier)的时候,就该将它声明为这个基类(Person),由于多态,可以使得它在未来(运行时)成为子类的对象。当把以上代码中的类Beijinger和Shanghaier都替换为Person后,发现这两个类除了类名之外都相同,所以可以合并,变为:

class highPerson{

Person person; //用基类代替子类

public void desc() { person.desc();System.out.println (" 是高个人"); }

public highPerson(Person person) { this.person = person; }

};

分析3:扩展时需要限制这个highPerson类实现抽象接口函数public void desc(),为了保证从继承转为组合/聚合后的函数public void desc()仍然遵循接口规范,还是需要通过继承来完善接口规范,不过只需要继承基类Person。继续对highPerson类作如下修改:

class highPerson extends Person //为实现接口public void desc()继承基类Person

分析4:这里,highPerson、richPerson和highrichPerson三个类中都含有字段Person person。根据重构原则,当多个类中含有重复字段和方法,应该将其提到基类中去。但是,如果将Person person提到Person基类中去,会发现这是不合理的。为解决这个问题,这里设计一个中间类DecoratorPerson。

abstract class DecoratorPerson extends Person{ //中间类

Person person; //以聚合的方式来支持未来多态的变化

public DecoratorPerson(Person person) { this.person = person; }

};

这样,人的特性类就变为:

class highPerson extends DecoratorPerson{

public void desc() { person.desc();System.out.println(" 是高个人"); }

public highPerson(Person person) { super(person); }

};

客户端调用:

Beijinger p=new Beijinger(); p.setName("Zhangsan");

highPerson hc=new highPerson(p); hc.desc();

richPerson rc=new richPerson(p); rc.desc();

分析5:这里,类richPerson和highPerson都繼承自Person,并持有Person类的成员,所以就可以用一个highPerson对象初始化richPerson对象的Person成员,语句如下:

richPerson rp=new richPerson(hc); rp.desc();

这样,不需要组合特性highrichPerson类也可以描述组合特性,就可以删除组合特性类,仅保留单个特性。设n是地区的个数,m是特性个数,则需要的类的最终个数是:1+n+1+m<1+n*2m,开始时的n=2、m=2(高、富),所以需要的类是1+2+1+2=6个。此时,无论是增加地区还是增加特性,只需再增加一个类。重构后增加Handsome特性的结构图如图2所示。

由这个实例的结构图自然就引出了装饰设计模式的结构图,此处不赘述。

2.3  要点

装饰设计模式里的继承是为了接口的规范,组合/聚合是为了将来支持具体实现类、充分利用多态性消除没必要的派生类。既继承又组合/聚合是装饰设计模式的特色。装饰设计模式通过采用组合/聚合而不仅仅是继承的手法根据需要向多个方向扩展相互独立的功能,在运行时动态装配这些功能,实现比定义组合类更灵活的不同功能的组合,这一过程避免了使用继承带来的灵活性差和功能扩展时的子类爆炸问题。

3  结  论

装饰设计模式的上述教学过程已经应用到我校计算机专业软件设计模式课程教学中,学生反映良好。软件设计模式是设计方面的模板,它不是凭空想象出来的,而是实践中的经验总结,老师要向学生传授软件设计模式的形成过程。本文以装饰设计模式为例介绍了它的设计动机,通过具体实例的一般实现及其改进思路,经过分析重构,使学生自然得出装饰设计模式,引导学生发现其要点,这样才能更深入地理解,并把理论思想融合在系统架构中。

参考文献:

[1] 温立辉.软件设计模式分析 [J].科技创新与应用,2020(7):92-93.

[2] GAMMA E,HELM R,JOHNSON R,et al.Design Patterns:Elements of Reusable Object-Oriented Software [M]. New Jersey USA:Addison-Wesley Publishing Company,1995.

[3] 肖力,周斌.推进信息化教学 打造精彩教学设计 [J].物理教师,2020,41(2):25-29+32.

[4] 杨承清,吕耀平,戴庆敏,等.基于直观认知的《园林设计初步》过程性教学改革探析 [J].西南师范大学学报(自然科学版),2019,44(11):161-166.

[5] 纪程宇,朱雪峰.设计模式组合操作优化研究 [J].计算机科学,2020,47(3):19-24.

作者简介:朱红梅(1969.12—),女,汉族,上海崇明人,副

教授,博士,研究方向:知识工程、智能信息处理;王鲁(1981. 11—),男,汉族,山东泰安人,副教授,博士,研究方向:智能信息处理。

猜你喜欢

设计模式教学过程重构
“1+1”作业设计模式的实践探索
长城叙事的重构
智慧图书馆环境下的融贯式服务设计模式研究
重构
学科哲学导向的高中历史教学重构
欣赏教育在中学化学教学中的实施
基于生产者/消费者设计模式的连续音频信号采集系统
浅析基于问题的教学设计模式
基于FPGA的动态可重构系统设计与实现