Closed. This question is opinion-based。它当前不接受答案。
                        
                    
                
            
        
            
        
                
                    
                
            
                
                    想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。
                
                    4年前关闭。
            
        

    

在我们的Delphi 2007应用程序中,我们使用了以下许多构造

FdmBasic:=TdmBasicData(FindOwnerClass(AOwner,TdmBasicData));


FindOwnerClass向上移动当前组件的Owner层次结构以查找特定的类(在示例TdmBasicData中)。结果对象存储在Field变量FdmBasic中。我们主要使用它来传递数据模块。

例:
生成报告时,将结果数据压缩并存储在通过数据模块TdmReportBaseData访问的表的Blob字段中。在我们应用程序的单独模块中,具有使用ReportBuilder以Paged形式显示来自报表数据的功能。该模块的主要代码(TdmRBReport)使用类TRBTempdatabase将压缩的Blob数据转换为Reportbuilder运行时reportdesigner中可用的不同表。
TdmRBReport可以访问TdmReportBaseData,以获取所有与报告相关的各种数据(报告类型,报告计算设置等)。 TRBTempDatabase是在TdmRBReport中构造的,但必须有权访问TdmReportBasedata。因此,现在可以使用上面的构造完成此操作:

constructor TRBTempDatabase.Create(aOwner: TComponent);
begin
  inherited Create(aOwner);

  FdmReportBaseData := TdmRBReport(FindOwnerClass(Owner, TdmRBReport)).dmReportBaseData;
end;{- .Create }


我的感觉是,这意味着TRBTempDatabase非常了解其所有者,并且我想知道这是某种代码味道还是反模式。

您对此有何想法?这是代码气味吗?如果是这样,还有什么更好的方法?

最佳答案

在这里介绍的描述中,我认为这是轻微的臭味。但是,似乎很容易修复。

我倾向于将dmReportBaseData对象传递到需要它的任何组件的构造函数中。这样可以使合同在编译时变得清晰,而不是像您当前在运行时那样强制执行。

从目前的情况来看,您执行的合同比需要的要强大。尽管TRBTempDatabase仅需要一个dmReportBaseData实例,但是它只能在可以从TdmRBReport报告对象获取该实例的情况下起作用。

进行此更改还将允许TRBTempDatabaseTdmRBReport离婚,并且仍然可以成功运行。正如@Lieven在评论中指出的那样,这可能会使测试更加容易。

07-26 09:36