2009-07-24 196 views
2

我有以下现有方案。什么是正确的设计方法?

我有一个Validator类包含验证传递给它的命令的validate(Command *)函数。

class Validator 
{ 
public: 
    validate(Command* cmd) 
    { 
     // common validation logic 
    } 

} 

我有三个类说WindowsExecute,SolarisExecute和AIXExecute。 SolarisExecute和AIXExecute中的成员函数execute()直接创建Validator对象,并在执行之前使用验证(Comman *)函数验证Command。

class SolarisExecute 
{ 
public: 
    execute(Command *cmd) 
    { 
     Validator v; 
     bool valid = v.validate(cmd); 

     // some processing depending on 'valid' 
    } 
} 

class AIXExecute 
{ 
public: 
    execute(Command *cmd) 
    { 
     Validator v; 
     bool valid = v.validate(cmd); 

     // some processing depending on 'valid' 
    } 
} 

WindowsExecute是完全不同的,并没有任何命令。相反,它需要验证一些字符串数据。为此,有一个名为WindowsValidator的独立类从Validator继承。 WindowsExecute :: execute()使用WindowsValidator而不是Validator。

class WindowsValidator : Validator 
{ 
public: 
    validate(const string &xmlData) 
    { 
     // specific validation logic 
    } 
} 

class WindowsExecute 
{ 
public: 
    execute(const string &data) 
    { 
     WindowsValidate v; 
     bool valid = v.validate(data); 

     // some processing depending on 'valid' 
    } 
} 

这是现有的代码。

现在我需要做一些特定的Solaris验证,因此不能使用Validator :: validate(Command *)。按照当前的设计,我需要创建一个名为SolarisValidator的新类,并拥有自己的validate(Command *)实现。

我对这种方法并不舒服。我认为的一些问题/评论:

  1. Validator类只能由AIXExecute使用。那么为什么有一个基类,如果没有什么共同的逻辑剩余的话?只需要三个类SolarisValidator,AIXValidator,WindowsValidator。

  2. Validator :: validate(Command *)不必要地被继承到WindowsValidate类中。注意WindowsValidate :: validate(string)和Validator :: validate(Command *)的签名是不同的。

  3. 如果我引入SolarisValidator :: validate(Command *),我应该使Validator :: validate(Command *)虚拟。这意味着我正在引入虚拟指针的开销,即使我没有使用任何动态多态。那么为什么不去上面的#1并创建三个单独的类?

什么将是此方案也将是未来扩展的最佳解决方案?我正在使用C++来实现。

在此先感谢。

-GP

回答

2

它看起来像你有一个命令的概念,即是否有效。根据您的平台,命令以不同的形式表示。

所以我想知道:为什么不用一个函数“isValid”创建一个ICommand接口,并让平台包装代码为该平台创建适当的ICommand对象。这将使您的“执行”调用免于创建验证器,从而使其与平台无关。

注意:这个平台包装子系统是使用工厂模式最好的设计。

0

这听起来很像你实际上没有任何共同的功能,甚至是你的各种... Validator类之间的通用接口。就我个人而言,如果出现真正的通用界面,我会删除共同的基类,并且只复活它。试图强迫一个没有明确目的或利益的共同基类只会导致无用的代码和/或维护成本,而没有任何好处。

此时,您可能希望删除... Validator类,并将该功能移入... Execute类的单独函数中。听起来好像验证与执行方法的实现紧密相关,这就是为什么你很难抽象出合适的验证接口。

试图去耦合固有紧密耦合的东西通常是无用的练习。另一方面,不应该允许本质上不紧密耦合的事物通过纯粹的糟糕设计而与实现紧密耦合。

相关问题