javascript设计模式笔记

JavaScript进阶:设计模式——组合模式

2022-01-27  本文已影响0人  听书先生
1、应用场景

在编写新闻模块时,我们通常会创建图片+文字的一条新闻,或者是icon图标+文字的新闻,也有可能是单纯的文字新闻,或者单纯的图片就是一条新闻链接,如果在数量很庞大的情况下,逐条的去组合创建,整个过程会非常臃肿以及代码繁琐,重复性高。

2、介绍组合模式

组合模式简单的就是不同的零件拼成一个汽车一样,整体就是对部分的组合,也就是一个繁化简的一个过程。

3、使用组合模式

创建虚拟父类News,因为每一个子类都会继承这个虚拟父类,所以这个虚拟父类不实现,只负责定义,因此可以创建两个特权变量,这两个特权变量是后面所有子类通过继承使用到的。

// 创建虚拟父类News
const News = function() {
    // 子元素容器数组
    this.children = [];
    // 当前元素
    this.element = null;
}

News.prototype = {
    // 子类重构
    init: function() { },
    add: function() { },
    getElement: function() { }
}

开始创建一个新闻模块的容器ul,用于存放所有的新闻,Object.create()使得新创建的对象Container保持指向News的原型对象。
init()是一个初始化操作,去创建一个ul的DOM元素
add()是一个插入操作,后面的子节点追加到当前创建的DOM树下


// 容器类构造
const Container = function(id, parent) {
    // 执行父类的构造函数
    News.call(this);
    this.id = id;
    this.parent = parent;
    this.init();
}

// 继承原型
Container.prototype = Object.create(News.prototype);

// 初始化操作:创建一个ul的dom元素
Container.prototype.init = function() {
    this.element = document.createElement('ul');
    this.element.id = this.id;
    this.element.className = 'news-container';
    console.log('init: ',this);
}
// 插入元素操作:插入一个子容器元素
Container.prototype.add = function(child) {
    this.children.push(child);
    this.element.appendChild(child.getElement());
    return this;
    console.log('add: ', this);
}
// 获取当前元素
Container.prototype.getElement = function() {
    return this.element;
}
// 显示方法
Container.prototype.show = function() {
    this.parent.appendChild(this.element);
}

开始创建新闻模块中的每一项新闻的容器li,用于存放这一组合的新闻
init()是一个初始化操作,去创建一个ul的DOM元素
add()是一个插入操作,后面的子节点追加到当前创建的DOM树下

// 每一个新闻条目
const Item = function(className) {
    News.call(this);
    this.className = className || '';
    this.init();
}

Item.prototype = Object.create(News.prototype);

// 子容器创建:初始化操作
Item.prototype.init = function() {
    this.element = document.createElement('li');
    this.element.className = this.className;
}

// 子容器中追加元素
Item.prototype.add = function(child) {
    this.children.push(child);
    this.element.appendChild(child.getElement());
    return this;
}

// 获取子容器的元素
Item.prototype.getElement = function() {
    return this.element;
}

创建新闻组合,主要将不同类型的新闻类型去包装,也就是类似点餐时的套餐,用一个袋子装起来。

// 新闻组的创建
const NewGroup = function(className) {
    News.call(this);
    this.className = className || '';
    this.init();
}

NewGroup.prototype = Object.create(Item.prototype);

NewGroup.prototype.init = function() {
    this.element = document.createElement('div');
    this.element.className = this.className;
}

NewGroup.prototype.add = function(child) {
    this.children.push(child);
    this.element.appendChild(child.getElement());
    return this;
}

NewGroup.prototype.getElement = function() {
    return this.element;
}

创建一个图片类型的新闻实体类,也就是相当于这个零件就是一个图片

// 创建一个图片类型的新闻实体类
const ImageNew = function(url, href, className) {
    News.call(this);
    this.url = url || '';
    this.href = href || '#';
    this.className = className || '';
    this.init();
}

ImageNew.prototype = Object.create(News.prototype);

ImageNew.prototype.init = function() {
    this.element = document.createElement('a');
    const img = new Image();
    img.src = this.url;
    img.style.width = 100 + 'px';
    img.style.height = 60 + 'px';
    this.element.appendChild(img);
    this.element.className = 'news-image ' + this.className;
    this.element.href = this.href;
}

ImageNew.prototype.add = function() {}

ImageNew.prototype.getElement = function() {
    return this.element;
}

创建一个文字类型的新闻实体类,也就是相当于这个零件就是一个text文字链接

// 创建一个文字类型的新闻实体类
const TextNew = function(message, href) {
    News.call(this);
    this.text = message || '';
    this.href = href;
    this.init();
}

TextNew.prototype = Object.create(News.prototype);

TextNew.prototype.init = function() {
    this.element = document.createElement('a');
    this.element.innerText = this.text;
    this.element.className = 'text';
    this.element.href = this.href;
}
TextNew.prototype.add = function() {}

TextNew.prototype.getElement = function() {
    return this.element;
}

开始使用组合模式去组合新闻项

const new1 = new Container('new', document.body);
console.log(new1)

new1.add(
    new Item('normal').add(
        new NewGroup('pic').add(
            new ImageNew('./img/188.jpg', '#', 'pic-img')
        ).add(
            new TextNew('测试一条新闻信息', '#')
        )
    )   
).show();
图1.png

这样在创建一些新闻条目非常多且大量重复性工作的时候,就可以单元化工作。将繁化简。

上一篇 下一篇

猜你喜欢

热点阅读