0

我有一个应用程序,其中一部分包含一组循环中的 wpf 窗口,发送一个业务对象以对模型进行更改。像这样的东西(不是真正的代码):

class Window1 {

    BusinessObject obj;

    public Window1 (BusinessObject obj){
        this.obj = obj;
    }

    /*  Things showing obj info and modifying it. */

    public void on_Button_Next_Click(object sender, EventArgs args){
        new Window2(obj).Show();
       this.close();
    }
}

 class Window2 {

    BusinessObject obj;

    public Window2 (BusinessObject obj){
        this.obj = obj;
    }

    /*  Things showing obj info and modifying it. */

    public void on_Button_Next_Click(object sender, EventArgs args){
        new Window3(obj).Show();
       this.close();
    }
}

class Window3 {

    BusinessObject obj;

    public Window3 (BusinessObject obj){
        this.obj = obj;
    }

    /*  Things showing obj info and modifying it. */

    public void on_Button_Next_Click(object sender, EventArgs args){
        if (!obj.Finished) {
            new Window1(obj).Show();
            this.close();
        }
    }
}

有了新的变化,不再总是 W1 -> W2 -> W3 -> W1,取决于业务对象的信息,每次迭代有 4 种不同的路径:W1 -> W2 -> W3 -> W2 -> W1 ,或 W1 -> W2 -> W3 -> W1 -> W2 -> W1,所以我需要为每个窗口设置一个状态。

class Window1 {
    BusinessObject obj;

    public Window1 (BusinessObject obj, int path, int repetition){
        this.obj = obj;
    }

    /*  Things showing obj info and modifying it. */

    public void on_Button_Next_Click(object sender, EventArgs args){
        if (path == 0) {
           new Window2(obj).Show();
           this.close();
        }
        if (path == 1 && repetition = 0){
            new Window2(obj, path, 0).Show();
            this.close();
        }
        else {
            new Window3(obj, path, 1).Show();
            this.close();
        }
    }
}

是否可以使用窗口管理器来控制窗口而不是这样做?像这样

while (true) {
    new Window1(obj).Show();
    wait(Window1);
    new Window2(obj).Show();
    wait(Window2); 
     if (obj.Condition1){
        new Window3(obj).Show();
    } else {
        new Window1(obj).Show();
         wait(Window1);
         new Window3(obj).Show();
    }
}

如果可能的话,会是一个不好的做法吗?

4

1 回答 1

0

尽管我不太清楚您要实现的目标实际上是否有意义,但这里有一个可能的解决方案(假设您可以配置所需的规则)。

首先,我们有一个可配置的“StateMachine”,您可以在其中将业务对象的状态耦合到应该创建的下一个窗口。

public class StateMachine
{
    private readonly List<Tuple<Predicate<MyBusinessObject>, Func<MyBusinessObject, StateMachine, Window>>> _matchList;
    public StateMachine()
    {
        _matchList = new List<Tuple<Predicate<MyBusinessObject>, Func<MyBusinessObject, StateMachine, Window>>>();
    }

    public void RegisterState(Predicate<MyBusinessObject> predicate, Func<MyBusinessObject, StateMachine, Window> windowFactory)
    {
        _matchList.Add(Tuple.Create(predicate, windowFactory));
    }
    public Window Next(MyBusinessObject currentState)
    {
        var entry = _matchList.Where(m => m.Item1(currentState)).FirstOrDefault();
        if (entry != null)
            return entry.Item2(currentState, this);
        return null;
    }
}

在创建窗口之前,在应用程序初始化时,创建状态机实例并配置规则:

    public StateMachine InitializeStateMachine()
    {
        var stateMachine = new StateMachine();
        // If condition1 is true open Window2
        stateMachine.RegisterState(bo => bo.Condition1, (bo, sm) => new Window2(bo, sm));
        // If the sum is more than 12.5 and some value is not 42 open Window3
        stateMachine.RegisterState(bo => bo.SomeSum > 12.5 && bo.SomeValue != 42, (bo, sm) => new Window3(bo, sm));
        // The answer to life and everything will open Window4
        stateMachine.RegisterState(bo => bo.SomeValue == 42, (bo, sm) => new Window3(bo, sm));
        // More rules ...
        // If no other condition matches, open Window1
        stateMachine.RegisterState(bo => true, (bo, sm) => new Window1(bo, sm));
        return stateMachine;
    }

您的窗口类都需要实现一个构造函数,该构造函数采用业务对象实例和状态机实例。当需要打开一个新窗口时,他们只需要调用Next状态机。

public class Window1 : Window
{
    private readonly StateMachine _stateMachine;
    private readonly MyBusinessObject _businessObject;

    public Window1(MyBusinessObject businessObject, StateMachine stateMachine)
    {
        _stateMachine = stateMachine;
        _businessObject = businessObject;
    }

    public void on_Button_Next_Click(object sender, EventArgs args)
    {
        // look ma, no logic ...
        var nextWindow = _stateMachine.Next(_businessObject);
        if (nextWindow != null)
            nextWindow.Show();
        this.Close();
    }
}

如果逻辑更复杂,或者不仅仅取决于业务对象本身的状态,则需要进行一些调整以将这些考虑在内。

于 2013-08-20T22:45:32.840 回答