本文通过学校、班级、小组与学生的层级案例,深入解析JavaScript中的组合模式。文章首先展示基于独立类的传统实现方式,指出其在扩展性上的不足;随后引入组合模式,将对象划分为组合节点与叶子节点,统一操作接口。通过构建树形结构并遍历执行操作,有效降低了类间的耦合度,为处理复杂层级关系提供了清晰的解决方案。
组合模式案例背景与需求分析
本文通过具体实例详细解析JavaScript中的组合模式,旨在为读者提供可参考的实践方案。
首先,
使用一个例子来引入组合模式,需求为 (1)有一个学校有2个班(一班,二班) (2)每个班级分2个小组(一班一组,一班二组,二班一组,二班二组) (3)学校计算机教室有限,每一个小组分着来上课
基于上述需求,我们可以初步识别出涉及四个核心概念:学校、班级、小组以及学生。
基于独立类的传统实现方案
接下来,我们尝试通过程序模拟这四个类之间的关系:
首先是学校类的定义:
var school=function (name) {
this.name=name;
var classes=new Array();
this.addClasses=function (cla) {
classes.push(classe);
}
this.getClass=function () {
return classes;
}
}
其次是班级类的定义:
//班级类
var classes=function (name) {
this.name = name;
var groups = new Array();
this.addGroup = function (group) {
groups.push(group);
return this;
};
this.getGroups = function () {
return groups;
}
};
接着是小组类的定义:
//组
var group=function (name) {
this.name=name;
var students=new Array();
var addStudents=function (student) {
students.push(student);
return this;
}
this.geStudent=function () {
return students;
}
};
最后是学生类的定义:
//学生类
var student=function (name) {
this.name=name;
this.gotoClass=function () {
document.write(name+":我是学生,我要去上课 ")
};
this.finishClass=function () {
document.write(name+": 终于下课了");
}
};
随后,我们需要验证测试用例是否满足以下要求:
具体验证条件包括: (1)每个班级包含两个小组(如一班一组、一班二组、二班一组、二班二组) (2)受限于学校计算机教室容量,每个小组的学生需分批上课 (3)在实现逻辑上,我们采用逆向构建的方式,即从学生对象开始,依次关联到小组、班级,最后汇总到学校。
//学生实例
var astudent=new student("我是a同学");
var bstudent=new student("我是b同学");
var cstudent=new student("我是c同学");
var dstudent=new student("我是d同学");
var estudent=new student("我是e同学");
var fstudent=new student("我是f同学");
var gstudent=new student("我是g同学");
var hstudent=new student("我是h同学");
var istudent=new student("我是i同学");
//班级实例(1)
var class1=new classes("一班");
//组1
var oneOne=new group("一班一组");
//组中添加学生
oneOne.addStudents(astudent).addStudents(bstudent);
//组2
var oneTwo=new group("一班二组");
//组中添加学生
oneTwo.addStudents(cstudent).addStudents(dstudent);
class1.addGroup(oneOne).addGroup(oneTwo);
//班级实例2
var class2=new classes("二班");
//组1
var towOne=new group("二班一组");
//组中添加学生
towOne.addStudents(estudent).addStudents(fstudent);
//组2
var towTwo=new group("二班二组");
//组中添加学生
towTwo.addStudents(gstudent).addStudents(hstudent).addStudents(istudent);
//
class2.addGroup(towOne).addGroup(towTwo);
//学校实例
var usSchool=new school("组合模式学校");
最后,当开学时,我们需要按照既定规则安排学生上课:
具体安排为:由一班一组的学生前往教室,整个流程涉及学校、班级、小组到学生的层级传递。
var classes=usSchool.getClass();//班级
for(var i=0;i<classes.length;i++){
if(classes[i].name=="一班"){
for(var j=0;j<classes[i].getGroups().length;j++){
if(classes[i].classes[i].getGroups()[j]=="一组"){
var students=classes[i].classes[i].getGroups()[j].geStudent();
for(var k=0;k<students.length;k++){
students[k].gotoClass();
}
}
}
}
}
然而,如果仅仅为了安排一次上课就需要编写如此繁琐的代码,那么当学校拥有上千个班级时,这种开发方式将难以维护且效率极低。
组合模式的核心优势与改进思路
显然,这种硬编码的方式不适合业务的扩展,因此我们引入组合模式来解决上述问题。 为何要使用设计模式? 因为设计模式提供了以下关键机制: (1)将对象划分为两种类型:组合对象(Composite)和叶子对象(Leaf) (2)组合对象和叶子对象实现相同的操作接口 (3)对组合对象执行的操作可以递归传递至叶子节点执行 (4)这种机制有效弱化了类与类之间的耦合度 (5)其常用手法是将对象组合成树形结构,从而统一管理。
接下来,我们将介绍如何利用JavaScript组合模式改进上述引入的案例。
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。