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恤
阔腿裤
运动鞋
相关推荐
mit6.82415 分钟前
[Agent可视化] 配置系统 | 实现AI模型切换 | 热重载机制 | fsnotify库(go)
开发语言·人工智能·golang
Chen-Edward1 小时前
有了Spring为什么还有要Spring Boot?
java·spring boot·spring
陈小桔2 小时前
idea中重新加载所有maven项目失败,但maven compile成功
java·maven
小学鸡!2 小时前
Spring Boot实现日志链路追踪
java·spring boot·后端
xiaogg36782 小时前
阿里云k8s1.33部署yaml和dockerfile配置文件
java·linux·kubernetes
逆光的July2 小时前
Hikari连接池
java
微风粼粼3 小时前
eclipse 导入javaweb项目,以及配置教程(傻瓜式教学)
java·ide·eclipse
番茄Salad3 小时前
Spring Boot临时解决循环依赖注入问题
java·spring boot·spring cloud
Yeats_Liao3 小时前
Go Web 编程快速入门 · 04 - 请求对象 Request:头、体与查询参数
前端·golang·iphone
天若有情6733 小时前
Spring MVC文件上传与下载全面详解:从原理到实战
java·spring·mvc·springmvc·javaee·multipart