欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

結(jié)合ES6?編寫?JavaScript?設(shè)計(jì)模式中的結(jié)構(gòu)型模式

 更新時(shí)間:2022年07月29日 09:35:07   作者:??天行無(wú)忌???  
這篇文章主要介紹了結(jié)合ES6編寫JavaScript?設(shè)計(jì)模式中的結(jié)構(gòu)型模式,設(shè)計(jì)模式是軟件設(shè)計(jì)中常見(jiàn)問(wèn)題的解決方案,這些模式很容易重復(fù)使用并且富有表現(xiàn)力

前言

本文將對(duì) 20 多種 JavaScript 設(shè)計(jì)模式進(jìn)行簡(jiǎn)單概述,然后結(jié)合 ES6 類的方式來(lái)編寫實(shí)例代碼展示其使用方式。

JavaScript 在現(xiàn)代前端中扮演重要的角色,相比過(guò)去能夠做的事情已經(jīng)不在一個(gè)級(jí)別上了。JavaScript 最大的特征是其靈活性,一般只要敢想敢寫,可以把程序?qū)懙煤芎?jiǎn)單,有可以寫得很復(fù)雜。其靈活性導(dǎo)致編寫 JavaScript 的時(shí)候能夠不斷的優(yōu)化,能夠不斷質(zhì)疑寫的質(zhì)量。而設(shè)計(jì)模式,是不分編程語(yǔ)言的,是軟件工程的內(nèi)容,JavaScript 強(qiáng)大的表現(xiàn)力賦予了開(kāi)發(fā)者運(yùn)用設(shè)計(jì)模式編寫代碼時(shí)創(chuàng)造性。

設(shè)計(jì)模式系列文章:

什么是設(shè)計(jì)模式?

設(shè)計(jì)模式是軟件設(shè)計(jì)中常見(jiàn)問(wèn)題的解決方案,這些模式很容易重復(fù)使用并且富有表現(xiàn)力。

在軟件工程中,設(shè)計(jì)模式(design pattern)是對(duì)軟件設(shè)計(jì)中普遍存在(反復(fù)出現(xiàn))的各種問(wèn)題,所提出的解決方案。它并不直接用來(lái)完成代碼的編寫,而是描述在各種不同情況下,要怎么解決問(wèn)題的一種方案。面向?qū)ο笤O(shè)計(jì)模式通常以類別或?qū)ο髞?lái)描述其中的關(guān)系和相互作用,但不涉及用來(lái)完成應(yīng)用程序的特定類別或?qū)ο蟆?mdash;— 維基百科

在 JavaScript 中使用設(shè)計(jì)模式主要有以下原因:

  • 可維護(hù)性:設(shè)計(jì)模式有助于降低模塊間的耦合程度。
  • 溝通:設(shè)計(jì)模式為處理不同類型的對(duì)象提供了一套通用的術(shù)語(yǔ)。
  • 性能:對(duì)代碼起到優(yōu)化作用,提高程序的運(yùn)行速度。當(dāng)然不是所有的設(shè)計(jì)模式都能夠改善性能。

有三種模式:創(chuàng)建型模式,結(jié)構(gòu)型模式、行為型模式。

  • 創(chuàng)建型模式:解決與創(chuàng)建對(duì)象相關(guān)的問(wèn)題。
  • 結(jié)構(gòu)型模式:處理實(shí)體之間的關(guān)系,以及它們?nèi)绾喂餐M成一個(gè)更大的結(jié)構(gòu)。
  • 行為型模式:處理對(duì)象如何相互通信和交互。

結(jié)構(gòu)型設(shè)計(jì)模式

結(jié)構(gòu)型設(shè)計(jì)模式涉及類和對(duì)象組合,使用繼承來(lái)組合接口。

在軟件工程中,結(jié)構(gòu)設(shè)計(jì)模式是通過(guò)識(shí)別實(shí)現(xiàn)實(shí)體之間關(guān)系的簡(jiǎn)單方法來(lái)簡(jiǎn)化設(shè)計(jì)的設(shè)計(jì)模式。

  • 適配器模式
  • 橋接模式
  • 組合模式
  • 裝飾者模式
  • 門面模式
  • 享元模式
  • 代理模式

適配器模式

適配器模式允許具有不兼容接口的類通過(guò)將它們自己的接口封裝在現(xiàn)有類周圍來(lái)一起工作。適配器也稱為包裝器(wrapper),用來(lái)把不匹配的接口替換為一個(gè)可用于現(xiàn)有系統(tǒng)中的接口。

在軟件工程中,適配器模式是一種軟件設(shè)計(jì)模式,它允許將現(xiàn)有類的接口用作另一個(gè)接口。它通常用于使現(xiàn)有類在不修改其源代碼的情況下與其他類一起使用。 

實(shí)例

實(shí)例將通過(guò)一個(gè)計(jì)算器的例子進(jìn)行改造。 Calculator1 是舊接口,Calculator2 是新接口。將構(gòu)建一個(gè)適配器,它將包裝新接口并使用其新方法為其提供結(jié)果。

class Calculator1 {
    constructor() {
        this.operations = function (value1, value2, operation) {
            const operationHandler = {
                add: () => value1 + value2,
                sub: () => value1 - value2,
            };
            return (
                typeof (operationHandler[operation] === "function") &&
                operationHandler[operation]()
            );
        };
    }
}
class Calculator2 {
    constructor() {
        this.add = function (value1, value2) {
            return value1 + value2;
        };
        this.sub = function (value1, value2) {
            return value1 - value2;
        };
    }
}
// 使用適配器模式構(gòu)建類
class CalcAdapter {
    constructor() {
        const cal2 = new Calculator2();
        this.operations = function (value1, value2, operation) {
            return (
                typeof (cal2[operation] === "function") &&
                cal2[operation](value1, value2)
            );
        };
    }
}
const adaptedCalc = new CalcAdapter();
console.log(adaptedCalc.operations(30, 25, "sub")); // 5

橋接模式

橋接模式將抽象與實(shí)現(xiàn)分開(kāi),以便兩者可以獨(dú)立變化。是一種既能把兩個(gè)對(duì)象連接在一起,又能避免二者間的強(qiáng)耦合的方法。

橋接模式是一種結(jié)構(gòu)化設(shè)計(jì)模式,它允許將一個(gè)大類或一組密切相關(guān)的類拆分為兩個(gè)獨(dú)立的層次結(jié)構(gòu):抽象和實(shí)現(xiàn),它們可以相互獨(dú)立地開(kāi)發(fā)。—— 維基百科

實(shí)例

將創(chuàng)建渲染器類來(lái)渲染多個(gè)形狀。

class VectorRenderer {
    renderCircle(radius) {
        console.log(`渲染一個(gè)半徑為 ${radius} 的圓`);
    }
}
class RasterRenderer {
    renderCircle(radius) {
        console.log(`繪制一個(gè)半徑為 ${radius} 的像素圓`);
    }
}
class Shape {
    constructor(renderer) {
        this.renderer = renderer;
    }
}
class Circle extends Shape {
    constructor(renderer, radius) {
        super(renderer);
        this.radius = radius;
    }

    draw() {
        this.renderer.renderCircle(this.radius);
    }
    resize(factor) {
        this.radius *= factor;
    }
}
const raster = new RasterRenderer();
const vector = new VectorRenderer();
const circle = new Circle(vector, 5);
const rasterCircle = new Circle(raster, 5);
circle.draw();
circle.resize(2);
circle.draw();
rasterCircle.draw();
rasterCircle.resize(2);
rasterCircle.draw();

組合模式

組合模式組合對(duì)象,以便可以將它們作為單個(gè)對(duì)象進(jìn)行操作,非常適合用于創(chuàng)建WEB上的動(dòng)態(tài)用戶界面。

組合模式描述了一組對(duì)象,這些對(duì)象的處理方式與相同類型對(duì)象的單個(gè)實(shí)例相同。—— 維基百科

實(shí)例

將使用工作示例:

class Employer {
    constructor(name, role) {
        this.name = name;
        this.role = role;
    }
    print() {
        const { name } = this;
        console.log(`姓名:${name}`);
    }
}
class EmplyerGroup {
    constructor(name, composite = []) {
        console.log(name);
        this.name = name;
        this.composite = composite;
    }
    print() {
        console.log(this.name);
        this.composite.forEach((emp) => {
            emp.print();
        });
    }
}
const ravi = new Employer("ravi", "developer");
const bhavy = new Employer("bhavy", "developer");
const groupDevelopers = new EmplyerGroup("Developer", [ravi, bhavy]);
groupDevelopers.print();

裝飾者模式

裝飾者模式動(dòng)態(tài)地添加或覆蓋對(duì)象的行為,用于把對(duì)象透明的包裝到另一個(gè)種具有相同接口的對(duì)象中。

裝飾器模式是一種設(shè)計(jì)模式,它允許將行為動(dòng)態(tài)地添加到單個(gè)對(duì)象,而不會(huì)影響同一類中其他對(duì)象的行為。

實(shí)例

將以顏色和形狀為例,如果必須畫一個(gè)圓,將創(chuàng)建方法并畫一個(gè)圓。如果要畫一個(gè)紅色的圓圈,將行為被添加到一個(gè)對(duì)象中,裝飾器模式將幫助實(shí)現(xiàn)。

class Shape {
    constructor(color = "") {
        this.color = color;
    }
}
class Circle extends Shape {
    constructor(radius = 0) {
        super();
        this.radius = radius;
    }
    resize(factor) {
        this.radius *= factor;
    }
    toString() {
        return `一個(gè)直徑為 ${this.radius} 的園`;
    }
}
class ColoredShape extends Shape {
    constructor(shape, color) {
        super();
        this.shape = shape;
        this.color = color;
    }
    toString() {
        return `${this.shape.toString()},顏色為${this.color}`;
    }
}
const circle = new Circle(2);
console.log(circle); // Circle { color: '', radius: 2 }
const redCircle = new ColoredShape(circle, "紅色");
console.log(redCircle.toString()); // 一個(gè)直徑為 2 的園,顏色為紅色

門面模式

門面模式為復(fù)雜代碼提供了一個(gè)簡(jiǎn)化的接口,可以用來(lái)把現(xiàn)有接口轉(zhuǎn)換為一個(gè)更便于使用的接口。

門面模式是面向?qū)ο缶幊讨谐S玫囊环N軟件設(shè)計(jì)模式。與架構(gòu)中的外觀類似,外觀是一個(gè)對(duì)象,它充當(dāng)前端接口,掩蓋更復(fù)雜的底層或結(jié)構(gòu)代碼。 —— 維基百科

實(shí)例

舉一個(gè)客戶端與計(jì)算機(jī)交互的例子:

class CPU {
    freeze() {
        console.log("凍結(jié)…");
    }

    jump() {
        console.log("跳過(guò)…");
    }

    execute() {
        console.log("執(zhí)行…");
    }
}
class Memory {
    load(position, data) {
        console.log("加載中…");
    }
}
class HardDrive {
    read(lba, size) {
        console.log("讀取中…");
    }
}
class ComputerFacade {
    constructor() {
        this.processor = new CPU();
        this.ram = new Memory();
        this.hd = new HardDrive();
    }
    start() {
        this.processor.freeze();
        this.ram.load("", this.hd.read("lba", "size"));
        this.processor.jump("");
        this.processor.execute();
    }
}
const computer = new ComputerFacade();
computer.start();

享元模式

享元模式降低了創(chuàng)建類似對(duì)象的內(nèi)存成本,是一種可以用于優(yōu)化目的的設(shè)計(jì)模式。最適合用于解決因創(chuàng)建大量類似對(duì)象而累及性能的問(wèn)題。

享元是一種通過(guò)與其他類似對(duì)象共享盡可能多的數(shù)據(jù)來(lái)最小化內(nèi)存使用的對(duì)象。—— 維基百科

實(shí)例

以用戶為例,讓有多個(gè)同名的用戶,可以通過(guò)存儲(chǔ)一個(gè)名稱來(lái)節(jié)省內(nèi)存,并將其引用給具有相同名稱的用戶。

class User {
    constructor(fullname) {
        this.fullname = fullname;
    }
}
class User2 {
    constructor(fullname) {
        const getOrAdd = (s) => {
            const idx = User2.strings.indexOf(s);
            if (idx !== -1) {
                return idx;
            } else {
                User2.strings.push(s);
                return User2.strings.length - 1;
            }
        };
        this.names = fullname.split(" ").map(getOrAdd);
    }
}
User2.strings = [];
const getRadmon = (max) => Math.floor(Math.random() * Math.floor(max));
const randomString = () => {
    const result = [];
    for (let x = 0; x < 10; ++x) {
        result.push(String.fromCharCode(65 + getRadmon(26)));
    }
    return result.join("");
};

現(xiàn)在將通過(guò)創(chuàng)建 10k 個(gè)用戶來(lái)進(jìn)行不使用享元模式和使用享元模式的占用字符大小來(lái)類比內(nèi)存大小。

const users = [];
const users2 = [];
const firstnames = [];
const lastnames = [];
for (let i = 0; i < 100; ++i) {
    firstnames.push(randomString());
    lastnames.push(randomString());
}
for (const first of firstnames) {
    for (const last of lastnames) {
        users.push(new User(`${first} ${last}`));
        users2.push(new User2(`${first} ${last}`));
    }
}
console.log(`10k用戶占用了大約 ${JSON.stringify(users).length} 字符`); // 10k用戶占用了大約 370001 字符
const user2length = [users2, User2.strings]
    .map((x) => JSON.stringify(x).length)
    .reduce((x, y) => x + y);
console.log(`10k用戶在享元模式占用約 ${user2length} 字符`); // 10k用戶在享元模式占用約 191602 字符

代理模式

通過(guò)使用代理,一個(gè)類可以代表另一個(gè)類的功能。更加詳細(xì)的介紹,可以參閱《JavaScript 設(shè)計(jì)模式之代理模式

代理模式是一種軟件設(shè)計(jì)模式。代理,在其最一般的形式中,是一個(gè)作為與其他事物的接口的類。—— 維基百科

實(shí)例

以價(jià)值代理作為實(shí)例。

class Percentage {
    constructor(percent) {
        this.percent = percent;
    }
    toString() {
        return `${this.percent}%`;
    }
    valueOf() {
        return this.percent / 100;
    }
}
const fivePercent = new Percentage(5);
console.log(fivePercent.toString()); // 5%
console.log(`5% 的50倍是${50 * fivePercent}`); // 5% 的50倍是2.5

到此這篇關(guān)于結(jié)合ES6 編寫 JavaScript 設(shè)計(jì)模式中的結(jié)構(gòu)型模式的文章就介紹到這了,更多相關(guān)JS 結(jié)構(gòu)型模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論