0

将不同职责放在一起的代码。代码更短,看起来很容易使用。

// Base class.
class A
{
public:
    // Native responsibility.
    virtual void F();

    // Show it with graphics.
    virtual void ShowGraphics();

    // Show it with table.
    virtual void ShowTable();

    // IO
    virtual void Read();
    virtual void Write();
};

// A number of concrete classes derive from base class.
class B : public A
{
public:
    // Native responsibility.
    virtual void F();

    // Show with graphics.
    virtual void ShowGraphics();

    // Show with table.
    virtual void ShowTable();

    // IO
    virtual void Read();
    virtual void Write();

private:
    // Include attributes required for native responsibility. 
    // Include attributes required for showing with graphics. 
    // Include attributes required for IO. 
    // Include attributes required for showing with table. 
};

使用图形职责作为示例来分离职责的代码。代码要长得多。它真的值得吗?

class AGraphics;
class BGraphics;

class A
{
public:
    // Native responsibility.
    virtual void F();

    // Create AGraphics for showing with graphics.
    virtual AGraphics* CreateGraphics(); // ShowGraphics() becomes
                                         // CreateGraphics().Show().
                                         // For IO and showing table
                                         // do similarly.
                                         // Is this design okay???

    virtual ATable* CreateTable();                                             
    virtual AIo* CreateIo();                                             
};
// for the above code, does a follow singe responsibility principle?

class B : public A
{
public:
    // Native responsibility.
    virtual void F();

    // Create AGraphics for showing with graphics.
    virtual BGraphics* CreateGraphics();
    virtual BTable* CreateTable();                                             
    virtual BIo* CreateIo();                                             

private:
    // Include attributes required for native responsibility.
};

class AGrahics
{
public:
    // Show with graphics.
    virtual void ShowGraphics();
};

class BGrahics : public AGrahics
{
public:
    // Show with graphics.
    virtual void Show();

public:
    B* b; // need B's data attributes.
    // Include attributes required for showing with graphics. 
};
4

2 回答 2

1

1) 取决于实施。如果实现简单且易于理解,那么您可能希望将其放在一个类中以降低复杂性。但是,如果实现很大且复杂,那么您可能希望将其分成不同的类以降低复杂性。
2) 取决于使用情况。尝试编写单元测试并相应地重构接口。单独测试各种功能应该很容易。如果它易于测试,则易于重用。

于 2013-02-05T02:41:51.487 回答
1

Gamma 等人的优秀“设计模式”一书谈到了将可能更频繁更改的事物与不太可能改变的事物隔离开来。一般来说,代表事物(图形、表格)的方式的代码会比事物本身的代码更频繁地变化。

因此,将关注点划分为不同类的麻烦的一个原因是,您最终会得到较小的类,每个类都做好一件事。稍后,如果您决定为表格输出的外观添加一个特性,例如,您不必费力地阅读所有有关 IO 和图形的代码。(如果类是分开的)使用包含似乎是一项额外的工作,但它的另一个好处是有助于澄清你对问题的思考——它避免了当你不小心在一部分中使用类变量时出现的讨厌的问题影响另一部分行为的代码。

于 2013-02-05T03:21:00.493 回答