首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >复合设计模式下的装饰设计模式

复合设计模式下的装饰设计模式
EN

Stack Overflow用户
提问于 2021-09-22 14:47:53
回答 2查看 652关注 0票数 3

我理解复合设计模式和装饰设计模式及其应用。我们能不能把它们放在一起用呢?这种情况下的类图会是什么样的呢?

我们是否会从组件继承装饰器(来自装饰器设计模式)、叶节点和复合(来自组合设计模式)?下面是我所指的装饰器模式:装饰图案的wiki链接和复合模式:复合维基链接

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-22 23:25:46

是的,装潢工模式通常与复合模式一起使用。以下是GoF所说的话:

装潢师常与复合词连用。当装饰器和复合器一起使用时,它们通常有一个公共的父类。因此,装饰师必须支持组件接口(.)

原因是复合模式的目标是让:

客户端以统一的方式处理单个对象和对象的组合()

将这两者结合起来,可以将特性和职责添加到复合和装饰器中,从而使用组合重于继承。主要的好处是:

  • 避免不太灵活的继承的缺点
  • 避免重复实现公共接口的缺点
  • 如果目标是添加共同的责任,则为复合和离开启用相同的装饰器。

其结果将是:

有趣的是,装饰图案在图形上看起来与合成相似,这可能会让人感到不安。GoF解释了这种感觉:

装饰器可以被看作是只包含一个组件的简并组合。然而,装饰师增加了额外的责任(.)

票数 2
EN

Stack Overflow用户

发布于 2021-09-22 15:14:27

装饰者在装饰单个对象的同时,委派其方法,从而修改其行为。考虑一个带有单个方法的接口TextString asString();是一个示例类,例如TrimmedTextUpperCaseTextLowerCaseText

复合是一个容器,包含零到n对象,只将行为委托给其子对象。

但是,可以将这些组合成一个名为组合装饰器的东西,与前面的示例相比,它将是ConcatenatedText

下面是一些代码,它证明复合类也可以充当装饰器,并且可以自己进行修饰:

代码语言:javascript
运行
复制
interface Text {
    String asString();

    // just a static helper to construct an instance of Text quickly
    static Text of(String text) {
        return () -> text;
    }
}
代码语言:javascript
运行
复制
// 1st decorator
@AllArgsConstructor
static class TrimmedText implements Text {
    Text text;

    @Override
    public String asString() {
        return text.asString().trim();
    }
}

// 2nd decorator
@AllArgsConstructor
static class UpperCaseText implements Text {
    Text text;

    @Override
    public String asString() {
        return text.asString().toUpperCase();
    }
}
代码语言:javascript
运行
复制
// composite decorator
@AllArgsConstructor
static class ConcatenatedText implements Text {
    List<Text> texts;

    public void add(String text) {
        texts.add(Text.of(text));
    }

    @Override
    public String asString() {
        return texts.stream().map(Text::asString).collect(Collectors.joining(", "));
    }
}
代码语言:javascript
运行
复制
@Test
void foo() {
    Text trimmedUpperCaseText = new TrimmedText(new UpperCaseText(Text.of(" a b c ")));
    assertThat(trimmedUpperCaseText.asString(), is("A B C"));

    ConcatenatedText concatenatedText = new ConcatenatedText(new ArrayList<>(List.of(
        new UpperCaseText(Text.of("    a    ")),
        new TrimmedText(Text.of("    b    ")))));

    concatenatedText.add("c");

    Text refinedText = new TrimmedText(concatenatedText);

    assertThat(refinedText.asString(), is("A    , b, c")
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69286561

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档