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