Mat*_*mov 0 oop design-patterns
说我有A级
class A
{
Z source;
}
Run Code Online (Sandbox Code Playgroud)
现在,上下文告诉我'Z'可以是不同类的实例(比如B和C),它们不在它们的继承树中共享任何公共类.
我想天真的方法是使"Z"的接口类,使B级和C实现它.
但是有些事情仍然没有说服我,因为每次使用A类实例时,我都需要知道'source'的类型.因此,所有完成的多个'ifs'制作'是instanceof'听起来不太好.也许在将来其他一些类实现Z,并且拥有这种类型的硬编码'ifs'肯定会破坏某些东西.
问题的存在是我无法通过向Z添加函数来解决问题,因为在每个实例类型的Z中完成的工作是不同的.
我希望有人可以给我和建议,也许是关于一些有用的设计模式.
谢谢
编辑:根据界面Z背后的类,当某个A的实例完全不同时,"某人"在某个地方所做的工作.这就是问题,执行"重要工作"的实体不是Z,是别人那个想知道谁是Z.
Edit2:也许一个具体的例子会有所帮助:
class Picture
{
Artist a;
}
interface Artist
{
}
class Human : Artist { }
class Robot : Artist {}
Run Code Online (Sandbox Code Playgroud)
现在某处我有一个实例Picture,
Picture p = getPicture();
// Now is the moment that depending if the type of `p.a` different jobs are done
// it doesn't matter any data or logic inside Human or Robot
Run Code Online (Sandbox Code Playgroud)
使用接口的目的是隐藏这些不同的实现; A应该只知道方法的意图或高级目的.
通过各执行所做的工作Z可能会有所不同,但用于调用的工作方法签名可以是相同的.类A可以只调用方法Z.foo(),并且根据Z的实现是否,B或者C将执行不同的代码.
您需要知道实际实现类型的唯一时间是您需要在两种不同类型上执行完全不相关的处理,并且它们不共享接口.但在那种情况下,为什么他们被同一个A级处理?现在,有情况下,这可能是有意义的,例如当B和C从XML模式生成的类,你不能修改他们-但是总的来说,它表明该设计能够得到改善.
现在更新了您添加了图片示例.我认为这证实了我的观点 - 虽然实施getPicture()方式不同,但目的和返回类型是相同的.在这两种情况下,艺术家都会返回一张图片.
如果调用者想要以相同的方式处理Robot创建的和人工创建的图片,那么他们使用Artist界面.他们不需要区分人类或机器人,因为他们只想要一张照片!创建图片的细节属于子类,调用者不应该看到这些细节.如果调用者精确地关注图片是如何创建的,那么调用者应该绘制它,而不是机器人或人类,并且设计将完全不同.
如果您的子类执行完全不相关的任务(这不是您的Artist示例所示!)那么您可能会使用非常模糊的接口,例如标准的Java Runnable ; 在这种情况下,调用者真的不知道该run()方法会做什么 - 它只知道如何运行它们Runnable.
链接
以下问题/文章提出了一些替代方案instanceof:
以下文章还给出了示例代码,使用了与您的类似的示例:
以下文章讨论了instanceof与其他方法(例如访客模式和非循环访问者)的权衡: