2010-08-10 18 views
2

我有一些操作...查看,編輯,簽出等。業務邏輯規定如果文檔已經簽出,所有視圖都會變成編輯。一個實例與新實例熱交換

有一個整潔的面向對象的方式做這樣的事情:

class Action 
{ 
public: 
    Document document; 
    virtual void execute(); 
}; 
class View, Edit, Checkout : public Action; 

View::execute() 
{ 
    if (document.isCheckedOut) 
    { 
    delete this; 
    this = new Edit; 
    this->execute(); 
    } 
    /* execute view */ 
} 

更新:你們覺得這是什麼:

class Action 
{ 
public: 
    static int type; 
    Document document; 
    virtual void execute(); 
    static Action* construct(int type, Document document) = 0; 
private: 
    Action(); 
}; 
class View, Edit: public Action; 

Action* View::construct(Document document) 
{ 
    if (document.isCheckedOut) 
    return new Edit(document); 
    return new View(document); 
} 

Action* Edit::construct(Document document) 
{ 
    return new Edit(document); 
} 

void onViewButton(Document document) 
{ 
    Action *action = View::construct(document); 
    action->execute(); 
    delete action; 
} 
+1

更好地陳述這個試圖解決的問題。 – 2010-08-10 22:05:39

+0

您可能需要檢查Proxy(http://www.mindspring.com/~mgrand/pattern_synopses.htm#Proxy),Interface,Delegate等一些衆所周知的模式;在嘗試做其他事情之前,滿足您的需求。 – Ismael 2010-08-10 22:08:05

+0

爲什麼不經過存儲所有'Actions'的位置,並用'Edit'替換所有'View'?或者其他的東西。很難弄清楚你在做什麼。 – GManNickG 2010-08-10 22:16:41

回答

1

有沒有辦法重新分配「這'這樣的指針。您可以使用智能指針實現通過添加一個間接層來做類似的事情。

class action_ptr 
{ 
    Action* m_Data; 
public: 
    action_ptr(Action* value) 
    { 
    m_Data = value; 
    } 

    Action* operator->() 
    { 
     if(m_Data->isView() && m_Data->isCheckedOut()) 
     { 
     delete m_Data; 
     m_Data = new Edit(); 
     } 
     return m_Data; 
    } 
}; 


// usage 
action_ptr pAction(new View()); 
pAction->DoViewStuff(); 
pAction->Checkout(); 
pAction->OtherStuff(); // If isCheckedOut returned true, this now magically operates on an Edit instead! 

這絕不是一個完整的實現,只是一個例子 - 存在內存泄漏和許多缺少的功能。

+0

將它看作Pimpl模式可能更有意義,在這種模式下,實現對象被響應某些條件而被換出,而不是稱之爲智能指針。但最終結果是相似的任何一種方式。 – TheUndeadFish 2010-08-10 22:18:20

+0

請使用'boost :: scoped_ptr '或'std :: unique_ptr '而不是單純的'Action *',這樣可以避免明顯的內存泄漏。 – 2010-08-11 08:58:44

0

我可能會解決這個戰略模式,其中的策略有一個轉換成員函數。沿着這些線的東西(省略了無趣的代碼部分):

struct action_strategy { 
    virtual ~action_strategy(); 

    virtual action_strategy *convert_strategy(document const &doc); 
    virtual void execute() = 0; 
}; 

class action { // Hur, hur :D 
public: 
    // construct with heap-allocated strategy 
    action(action_strategy *strategy); 

    void execute() { 
    strategy_.reset(strategy_->convert_strategy(doc_); 
    strategy_->execute(); 
    } 

private: 
    document doc_; 
    std::auto_ptr<action_strategy> strategy_; 
}; 

// Default: do nothing 
action_strategy *action_strategy::convert_strategy(document const &doc) { 
    return this; 
} 

class view : public action_strategy { 
    // overload as necessary 
    virtual action_strategy *convert_strategy(document const &doc); 
}; 

action_strategy *view::convert_strategy(document const &doc) { 
    if(doc.is_checked_out()) { 
    return new edit(); 
    } 

    return this; 
}