所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如:

1、肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的

2、组装的台式机同理,由主板,电源,内存条,显卡, 机箱,显示器,外设等组成的

把一个成型的产品组成部件,分成一个个独立的部件,这种方式可以做出很多灵活的产品,这就是组合模式的优势

比如:家用台式机电脑,要求配置比较低, 这个时候只需要主板+电源+内存条+机箱+显示器+外设就可以了,不需要配置独立显卡

鸡腿堡+鸡翅+紫薯+可乐可以配置出另外一种套餐。

而在我们的前端领域,经常要接触的就是排版,通过不同的html结构+css样式组合成不用绚丽多彩的网页,我们也可以通过组合模式来完成的,

有人可能要问,为什么要用js来生成,直接写html和css不是很省事吗?是的,但是用组合模式做成不同的套餐(模块),是不是可以非常快的生成出不同的模板呢? 大大提高网页编写的速度?

本文我们来实战一个最基本的列表新闻模块,看看怎么使用组合模式?先看下要做出来的效果:

这个是一个无序列表加一个a标签,非常简单的套餐(模块)

1、首先,我们定义父类,2个属性,3个方法

 /***************父类开始***********************/
var Layout = function () {
this.children = [];
this.element = null;
}
Layout.prototype = {
init: function () {
throw new Error('该方法需要重写');
},
add: function () {
throw new Error('该方法需要重写');
},
getElement: function () {
throw new Error('该方法需要重写');
}
}
/***************父类结束***********************/

this.element用来存储当前的元素,this.children用来存储当前元素下面的子元素

init方法:用来初始化元素的标签,属性,样式

add方法:把子节点添加在父节点下面

getElement: 获取当前的节点

2、这里我们需要用到寄生组合继承

 function object(o) {
var G = function () {
};
G.prototype = o;
return new G();
}
function inheritPrototype(subObj, superObj) {
var proObj = object(superObj.prototype); //复制父类superObj的原型对象
proObj.constructor = subObj; //constructor指向子类构造函数
subObj.prototype = proObj; //再把这个对象给子类的原型对象
}

3,由于这个新闻模块最外层是ul,所以我们要封装一个生成ul元素的容器类

 /***************列表容器类开始***********************/
var UlContainer = function (id, parent) {
Layout.call(this);
this.id = id;
this.parent = parent;
this.init();
}
inheritPrototype(UlContainer, Layout);
UlContainer.prototype.init = function () {
this.element = document.createElement("ul");
this.element.id = this.id;
this.element.className = 'news-list';
}
UlContainer.prototype.add = function (child) {
this.children.push(child);
this.element.appendChild(child.getElement());
return this;
}
UlContainer.prototype.getElement = function () {
return this.element;
}
UlContainer.prototype.show = function () {
this.parent.appendChild(this.element);
}
/***************列表容器类结束***********************/

采用寄生组合继承,把父类的方法重写,父类的属性通过子类的借用构造函数复制到子类实例上,新增了一个show方法,这个方法的目的就是,把最终的模板显示出来

4、生成li元素

 /***************列表项li开始***********************/
var LiTag = function (cName) {
Layout.call(this);
this.className = cName || '';
this.init();
}
inheritPrototype(LiTag, Layout);
LiTag.prototype.init = function () {
this.element = document.createElement("li");
this.element.className = this.className;
}
LiTag.prototype.add = function (child) {
this.children.push(child);
this.element.appendChild(child.getElement());
return this;
}
LiTag.prototype.getElement = function () {
return this.element;
}
/***************列表项li结束***********************/

5、生成图片与a标签组合的方式

 /***************图片新闻开始*******************/
var ImageMsg = function (url, href, cName) {
Layout.call(this);
this.url = url || '';
this.href = href || '#';
this.className = cName || 'default';
this.init();
}
inheritPrototype(ImageMsg, Layout);
ImageMsg.prototype.init = function () {
this.element = document.createElement("a");
var oImg = new Image();
oImg.src = this.url;
this.element.appendChild(oImg);
this.element.className = 'img-Layout ' + this.className;
this.element.href = this.href;
}
ImageMsg.prototype.add = function () {
}
ImageMsg.prototype.getElement = function () {
return this.element;
}
/***************图片新闻结束*******************/

6,生成单纯的a标签和内容这种组合

 /***************简单新闻开始*******************/
var ATag = function (text, href, cName) {
Layout.call(this);
this.href = href || '#';
this.className = cName || 'default';
this.text = text || '';
this.init();
}
inheritPrototype(ATag, Layout);
ATag.prototype.init = function () {
this.element = document.createElement("a");
this.element.href = this.href;
this.element.innerHTML = this.text;
}
ATag.prototype.add = function () {
}
ATag.prototype.getElement = function () {
return this.element;
}
/***************简单新闻结束*******************/

7,生成带分类的新闻标题

 /***************分类新闻开始*******************/
var TypeMsg = function (text, href, type, cName, pos) {
Layout.call(this);
this.text = text || '';
this.href = href || '#';
this.type = type || '';
this.pos = pos || 'left';
this.className = cName || '';
this.init();
}
inheritPrototype(TypeMsg, Layout);
TypeMsg.prototype.init = function () {
this.element = document.createElement("a");
if (this.pos === 'left') {
this.element.innerHTML = '[' + this.type + '] ' + this.text;
} else {
this.element.innerHTML = this.text + ' [' + this.type + ']';
}
this.element.href = this.href;
this.element.className = this.className;
}
TypeMsg.prototype.add = function () {
}
TypeMsg.prototype.getElement = function () {
return this.element;
}
/***************分类新闻结束*******************/

8、大功告成,开始调用生成最后的模块

 window.onload = function () {
var oUlContainer = new UlContainer('Layout', document.body);
oUlContainer.add(
new LiTag('default').add(
new TypeMsg('es6系列教程 - 新的类语法实战选项卡', 'http://www.cnblogs.com/ghostwu/p/7465066.html', 'js高手之路-ghostwu', 'default', 'left')
)
).add(
new LiTag('default').add(
new TypeMsg('设计模式系列课程-单例模式实现模态框', 'http://www.cnblogs.com/ghostwu/p/7460301.html', 'js高手之路-ghostwu', 'default', 'left')
)
).add(
new LiTag('default').add(
new TypeMsg('HTML标签解释成DOM节点', 'http://www.cnblogs.com/ghostwu/p/7455184.html', 'js高手之路-ghostwu', 'default', 'left')
)
).add(
new LiTag('default').add(
new TypeMsg('HTML标签解释成DOM节点', 'http://www.cnblogs.com/ghostwu/p/7455184.html', 'js高手之路-ghostwu', 'default', 'left')
)
).add(
new LiTag('default').add(
new ATag('构造函数的基本特性与优缺点', 'http://www.cnblogs.com/ghostwu/p/7434609.html', 'js高手之路-ghostwu' )
)
).show();
}

[js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表的更多相关文章

  1. [js高手之路]设计模式系列课程-委托模式实战微博发布功能

    在实际开发中,经常需要为Dom元素绑定事件,如果页面上有4个li元素,点击对应的li,弹出对应的li内容,怎么做呢?是不是很简单? 大多数人的做法都是:获取元素,绑定事件 <ul> < ...

  2. [js高手之路] 设计模式系列课程 - jQuery的extend插件机制

    这里在之前的文章[js高手之路] 设计模式系列课程 - jQuery的链式调用与灵活的构造函数基础上增加一个extend浅拷贝,可以为对象方便的扩展属性和方法, jquery的插件扩展机制,大致就是这 ...

  3. [js高手之路]设计模式系列课程-发布者,订阅者重构购物车

    发布者订阅者模式,是一种很常见的模式,比如: 一.买卖房子 生活中的买房,卖房,中介就构成了一个发布订阅者模式,买房的人,一般需要的是房源,价格,使用面积等信息,他充当了订阅者的角色 中介拿到卖主的房 ...

  4. [js高手之路] 设计模式系列课程 - jQuery的链式调用与灵活的构造函数

    一.我们从一个简单的构造函数+原型程序开始 var G = function(){}; G.prototype = { length : 5, size : function(){ return th ...

  5. [js高手之路]设计模式系列课程-单例模式实现模态框

    什么是单例呢? 单,就是一个的意思.例:就是实例化出来的对象,那合在一起就是保证一个构造函数只能new出一个实例,为什么要学习单例模式呢?或者说单例模式有哪些常见的应用场景.它的使用还是很广泛,比如: ...

  6. [js高手之路]设计模式系列课程-设计一个模块化扩展功能(define)和使用(use)库

    模块化的诞生标志着javascript开发进入工业时代,近几年随着es6, require js( sea js ), node js崛起,特别是es6和node js自带模块加载功能,给大型程序开发 ...

  7. [js高手之路] 设计模式系列课程 - DOM迭代器(2)

    如果你对jquery比较熟悉的话,应该用过 eq, first, last, get, prev, next, siblings等过滤器和方法.本文,我们就用迭代设计模式来封装实现,类似的功能 < ...

  8. [js高手之路] 设计模式系列课程 - 迭代器(1)

    迭代器是指通过一种形式依次遍历数组,对象,或者类数组结构中的每个元素. 常见的有jquery中的each方法, ES5自带的forEach方法. 下面我们就来自定义一个类似jquery或者ES5的迭代 ...

  9. [js高手之路] es6系列教程 - 迭代器与生成器详解

    什么是迭代器? 迭代器是一种特殊对象,这种对象具有以下特点: 1,所有对象都有一个next方法 2,每次调用next方法,都会返回一个对象,该对象包含两个属性,一个是value, 表示下一个将要返回的 ...

随机推荐

  1. python函数(2):函数进阶

    昨天说了函数的一些最基本的定义,今天我们继续研究函数.今天主要研究的是函数的命名空间.作用域.函数名的本质.闭包等等 预习: 1.写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的 ...

  2. oracle-plsql序列问题

    场景:用来汇总工作中数据库的异常问题! 1 问题 序列在会话中未定义 解决: 创建Sequence后直接查询它的当前值(CURRVAL)会出错,要先调用Sequence对象.NEXTVAL,才能查询当 ...

  3. ubuntu上安装nginx+mysql+php5-fpm(PHP5 - FastCGI Process Manager)

    题外话:由于近段时间测试环境ssh链路质量不大好,经常短线.故我把整个安装过程放到screen里去执行,以防止断线中断了安装过程.执行screen -S install,这样断线后,只要再执行scre ...

  4. Hibernate 中 简便proxool连接池配置

    资源&文档 请百度云盘下载:http://pan.baidu.com/s/1hsmVVBu     提取码y966

  5. 基于脚本的modelsim自动化仿真笔记

    这里记录一下基于脚本的modelsim自动化仿真的一些知识和模板,以后忘记了可以到这里查找.转载请标明出处:http://www.cnblogs.com/IClearner/ . 一.基本介绍 这里介 ...

  6. python--代码统计小程序

    有人说,大学生在校期间要码够10W行代码,也有人说,看的不是写代码的行数,而是修改代码的行数... 不管谁说,说的人都挺牛的 咳,首先给自己定个小目标吧,5W行代码!成天写代码,啥时候到5W呢?为了更 ...

  7. HAUT--1262--魔法宝石(暴力)

    1262: 魔法宝石 时间限制: 2 秒  内存限制: 64 MB提交: 525  解决: 157提交 状态 题目描述 小s想要创造n种魔法宝石.小s可以用ai的魔力值创造一棵第i种魔法宝石,或是使用 ...

  8. 初识matplotlib

    最好将配置项与代码分离,在代码之外用一个永久的文件设定matplotlib参数默认值 配置文件选择放在当前工作目录,包括以下配置项: P13

  9. Treap详解

    今天一天怼了平衡树.深深地被她的魅力折服了.我算是领略到了高级数据结构的美妙.oi太神奇了. 今天初识平衡树,选择了Treap. Treap又叫树堆,是一个二叉搜索树.我们知道,它的节点插入是随机的, ...

  10. 排座椅 2008 NOIP 普及组 第二题

    题目描述 上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情.不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的D对同学上课时会交头接耳.同学 ...