1. 加薪代码初步

B: 管理类里面的结构方法比较长,加上有太多的分支判断,这其实非常不好的设计。
A: 很好,因为你很难讲当中会不会增加其他的管理类别,比如项目经理,部门经理等等。这个类承担了太多的责任。
B: 类有太多的责任,这违背了单一职责原则,增加新的类,需要修改这个类,违背了开放-封闭原则。
A: 如何解决经理无权上报总监这样的功能?
B: 它们之间有一定的关联,把用户的请求传递,直到可以解决这个请求为止。

2. 责任链模式

是多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

A: 请求的客户端并不知道这当中的哪个对象最终处理这个请求,这样系统的更改可以在不影响客服端的情况下动态地重新组织和分配责任。
图1

class Program
{
    static void Main(string[] args)
    {
        Handler h1 = new ConcreteHandler1();
        Handler h2 = new ConcreteHandler2();
        Handler h3 = new ConcreteHandler3();
        h1.SetSuccessor(h2);
        h2.SetSuccessor(h3);

        int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };

        foreach (int request in requests)
        {
            h1.HandleRequest(request);
        }

        Console.Read();

    }
}

abstract class Handler
{
    protected Handler successor;

    public void SetSuccessor(Handler successor)
    {
        this.successor = successor;
    }

    public abstract void HandleRequest(int request);
}

class ConcreteHandler1 : Handler
{
    public override void HandleRequest(int request)
    {
        if (request >= 0 && request < 10)
        {
            Console.WriteLine("{0}  处理请求  {1}",
                this.GetType().Name, request);
        }
        else if (successor != null)
        {
            successor.HandleRequest(request);
        }
    }
}

class ConcreteHandler2 : Handler
{
    public override void HandleRequest(int request)
    {
        if (request >= 10 && request < 20)
        {
            Console.WriteLine("{0}  处理请求  {1}",
                this.GetType().Name, request);
        }
        else if (successor != null)
        {
            successor.HandleRequest(request);
        }
    }
}

class ConcreteHandler3 : Handler
{
    public override void HandleRequest(int request)
    {
        if (request >= 20 && request < 30)
        {
            Console.WriteLine("{0}  处理请求  {1}",
                this.GetType().Name, request);
        }
        else if (successor != null)
        {
            successor.HandleRequest(request);
        }
    }
}

3. 责任链的好处

A: 这当中最关键的是当客户提交一个请求是,请求是沿着链传递直至有一个ConcreteHandler对象负责处理它。
A: 这就使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结构是职责链可简化对象的互相连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。
B: 随时地增加或修改一个请求的结构。增强了给对象指派职责的灵活性。
A: 不过也要当心,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,这很糟糕。

4. 加薪代码重构

图2
注意客户端是如何编写的:

class Program
{
    static void Main(string[] args)
    {

        CommonManager jinli = new CommonManager("金利");
        Majordomo zongjian = new Majordomo("宗剑");
        GeneralManager zhongjingli = new GeneralManager("钟精励");
        jinli.SetSuperior(zongjian);
        zongjian.SetSuperior(zhongjingli);

        Request request = new Request();
        request.RequestType = "请假";
        request.RequestContent = "小菜请假";
        request.Number = 1;
        jinli.RequestApplications(request);

        Request request2 = new Request();
        request2.RequestType = "请假";
        request2.RequestContent = "小菜请假";
        request2.Number = 4;
        jinli.RequestApplications(request2);

        Request request3 = new Request();
        request3.RequestType = "加薪";
        request3.RequestContent = "小菜请求加薪";
        request3.Number = 500;
        jinli.RequestApplications(request3);

        Request request4 = new Request();
        request4.RequestType = "加薪";
        request4.RequestContent = "小菜请求加薪";
        request4.Number = 1000;
        jinli.RequestApplications(request4);

        Console.Read();

    }
}

//管理者
abstract class Manager
{
    protected string name;
    //管理者的上级
    protected Manager superior;

    public Manager(string name)
    {
        this.name = name;
    }

    //设置管理者的上级
    public void SetSuperior(Manager superior)
    {
        this.superior = superior;
    }

    //申请请求
    abstract public void RequestApplications(Request request);
}

//经理
class CommonManager : Manager
{
    public CommonManager(string name)
        : base(name)
    { }
    public override void RequestApplications(Request request)
    {

        if (request.RequestType == "请假" && request.Number <= 2)
        {
            Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
        }
        else
        {
            if (superior != null)
                superior.RequestApplications(request);
        }

    }
}

//总监
class Majordomo : Manager
{
    public Majordomo(string name)
        : base(name)
    { }
    public override void RequestApplications(Request request)
    {

        if (request.RequestType == "请假" && request.Number <= 5)
        {
            Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
        }
        else
        {
            if (superior != null)
                superior.RequestApplications(request);
        }

    }
}

//总经理
class GeneralManager : Manager
{
    public GeneralManager(string name)
        : base(name)
    { }
    public override void RequestApplications(Request request)
    {

        if (request.RequestType == "请假")
        {
            Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
        }
        else if (request.RequestType == "加薪" && request.Number <= 500)
        {
            Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
        }
        else if (request.RequestType == "加薪" && request.Number > 500)
        {
            Console.WriteLine("{0}:{1} 数量{2} 再说吧", name, request.RequestContent, request.Number);
        }
    }
}

//申请
class Request
{
    //申请类别
    private string requestType;
    public string RequestType
    {
        get { return requestType; }
        set { requestType = value; }
    }

    //申请内容
    private string requestContent;
    public string RequestContent
    {
        get { return requestContent; }
        set { requestContent = value; }
    }

    //数量
    private int number;
    public int Number
    {
        get { return number; }
        set { number = value; }
    }
}

这很好解决了原来的大量分支判断造成难维护,灵活性差的问题。


yuanoung
10 声望1 粉丝

« 上一篇
命令模式
下一篇 »
中介者模式

引用和评论

0 条评论