1. 工作状态-函数版

A: 还在面向过程。
A: 这是起码的面向对象思维,至少应该有个工作类,你的写程序方法是类方法,而钟点,任务完成其实就是类的什么?
B: 对外属性?

2. 工作状态-分类版

class Program
{
    static void Main(string[] args)
    {
        //紧急项目
        Work emergencyProjects = new Work();
        emergencyProjects.Hour = 9;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 10;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 12;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 13;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 14;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 17;

        //emergencyProjects.WorkFinished = true;
        emergencyProjects.TaskFinished = false;

        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 19;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 22;
        emergencyProjects.WriteProgram();

        Console.Read();
    }
}

//工作
public class Work
{
    //钟点
    private int hour;
    public int Hour
    {
        get { return hour; }
        set { hour = value; }
    }

    //任务完成
    private bool finish = false;
    public bool TaskFinished
    {
        get { return finish; }
        set { finish = value; }
    }


    public void WriteProgram()
    {
        if (hour < 12)
        {
            Console.WriteLine("当前时间:{0}点 上午工作,精神百倍", hour);
        }
        else if (hour < 13)
        {
            Console.WriteLine("当前时间:{0}点 饿了,午饭;犯困,午休。", hour);
        }
        else if (hour < 17)
        {
            Console.WriteLine("当前时间:{0}点 下午状态还不错,继续努力", hour);
        }
        else
        {
            if (finish)
            {
                Console.WriteLine("当前时间:{0}点 下班回家了", hour);
            }
            else
            {
                if (hour < 21)
                {
                    Console.WriteLine("当前时间:{0}点 加班哦,疲累之极", hour);
                }
                else
                {
                    Console.WriteLine("当前时间:{0}点 不行了,睡着了。", hour);
                }
            }
        }
    }
}

3. 方法过程是坏味道

B: 面向对象设计其实就是希望做到代码的职责分解。这个类违背了'单一职责原则'。
A: 这里有太多的判断,使得任何需求的改动或增加,都需要去更改这个方法。但是真正改动的地方只涉及17点到22点的状态,但是目前的代码却是对整个方法做改动,维护出错的风险很大。
B: 违背了开放-封闭原则。
A: 把这些分支想办法变成一个又一个的类,增加时不会影响其他类。然后状态的变化在各自的类中完成。

4. 状态模式

当一个对象的内部状态改变时允许改变其行为,这个对象看起来像是改变了其类。

A: 状态模式主要解决的是当控制一个对象状态转化的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类单中,可以把复杂的判断逻辑简化。如果判断很简单,当然没必要这样做。
图1

class Program
{
    static void Main(string[] args)
    {
        Context c = new Context(new ConcreteStateA());

        c.Request();
        c.Request();
        c.Request();
        c.Request();

        Console.Read();
    }
}

class Context
{
    private State state;

    public Context(State state)
    {
        this.state = state;
    }

    public State State
    {
        get
        {
            return state;
        }
        set
        {
            state = value;
            Console.WriteLine("当前状态:" + state.GetType().Name);
        }
    }

    public void Request()
    {
        state.Handle(this);
    }
}

abstract class State
{
    public abstract void Handle(Context context);
}

class ConcreteStateA : State
{
    public override void Handle(Context context)
    {
        context.State = new ConcreteStateB();
    }
}

class ConcreteStateB : State
{
    public override void Handle(Context context)
    {
        context.State = new ConcreteStateA();
    }
}

5. 状态模式的好处与用处

A: 将特定状态相关的行为局部化,并且将不同状态的行为分割开来。
B: 是不是将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所有通过定义新的子类可以很容易地增加新的状态和转换。
A: 目的是为了消除庞大的条件分支,大的分支判断会使得它们难以修改和扩展。状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
A: 当一个对象的行为取决以它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。多个状态,且状态的变化都是依靠大量的分支判断语句来实现,此时应该考虑将每一种业务状态定义为一个State的子类。这样这些对象就可以不依赖其他对象而独立变化。某一天客户需要更改需求,增加或减少业务状态或改变状态流程,对你来说都不是困难的事。

6. 工作状态-状态模式版

图1

class Program
{
    static void Main(string[] args)
    {
        //紧急项目
        Work emergencyProjects = new Work();
        emergencyProjects.Hour = 9;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 10;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 12;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 13;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 14;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 17;

        //emergencyProjects.WorkFinished = true;
        emergencyProjects.TaskFinished = false;

        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 19;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 22;
        emergencyProjects.WriteProgram();


        Console.Read();
    }
}


//抽象状态
public abstract class State
{
    public abstract void WriteProgram(Work w);
}

//上午工作状态
public class ForenoonState : State
{
    public override void WriteProgram(Work w)
    {
        if (w.Hour < 12)
        {
            Console.WriteLine("当前时间:{0}点 上午工作,精神百倍", w.Hour);
        }
        else
        {
            w.SetState(new NoonState());
            w.WriteProgram();
        }
    }
}

//中午工作状态
public class NoonState : State
{
    public override void WriteProgram(Work w)
    {
        if (w.Hour < 13)
        {
            Console.WriteLine("当前时间:{0}点 饿了,午饭;犯困,午休。", w.Hour);
        }
        else
        {
            w.SetState(new AfternoonState());
            w.WriteProgram();
        }
    }
}

//下午工作状态
public class AfternoonState : State
{
    public override void WriteProgram(Work w)
    {
        if (w.Hour < 17)
        {
            Console.WriteLine("当前时间:{0}点 下午状态还不错,继续努力", w.Hour);
        }
        else
        {
            w.SetState(new EveningState());
            w.WriteProgram();
        }
    }
}

//晚间工作状态
public class EveningState : State
{
    public override void WriteProgram(Work w)
    {
        if (w.TaskFinished)
        {
            w.SetState(new RestState());
            w.WriteProgram();
        }
        else
        {
            if (w.Hour < 21)
            {
                Console.WriteLine("当前时间:{0}点 加班哦,疲累之极", w.Hour);
            }
            else
            {
                w.SetState(new SleepingState());
                w.WriteProgram();
            }
        }
    }
}

//睡眠状态
public class SleepingState : State
{
    public override void WriteProgram(Work w)
    {
        Console.WriteLine("当前时间:{0}点 不行了,睡着了。", w.Hour);
    }
}

//下班休息状态
public class RestState : State
{
    public override void WriteProgram(Work w)
    {
        Console.WriteLine("当前时间:{0}点 下班回家了", w.Hour);
    }
}

//工作
public class Work
{
    private State current;
    public Work()
    {
        current = new ForenoonState();
    }

    private double hour;
    public double Hour
    {
        get { return hour; }
        set { hour = value; }
    }

    private bool finish = false;
    public bool TaskFinished
    {
        get { return finish; }
        set { finish = value; }
    }


    public void SetState(State s)
    {
        current = s;
    }

    public void WriteProgram()
    {
        current.WriteProgram(this);
    }
}

B: 增加个强制下班状态,并改动一下傍晚工作状态类的判断就可了。而这是不影响其他状态的代码的。


yuanoung
10 声望1 粉丝

« 上一篇
抽象工厂模式
下一篇 »
适配器模式

引用和评论

0 条评论