当前位置:  开发笔记 > 编程语言 > 正文

避免并行继承层次结构

如何解决《避免并行继承层次结构》经验,为你挑选了2个好方法。

我有两个并行的继承链:

Vehicle <- Car
        <- Truck <- etc.

VehicleXMLFormatter <- CarXMLFormatter
                    <- TruckXMLFormatter <- etc.

我的经验是,并行继承层次结构随着它们的增长而成为一种维护问题.

即不向toXML(), toSoap(), toYAML()我的主要类添加方法.

如何在不违反关注点分离概念的情况下避免并行继承层次结构?



1> Frederik Ghe..:

我正在考虑使用访客模式.

public class Car : Vehicle
{
   public void Accept( IVehicleFormatter v )
   {
       v.Visit (this);
   }
}

public class Truck : Vehicle
{
   public void Accept( IVehicleFormatter v )
   {
       v.Visit (this);
   }
}

public interface IVehicleFormatter
{
   public void Visit( Car c );
   public void Visit( Truck t );
}

public class VehicleXmlFormatter : IVehicleFormatter
{
}

public class VehicleSoapFormatter : IVehicleFormatter
{
}

这样,您就可以避免使用额外的继承树,并将格式化逻辑与Vehicle-classes分开.当然,当你创建一个新的车辆时,你将不得不向Formatter接口添加另一个方法(并在formatter接口的所有实现中实现这个新方法).
但是,我认为这比创建一个新的Vehicle类更好,并且对于你拥有的每个IVehicleFormatter,创建一个可以处理这种新型车辆的新类.


但这只能解决编译错误.它实际上并没有修复逻辑,并且可能被认为更糟,因为现在编译器不会告诉你你忘了实现某些东西.

2> Pete Kirkham..:

另一种方法是采用推模型而不是拉模型.通常你需要不同的格式化程序,因为你打破了封装,并有类似的东西:

class TruckXMLFormatter implements VehicleXMLFormatter {
   public void format (XMLStream xml, Vehicle vehicle) {
      Truck truck = (Truck)vehicle;

      xml.beginElement("truck", NS).
          attribute("name", truck.getName()).
          attribute("cost", truck.getCost()).
          endElement();
...

您将数据从特定类型提取到格式化程序中的位置.

相反,创建与格式无关的数据接收器并反转流,以便特定类型将数据推送到接收器

class Truck  implements Vehicle  {
   public DataSink inspect ( DataSink out ) {
      if ( out.begin("truck", this) ) {
          // begin returns boolean to let the sink ignore this object
          // allowing for cyclic graphs.
          out.property("name", name).
              property("cost", cost).
              end(this);
      }

      return out;
   }
...

这意味着您仍然已经封装了数据,而您只是将标记数据提供给接收器.然后,XML接收器可能会忽略数据的某些部分,可能会对其中的某些部分进行重新排序,并编写XML.它甚至可以在内部委托不同的汇策略.但是接收器不一定需要关心车辆的类型,只需要如何以某种格式表示数据.使用实体化的全局ID而不是内联字符串有助于降低计算成本(仅在编写ASN.1或其他严格格式时才有意义).

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有