Go和Java实现装饰器模式

Go和Java实现装饰器模式

我们通过人穿着打扮自己的实例来演示装饰器模式的用法。

1、装饰器模式

装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它

是作为现有的类的一个包装。

装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

  • 意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

  • 主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展

    功能的增多,子类会很膨胀。

  • 何时使用:在不想增加很多子类的情况下扩展类。

  • 如何解决:将具体功能职责划分,同时继承装饰者模式。

  • 关键代码:1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具

    体扩展类重写父类方法。

  • 应用实例:1、孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。 2、

    不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上

    之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。

  • 优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态

    扩展一个实现类的功能。

  • 缺点:多层装饰比较复杂。

  • 使用场景:1、扩展一个类的功能。 2、动态增加功能,动态撤销。

  • 注意事项:可代替继承。

  • 装饰器模式包含以下几个核心角色:

    抽象组件(Component):定义了原始对象和装饰器对象的公共接口或抽象类,可以是具体组件类的父类或

    接口。

    具体组件(Concrete Component):是被装饰的原始对象,它定义了需要添加新功能的对象。

    抽象装饰器(Decorator):继承自抽象组件,它包含了一个抽象组件对象,并定义了与抽象组件相同的接

    口,同时可以通过组合方式持有其他装饰器对象。

    具体装饰器(Concrete Decorator):实现了抽象装饰器的接口,负责向抽象组件添加新的功能。具体装饰

    器通常会在调用原始对象的方法之前或之后执行自己的操作。

  • 适用性:

    在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

    处理那些可以撤消的职责。

    当不能采用生成子类的方法进行扩充时。

装饰器模式通过嵌套包装多个装饰器对象,可以实现多层次的功能增强。每个具体装饰器类都可以选择性地增加新

的功能,同时保持对象接口的一致性。

2、Go实现装饰器模式

go 复制代码
package decorator

// ========== Person ==========
type Person interface {
	// 形象展示
	Show()
}
go 复制代码
package decorator

import "fmt"

// ========== 服饰类 ==========
type Finery struct {
}

func (finery *Finery) Show() {
	fmt.Println("穿着了如下衣服:")
}
go 复制代码
package decorator

// ========== FineryDecorator =========
type FineryDecorator interface {
	Decorate(Person)
}
go 复制代码
package decorator

import "fmt"

// ========== Tshirt =========
type Tshirt struct {
	person Person
}

func (tshirt *Tshirt) Decorate(person Person) {
	tshirt.person = person
}

func (tshirt *Tshirt) Show() {
	tshirt.person.Show()
	fmt.Println("大T恤")
}
go 复制代码
package decorator

import "fmt"

// ========== Trouser =========
type Trouser struct {
	person Person
}

func (trouser *Trouser) Decorate(person Person) {
	trouser.person = person
}

func (trouser *Trouser) Show() {
	trouser.person.Show()
	fmt.Println("阔腿裤")
}
go 复制代码
package decorator

import "fmt"

// ========== Shoe =========
type Shoe struct {
	person Person
}

func (shoe *Shoe) Decorate(person Person) {
	shoe.person = person
}

func (shoe *Shoe) Show() {
	shoe.person.Show()
	fmt.Println("运动鞋")
}
go 复制代码
package main

import . "proj/decorator"

func main() {
	person := &Finery{}
	tshirt := &Tshirt{}
	trouser := &Trouser{}
	shoe := Shoe{}

	tshirt.Decorate(person)
	trouser.Decorate(tshirt)
	shoe.Decorate(trouser)
	shoe.Show()
}
shell 复制代码
# 输出
穿着了如下衣服:
大T恤
阔腿裤
运动鞋

3、Java实现装饰器模式

java 复制代码
package com.decorator;

// ========== Person ==========
public interface Person {
    // 形象展示
    void show();
}
java 复制代码
package com.decorator;

// ========== 服饰类 ==========
public class Finery implements Person{
    @Override
    public void show() {
        System.out.println("穿着了如下衣服:");
    }
}
java 复制代码
package com.decorator;

// ========== FineryDecorator =========
public class FineryDecorator implements Person{

    protected Person person;

    public void decorator(Person person){
        this.person = person;
    }

    @Override
    public void show() {
        this.person.show();
    }
}
java 复制代码
package com.decorator;

// ========== Tshirt =========
public class Tshirt extends FineryDecorator{

    @Override
    public void show() {
        super.show();
        System.out.println("大T恤");
    }
}
java 复制代码
package com.decorator;

// ========== Trouser =========
public class Trouser extends FineryDecorator {

    @Override
    public void show() {
        super.show();
        System.out.println("阔腿裤");
    }

}
java 复制代码
package com.decorator;

// ========== Shoe =========
public class Shoe extends FineryDecorator{

    @Override
    public void show() {
        super.show();
        System.out.println("运动鞋");
    }
}
java 复制代码
package com.decorator;

public class Test {

    public static void main(String[] args) {
        Person person = new Finery();
        FineryDecorator fineryDecorator = new FineryDecorator();
        Tshirt tshirt = new Tshirt();
        Trouser trouser = new Trouser();
        Shoe shoe = new Shoe();
        fineryDecorator.decorator(person);
        tshirt.decorator(fineryDecorator);
        trouser.decorator(tshirt);
        shoe.decorator(trouser);
        shoe.show();
    }
}
shell 复制代码
# 输出
穿着了如下衣服:
大T恤
阔腿裤
运动鞋
相关推荐
李少兄20 分钟前
如何从远程Maven仓库下载JAR包并手动放置到本地仓库
java·maven·jar
CodeMartain21 分钟前
stream流的toMap
java·开发语言
ling1s31 分钟前
C#核心(18)面向对象多态vob
java·开发语言·c#
sin220134 分钟前
idea创建springBoot的五种方式
java·spring boot·intellij-idea
皓木.41 分钟前
苍穹外卖——准备工作
java·数据库·mybatis
愤怒的代码1 小时前
Spring Boot对访问密钥加密解密——RSA
java·spring boot·后端
美美的海顿1 小时前
springboot基于Java的校园导航微信小程序的设计与实现
java·数据库·spring boot·后端·spring·微信小程序·毕业设计
愤怒的代码1 小时前
Spring Boot中幂等性的应用
java·spring boot·后端
silver6871 小时前
JAVA8 Stream API 使用详解
java
武子康1 小时前
大数据-259 离线数仓 - Griffin架构 修改配置 pom.xml sparkProperties 编译启动
xml·java·大数据·hive·hadoop·架构