是否有解决方案允许在具有不同接口的几种相似类型上使用泛型来实现抽象层?
Is there a solution to allow implementation of an abstraction layer using generics over several similar types with different interfaces?
假设您有几种类型,每种类型代表一个字段集合。
每种类型的字段不同,但有些类型共享一些字段。
让我们考虑一下 IceCream 类型。所有 IceCream 类型都实现一个公共接口,该接口需要公开一个方法 getFlavor()。但是,每个 IceCream 类型还公开了其他几种方法。冰淇淋类型包括 Gelato、WaterIce、FrozenCustard、ChilledCream 和 Traditional
一些 IceCream 类型公开了获取制造商的方法,但其他 IceCream 类型没有制造商,因此不公开获取制造商的方法。
此外,IceCream 类型不会以相同的方式公开 getManufacturer() 方法 - 有些人将其称为 getManufacturer(),而其他人则将其称为 getMaker()、getChef() 或 getOwner()。此外,单个 IceCream 类型可能有多个单独的方法,每个方法 return 相同(或不同)的制造商。
给定一组 IceCream 类型,其中一些具有 return 制造商的方法(制造商将始终是相同的数据类型)如何抽象这些 IceCream 类型以便他们可以编写通用逻辑处理 IceCream 类型而不是复制用于分别检索每种 IceCream 类型的制造商的所有代码?
很遗憾,无法修改这些 classes。
这似乎需要某种枚举,其中包含类型 -> 字符串的映射,并且字符串用于反射性地解析 class 方法。是否有另一种通用方法来实现它?
如果您可以更改现有的 IceCream 类型,则可以引入一个新界面。
由于这是不可能的,下一个最佳选择是为每个 "fields" 设置专用的 class;就像 class ManufactorerRetriever
。对于该示例,此 class 知道不同的 IceCream 类型 - 以及如何检索不同类型的实际制造商。这使您至少可以将所有这些丑陋的 "instanceof" 调用包含在一个中心位置。
您可以在Java8的接口中设置默认实现,所以如果没有制造商则不需要实现它。或者您可以使用实现一些基本方法的基本抽象 class,它可以包含一些需要实现的基本接口实现。很难为这种抽象找到一个好的解决方案,因为未来一切都可能发生变化。
我建议你使用装饰器模式。对于每种类型的冰淇淋,您需要创建一个 IceCreamDecorator
。装饰器将实现两个接口,即 IIceCream
和 IIceCreamManufactor
,您将 icecream
作为内部 class 传递。 IIceCreamManufactor
有一种方法是 getManufactor
,因此这将封装内部 class 的 getMaker()
、getChef()
或 getOwner()
。这样您就不会更改现有代码,并且可以随意扩展装饰器。
假设您有几种类型,每种类型代表一个字段集合。 每种类型的字段不同,但有些类型共享一些字段。
让我们考虑一下 IceCream 类型。所有 IceCream 类型都实现一个公共接口,该接口需要公开一个方法 getFlavor()。但是,每个 IceCream 类型还公开了其他几种方法。冰淇淋类型包括 Gelato、WaterIce、FrozenCustard、ChilledCream 和 Traditional
一些 IceCream 类型公开了获取制造商的方法,但其他 IceCream 类型没有制造商,因此不公开获取制造商的方法。
此外,IceCream 类型不会以相同的方式公开 getManufacturer() 方法 - 有些人将其称为 getManufacturer(),而其他人则将其称为 getMaker()、getChef() 或 getOwner()。此外,单个 IceCream 类型可能有多个单独的方法,每个方法 return 相同(或不同)的制造商。
给定一组 IceCream 类型,其中一些具有 return 制造商的方法(制造商将始终是相同的数据类型)如何抽象这些 IceCream 类型以便他们可以编写通用逻辑处理 IceCream 类型而不是复制用于分别检索每种 IceCream 类型的制造商的所有代码?
很遗憾,无法修改这些 classes。
这似乎需要某种枚举,其中包含类型 -> 字符串的映射,并且字符串用于反射性地解析 class 方法。是否有另一种通用方法来实现它?
如果您可以更改现有的 IceCream 类型,则可以引入一个新界面。
由于这是不可能的,下一个最佳选择是为每个 "fields" 设置专用的 class;就像 class ManufactorerRetriever
。对于该示例,此 class 知道不同的 IceCream 类型 - 以及如何检索不同类型的实际制造商。这使您至少可以将所有这些丑陋的 "instanceof" 调用包含在一个中心位置。
您可以在Java8的接口中设置默认实现,所以如果没有制造商则不需要实现它。或者您可以使用实现一些基本方法的基本抽象 class,它可以包含一些需要实现的基本接口实现。很难为这种抽象找到一个好的解决方案,因为未来一切都可能发生变化。
我建议你使用装饰器模式。对于每种类型的冰淇淋,您需要创建一个 IceCreamDecorator
。装饰器将实现两个接口,即 IIceCream
和 IIceCreamManufactor
,您将 icecream
作为内部 class 传递。 IIceCreamManufactor
有一种方法是 getManufactor
,因此这将封装内部 class 的 getMaker()
、getChef()
或 getOwner()
。这样您就不会更改现有代码,并且可以随意扩展装饰器。