2011-04-17 70 views
1

我经常遇到需要执行单个操作的情况,比如说“备份数据库”。在传统的结构化编程中,我只是简单地将其实现为一个函数,它将数据库连接和备份目录作为参数。执行单一操作的OO模式

在面向对象编程中,我觉得这个动作应该以某种方式封装在一个类中。现在我有threeoptions:

我可以用实例的方法实现它,直接传递参数的方法类似

class Backup { 
    public void DoBackup(DBConnection connection, string backupDir) { 
    // ... 
    } 
} 

我也可以传递参数给构造私有字段存储它们,如:

class Backup { 
    private DBConnection connection; 
    private string backupDir; 


    public Backup(DBConnection connection, string backupDir) { 
    this.connection = connection; 
    this.backupDir = backupDir; 
    } 

    public void DoBackup() { 
    // ... 
    } 
} 

而且我可以用一个静态方法(如第一个选项):

class Backup { 
    public static void DoBackup(DBConnection connection, string backupDir) { 
    // ... 
    } 
} 

最后一个选项(静态方法)是IMO与结构化方法直接等价的方法,第一种方法或多或少是命令模式所暗示的,但是具有一定的开销(对于调用方法来说,实现类也是如此)

我在实践中见过所有三种变体。

您认为这三种方法的优缺点是什么?

+0

最好是加上'备份(串备份位置)'到DBConnection的类,如果可能的话给出的语言(C#,您可以做到这一点,所以会红宝石) – alternative 2011-04-17 11:34:22

回答

1

当每个班级有多个命令时,优点和缺点就显现出来了。我不喜欢命令模式 - 每个类只有一个方法是愚蠢的。只需为数据库操作定义一个类或接口即可。

如果确实有多种方法,然后优点/的不同的方法缺点是:

实例方法 - 优点 - 你可以存储被跨越不同的命令共享的对象有关的信息,即,数据库连接信息。缺点:这种方法说明意味着在调用重复 - 特别是如果你允许不同类型的数据存储,数据库类型等

构造方法 - 优势 - 这是一个好主意,在连接信息传递给构造函数,或者将它们作为实例变量存储并设置它们,但是恕我直言,没有方法的命令模式只是愚蠢的。特定于方法的参数应传递给方法,而不传递给构造函数。

静态方法 - 优点 - 没有保留状态,所以非常简单明了 - 基本上只是一个过程调用。 Disadvanage - 即使您有多个使用相同连接信息的方法,或者如果使用静态变量来存储它,也不得不重复连接信息,那么您不能同时运行2个不同的Backup数据存储。

0

中产阶级很棒。单元测试辅助函数是很容易的。这将很容易添加public BOOL debug;,所以你可以输出调试信息到日志。

+0

'公共BOOL调试'不是一个好的方法,调试信息应该来自运行时加载的外部文件,然后在Logger类本身中,并且会自动处理。 – alternative 2011-04-17 11:36:16

1

第二种方法是最灵活的。您还应该执行​​并使用某种服务容器。

伪代码:

// Commands: 

interface Command { 
    public void execute(); 
} 

class CreateBackupCommand implements Command { 
    private DBConnection connection; 
    private string backupDir; 


    public CreateBackupCommand(DBConnection connection, string backupDir) { 
     this.connection = connection; 
     this.backupDir = backupDir; 
    } 

    public void execute() { 
     // ... 
    } 
} 

// Service container configuration: 

<service id="abc.command.create-backup" class="..."> 
    <constructor-arguments> 
     <argument type="service" id="database.connection" /> 
     <argument>/path/to/dir</argument> 
    </constructor-arguments> 
</service> 

// Final usage: 

String commandName = "create-backup"; 

Command command = serviceContainer.getService("abc.command." + commandName); 
command.execute();