java获取装饰器对象的所有类型:包装对象的类型和包装对象的类型
这是我的设计AccessDecorator
类有一个对另一个Access
的引用,就像普通的装饰器模式一样
但问题是,当我创建一个AccessDecorator
包装一个ConcreteAccess
然后尝试查看访问是哪种类型时:
Access access = new InAllowedAccess();
Access wrapperAccess = new MismatchAccess(access);
if (wrapperAccess instanceof InAllowedAccess) //this condition could be used to be a predicate for a filtering over an access list for example
//do something
当然,这不会起作用,因为wrapperAccess
不是InAllowedAccess
类型,但我真正想知道的是一些Access
的所有类型在这种情况下,wrapperAccess
不仅是类型MismatchAccess
,而且也是类型InAllowedAccess
我曾想过在Access
类中实现isInstanceofInAllowed()
、isInstanceofOutAllowed()
、isInstanceofInDenied()
和isinstanceofOutDenied()
、isinstanceofMismatch()
等方法,但这似乎不是一个好的解决方案,我不知道
否则,我应该为每4种类型InAllowedMismatchAccess
、OutAllowedMismatchAccess
、InDeniedMismatchAccess
和OutDeniedMismatchAccess
创建一个大的层次结构树吗?然后,当我开发另一个装饰师时
还是有其他更好的设计
我如何知道Access
的所有类型?不仅是包装访问的类型,而且是包装访问的类型强>
编辑:
我的需求之一是:按类型过滤Access
个集合-ÌnAllowedAccess
、InDeniedAccess
、OutAllowedAccess
、OutDeniedAccess
、MismatchAccess
(这是一个装饰器)和我可能开发的其他类型的装饰器
# 1 楼答案
避免类型检查通常是最好的方法。不幸的是,您没有给出足够的上下文来说明如何使用类,所以我可以举一个例子说明如何使用多态性并避免它
添加类型检查将限制系统的增长能力,因为随着新类的添加,这些类型需要包含在类型检查中。有时这可能会导致错误,因为代码可能会假设类的数量或类型。下面是一个例子:
注:我只是为了说明而编造的。这并不是说你必须表达自己的逻辑或诸如此类的东西
当我们启动系统时,有两个类继承自
Access
。假设我们向系统中添加另一个Access class
。此代码将在else上崩溃,因为我们可能会通过新的第三个访问类型,而强制转换将不会成功当然,情况并非总是如此。有时候,你的课程数量不会增长太多。你有可能预测出所有可能发生的类型
当然,由于所有事情都可能发生在编程中,有时你确实需要知道你正在使用的对象的类型
假设您的系统确实需要知道对象的类型。以下是两种解决方案:
public enum AccessType { InAccessAllowed, InAccessDenied, OutAccessDenied, // other types }
这样,您将使用
enum AccessType
而不是类型转换不是使用类,而是为每种类型的
Access
定义一个接口。然后,您将检查接口,而不是类。通过这种方式,装饰器可以实现与其装饰的类相同的接口我只是不想给出一个替代实现的例子。由于您的描述中缺少上下文,我将尝试猜测您将如何使用您的类并向它们添加行为。这只是一个想法而已
假设您的系统授予用户访问权限。用户可以被授予进出权限,系统的某些部分需要询问特定用户是否被授予或拒绝访问权限,以便它可以执行特定的逻辑
如果你没有任何与
Access classes
相关的行为,你可以把它作为一个描述符来使用,它将携带其他类完成工作所需的信息如果你确实有行为,那么你可以使用多态性。在
Access interface
中定义行为,并让推动此接口的类定义行为假设我们有一个消息系统,用户可以接收(输入)和发送(输出)消息。这些信息通过一个渠道传递。这些通道将接受或拒绝消息。下面是一种使用多态性而不是类型检查的方法
正如你所看到的,每个
MessageCahnnel
都有与之相关的行为。如果允许或不允许,它可以发送或接收消息。这样,其他使用MessageChannel
的类就不必进行类型转换# 2 楼答案
你说得对。这是个糟糕的解决方案。接口通常属于软件中具有高度抽象的层,因此其方法列表应该是稳定的。如果你在
Access
接口中加入这样一堆方法,这个接口将非常不稳定,因为将来很可能会添加更多这样的方法解决问题的最简单方法是(仅一次)向
Access
接口添加一个名为core()
的新方法。每个decorator都只是通过返回wrapped/core对象来实现这个方法