我是设计模式的新手,这是我的问题
如果我们有一个抽象类,几乎没有实现它的类,并且每个类都有不同的属性.
现在我有另一个(Manager类),它包含一个抽象类的数组,我想在其中放入一个搜索方法...如何在不转换为具体类的情况下这样做?
我有2个想法:
第一个:添加额外级别的接口(即,而不是强制转换为具体类,我将转换为接口),这与代码接口而不是实现规则...但这样当我添加另一个类时,我将拥有为它创建一个接口,我还必须编辑管理器(客户端),这看起来不是很好.
第二个解决方案: 它看起来有点奇怪,仍然需要增强,但它的主要目标是让管理器或任何其他客户端使用抽象类,而不知道谁扩展它或它的属性.
solutin如下:每个添加的新项目都必须覆盖一个接口,强制它生成一个完整的字段描述,例如一个汽车对象必须返回一个具有下面的哈希映射
字段:{fieldType,fieldValue}
例
型号:{text,"ford"}
manifactureDate:{Date,"12/1/89"}
并且每个对象还将实现一个名为compareFields的方法,该方法采用这样的哈希映射并将其与其字段进行比较并返回true或false.
现在通过这种方式我已经解决了很多问题 - 对于gui我将只需要为这个hashmap创建一个渲染引擎,它可以显示任何项目而不必知道它的类型.(再次,gui是抽象类的另一个客户端)
- 对于搜索,我可以获得一个哈希映射,其中包含用户在搜索表单中输入的字段并循环抽象项并调用compare fieldmethod
我仍然不知道我将如何处理复杂的对象(有另一个对象作为其属性)
我不知道这是什么样的模式..这只是我想到的一个想法.
编辑:具体的例子
如果我有一个带有汽车和公共汽车的抽象项目类和实现它的船,并且每个类具有不同的属性......例如,管理者如何使用抽象类来搜索某个项目而不进行投射去汽车或公共汽车...真的很抱歉长期的问题
封装
封装的OO原则声明您反对不应将其状态暴露给外部.如果你的对象在内部信息上显示它打破了封装.根据OO设计,仍然可以将搜索标准传递给对象,并让它决定它们是否匹配.
interface IVehicle{ bool doesMatch( MapsearchCriterion ) }
您可以在所有车辆上安装一个交互器,并检索那些与打破封装相匹配的车辆.车辆的特定实施仍可根据需要重新实现.
游客
否则,我建议你看看访客模式.然后,想法是遍历所有对象,并有一个额外的类处理每种特定类型的处理.这也打破了纯封装(因为对象需要将其数据暴露给访问者),但它非常优雅.
class VehicleSearchVisitor { MapsearchCriterion; void visit( Car car ) {...} void visit( Bike bike ) { ... } .... }
元编程
自描述对象的概念是另一个概念,称为元编程.然后,表示层会反省其他对象以了解如何处理它们.传统上这被认为是一种先进的OO技术.您可以创建自定义注释来描述类的字段,以便表示层可以动态呈现相应的标签.例如,与hibernate注释一起使用相同的想法.元编程需要仔细完成,否则你会遇到其他问题.
Insteanceof
使用insteanceof
也是一种内省(因为你问对象的类)并且通常是气馁的.不是因为它本身是错误的,而是因为它往往被滥用.尽可能依赖传统的OO原则.用instanceof
滥用是一个代码味道.
总而言之,我建议使用访问者进行搜索,不要对表示层使用元编程,而是为每种类型的车辆创建一个简单的页面.
好的,所以你要扩展类而不是实现一个接口.如果您有Bus,Car,Truck,Train等类,并且它们都实现了IVehicle,它需要一个返回可排序/可搜索值的函数,您可以将它们全部作为类型IVehicle引用并在所有这些上调用该方法.
ActionScript 3代码:
package com.transportation.methods { public interface IVehicle { function getSpeed():Number; function getOtherSortableOrSearchableValue():*; } }
和
public class Car extends Sprite implements IVehicle
您需要在Car类中定义getSpeed()和getOtherSortableValue(),并且可以将其称为Car或IVehicle.由于我的示例中的所有传输模式都将实现IVehicle,只要您将它们作为IVehicle引用,就可以调用这两个函数.