Java 装饰图案的混乱

Java 装饰图案的混乱,java,design-patterns,Java,Design Patterns,我正在阅读Gof的装饰设计模式。我对以下几点感到困惑 它说图案的重要方面是让装饰师 出现在使用组件的任何位置。客户的不能 一般来说,区分装饰构件和装饰构件 未装饰组件?例如,如果我认为,我是客户 基本组件是有关电子邮件,但我希望它也安全。 有人像我一样为我提供功能 Email email = new SecuredEmail(new TextEmail()); 问:这只是一个假设。作为客户我难道不知道吗 那,这封短信邮件是装饰的吗?我只是糊涂了,有人能帮我吗 澄清这个疑问 装饰器及其组件不完

我正在阅读Gof的装饰设计模式。我对以下几点感到困惑

  • 它说图案的重要方面是让装饰师 出现在使用组件的任何位置。客户的不能 一般来说,区分装饰构件和装饰构件 未装饰组件?例如,如果我认为,我是客户 基本组件是有关电子邮件,但我希望它也安全。 有人像我一样为我提供功能

     Email email = new SecuredEmail(new TextEmail());
    
    问:这只是一个假设。作为客户我难道不知道吗 那,这封短信邮件是装饰的吗?我只是糊涂了,有人能帮我吗 澄清这个疑问

  • 装饰器及其组件不完全相同。装潢师充当 透明的外壳。但从对象标识的角度来看, 装饰构件与构件本身不同。 因此,在使用装饰器时,不应该依赖对象标识。 这是什么意思

  • 有人能解释一下这两部分吗


    Ben

    假设
    电子邮件是一个Java接口。实现
    Email
    的任何类都可以用来初始化变量
    Email
    ,包括任何decorator,因为decorator实现接口或扩展抽象类(实现接口)。当然,客户机可以知道类实例是什么,但他们通常不需要这样做。只需使用
    email.getClass()

    另一方面,装饰者与被装饰者不是同一个对象。它包裹装饰过的对象。因此,
    textmail
    SecuredEmail
    不是相同的对象。如果代码如下所示:

    TextEmail txtEmail = new TextEmail();
    SecuredEmail securedEmail = new SecuredEmail(txtEmail);
    
    然后检查他们的身份将得到下一个结果:

    System.out.println("identical: " + (txtEmail == securedEmail));
    
    i、 e

    可以编写
    equals(Object)
    ,这样它可以给出不同的结果,例如

    System.out.println("equal: " + txtEmail.equals(securedEmail));
    
    输出:

    equal: true
    

    假设
    电子邮件
    是一个Java接口。实现
    Email
    的任何类都可以用来初始化变量
    Email
    ,包括任何decorator,因为decorator实现接口或扩展抽象类(实现接口)。当然,客户机可以知道类实例是什么,但他们通常不需要这样做。只需使用
    email.getClass()

    另一方面,装饰者与被装饰者不是同一个对象。它包裹装饰过的对象。因此,
    textmail
    SecuredEmail
    不是相同的对象。如果代码如下所示:

    TextEmail txtEmail = new TextEmail();
    SecuredEmail securedEmail = new SecuredEmail(txtEmail);
    
    然后检查他们的身份将得到下一个结果:

    System.out.println("identical: " + (txtEmail == securedEmail));
    
    i、 e

    可以编写
    equals(Object)
    ,这样它可以给出不同的结果,例如

    System.out.println("equal: " + txtEmail.equals(securedEmail));
    
    输出:

    equal: true
    

    你不是客户。使用电子邮件的代码是客户端,它只知道对象是电子邮件。它不会知道这是一封用SecuredEmail装饰的文本电子邮件


    至于依赖对象标识,这意味着一段代码的工作原理应该是相同的,无论它是通过textmail传递的,还是用SecuredEmail包装的textmail。从技术角度讲,您不应该依赖于
    email1==email2
    ,因为email2可以是用SecureEmail修饰的email1。

    您不是客户。使用电子邮件的代码是客户端,它只知道对象是电子邮件。它不会知道这是一封用SecuredEmail装饰的文本电子邮件


    至于依赖对象标识,这意味着一段代码的工作原理应该是相同的,无论它是通过textmail传递的,还是用SecuredEmail包装的textmail。从技术意义上讲,您不应该依赖于
    email1==email2
    ,因为email2可以是用SecureEmail修饰的email1。

    Ad.1作为客户机,修饰类的用户,您无法确定使用什么实现

    我们需要假设
    Email
    是一个接口,并创建两种方法

    方法1

     public Email getMail() {
       reutrn TextEmai();
     }
    
    方法2

     public Email getMail() {
       reutrn SecureEmail();
     }
    
    作为API的用户,您将知道存在一个类,该类具有方法
    Email getMail()
    ,您无法根据它的说明确定将解析哪些类。可以是方法1或方法2。但作为一个二手货,你不能确定


    第二点,指的是对象相等。对于本例,
    textmail
    对象不等于
    SecureEmail
    。正如鲍里斯在他的回答和评论中所解释的那样。装饰器可以但不必以相同的方式实现equals方法。因此,当使用装饰图案时,您永远不应该信任或依赖于平等

    Ad.1作为客户机、修饰类用户,您无法确定使用什么实现

    我们需要假设
    Email
    是一个接口,并创建两种方法

    方法1

     public Email getMail() {
       reutrn TextEmai();
     }
    
    方法2

     public Email getMail() {
       reutrn SecureEmail();
     }
    
    作为API的用户,您将知道存在一个具有方法
    Email getMail()
    的类,您无法通过它的描述来确定将解析哪个类。可以是方法1或方法2。但作为一个二手货,你不能确定


    第二点,指的是对象相等。对于本例,
    textmail
    对象不等于
    SecureEmail
    。正如鲍里斯在他的回答和评论中所解释的那样。装饰器可以但不必以相同的方式实现equals方法。因此,当使用装饰图案时,您永远不应该信任或依赖于平等

    我知道你违反了第二条规定。我不认为文本电子邮件应该与安全电子邮件相等。谢谢@Vash-在这种情况下,没有理由让这两个对象相等。一般来说,这可能是一种情况。谢谢@Vash和Boris。简言之,这意味着,装饰器基本上是在扩展一个抽象类,该抽象类在inturn中实现或扩展组件接口,因此它们不能与identity相同?接受答案就可以了;-)@BorisPavlović会马上做的,如果我的理解是正确的,你能确认我评论中的部分吗