typesciprt: Composite Pattern

发布时间 2023-10-08 06:28:43作者: ®Geovin Du Dream Park™

 

/**
 * Composite Pattern 组合是一种结构型设计模式, 你可以使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们。
 * https://refactoringguru.cn/design-patterns/composite/typescript/example#lang-features
 * The base Component class declares common operations for both simple and
 * complex objects of a composition.
 * 
 *
 */
abstract class DuComponent {
    protected parent!: DuComponent | null;

    /**
     * Optionally, the base Component can declare an interface for setting and
     * accessing a parent of the component in a tree structure. It can also
     * provide some default implementation for these methods.
     */
    public setParent(parent: DuComponent | null) {
        this.parent = parent;
    }
    /**
     * 
     */
    public getParent(): DuComponent | null {
        return this.parent;
    }

    /**
     * In some cases, it would be beneficial to define the child-management
     * operations right in the base Component class. This way, you won't need to
     * expose any concrete component classes to the client code, even during the
     * object tree assembly. The downside is that these methods will be empty
     * for the leaf-level components.
     */
    public add(component: DuComponent): void { }
    /**
     * 
     * @param component 
     */
    public remove(component: DuComponent): void { }

    /**
     * You can provide a method that lets the client code figure out whether a
     * component can bear children.
     */
    public isComposite(): boolean {
        return false;
    }

    /**
     * The base Component may implement some default behavior or leave it to
     * concrete classes (by declaring the method containing the behavior as
     * "abstract").
     */
    public abstract operation(): string;
}

/**
 * The Leaf class represents the end objects of a composition. A leaf can't have
 * any children.
 *
 * Usually, it's the Leaf objects that do the actual work, whereas Composite
 * objects only delegate to their sub-components.
 */
class Leaf extends DuComponent {
    public operation(): string {
        return 'Leaf';
    }
}

/**
 * The Composite class represents the complex components that may have children.
 * Usually, the Composite objects delegate the actual work to their children and
 * then "sum-up" the result.
 */
class Composite extends DuComponent {
    protected children: DuComponent[] = [];

    /**
     * A composite object can add or remove other components (both simple or
     * complex) to or from its child list.
     */
    public add(component: DuComponent): void {
        this.children.push(component);
        component.setParent(this);
    }
    /**
     * 
     * @param component 
     */
    public remove(component: DuComponent): void {
        const componentIndex = this.children.indexOf(component);
        this.children.splice(componentIndex, 1);

        component.setParent(null);
    }
    /**
     * 
     */
    public isComposite(): boolean {
        return true;
    }

    /**
     * The Composite executes its primary logic in a particular way. It
     * traverses recursively through all its children, collecting and summing
     * their results. Since the composite's children pass these calls to their
     * children and so forth, the whole object tree is traversed as a result.
     */
    public operation(): string {
        const results = [];
        for (const child of this.children) {
            results.push(child.operation());
        }

        return `Branch(${results.join('+')})`;
    }
}

/**
 * The client code works with all of the components via the base interface.
 */
function clientCodeCompostite(component: DuComponent) {
    // ...
    let str="";
    console.log(`RESULT: ${component.operation()}`);
    
    str=str+component.operation();
    return str;
    // ...
}

/**
 * This way the client code can support the simple leaf components...
 */
let strCom="";
const simple = new Leaf();
console.log('Client: I\'ve got a simple component:');

strCom=clientCodeCompostite(simple);

console.log('');

/**
 * ...as well as the complex composites.
 */
const tree = new Composite();
const branch1 = new Composite();
branch1.add(new Leaf());
branch1.add(new Leaf());
const branch2 = new Composite();
branch2.add(new Leaf());
tree.add(branch1);
tree.add(branch2);
console.log('Client: Now I\'ve got a composite tree:');
let strCom1=clientCodeCompostite(tree);
console.log('');

/**
 * Thanks to the fact that the child-management operations are declared in the
 * base Component class, the client code can work with any component, simple or
 * complex, without depending on their concrete classes.
 */
function clientCodeCompostite2(component1: DuComponent, component2: DuComponent) {
    // ...
    let str="";
    if (component1.isComposite()) {
        component1.add(component2);
    }
    console.log(`RESULT: ${component1.operation()}`);

    return str=component1.operation()+","+component2.operation();
    
}

console.log('Client: I don\'t need to check the components classes even when managing the tree:');
let strCom2=clientCodeCompostite2(tree, simple);

let messageComposite: string = 'Hello World,This is a typescript!,涂聚文 Geovin Du Web';
document.body.innerHTML = messageComposite+",one="+strCom+",two="+strCom1+",three="+strCom2+",TypeScript 组合模式"

  

调用:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <head><title>TypeScript:桥接模式</title>
      <meta name="Description" content="geovindu,涂聚文,Geovin Du"/>
<meta name="Keywords" content="geovindu,涂聚文,Geovin Du"/>
<meta name="author" content="geovindu,涂聚文,Geovin Du"/>  
    </head>
    <body>
        <script src="dist/Compositets.js"></script>
    </body>
</html>

  

 

输出: