责任链设计模式混淆如何运作

时间:2017-09-18 13:01:29

标签: c#

Below code is from the article in CodeProject website. It is an example that explains **Code of responsibility design pattern**. Here is the link  "https://www.codeproject.com/articles/494241/understanding-and-implementing-chain-of-responsibi"

我无法理解何时 tl.ApplyLeave(new Leave(Guid.NewGuid(),15)); 行在方法中执行并且LeaveApplied Supervisor属性上的方法称为 Supervisor.LeaveApplied(this,l); 其中 this 指向 void TeamLeader_onLeaveApplied(Employee e,)中的ProjectLeader类类型的对象离开l)方法然后如何调用基类中的方法Employee public void LeaveApplied(Employee s,Leave leave)第一个参数 Employee s 一直指向对象键入TeamLeader。这怎么可能?不应该员工指向 ProjectLeader 类型的对象。请帮我理解这是怎么发生的?谢谢你的帮助。

 public abstract class Employee
        {
            // Every employee will have a supervisor
            protected Employee supervisor;

            // Event mechanism to know whenever a leave has been applied
            public delegate void OnLeaveApplied(Employee e, Leave l);
            public event OnLeaveApplied onLeaveApplied = null;

            // This will invoke events when the leave will be applied
            // i.e. the actual item will be handed over to the hierarchy of
            // concrete handlers.
            public void LeaveApplied(Employee s, Leave leave)
            {
                if (onLeaveApplied != null)
                {
                    onLeaveApplied(this, leave);
                }
            }

            // This is the function which concrete handlers will use to take 
            // action, if they are able to take actions.
            public abstract void ApproveLeave(Leave leave);

            // getter to get the supervisor of current employee
            public Employee Supervisor

            {
                get
                {
                    return supervisor;
                }
                set
                {
                    supervisor = value;
                }
            }

            // Using this we can apply for leave
            public void ApplyLeave(Leave l)
            {
                LeaveApplied(this, l);
            }
        }
        public class TeamLeader : Employee
        {
            // team leas can only approve up to 7 days of leave
            const int MAX_LEAVES_CAN_APPROVE = 10;

            // in constructor we will attach the event handler that
            // will check if this employee can process or he needs to
            // pass on to next employee
            public TeamLeader()
            {
                this.onLeaveApplied += new OnLeaveApplied(TeamLeader_onLeaveApplied);
            }

            // in this function we will check if this employee can 
            // process or he needs to pass on to next employee
            void TeamLeader_onLeaveApplied(Employee e, Leave l)
            {
                // check if we can process this request
                if (l.NumberOfDays < MAX_LEAVES_CAN_APPROVE)
                {
                    // process it on our level only
                    ApproveLeave(l);
                }
                else
                {
                    // if we cant process pass on to the supervisor 
                    // so that he can process
                    if (Supervisor != null)
                    {
                        Supervisor.LeaveApplied(this, l);
                    }
                }
            }

            // If we can process lets show the output
            public override void ApproveLeave(Leave leave)
            {
                Console.WriteLine("LeaveID: {0} Days: {1} Approver: {2}",
                    leave.LeaveID, leave.NumberOfDays, "Team Leader");
            }
        }
        class ProjectLeader : Employee
        {
            const int MAX_LEAVES_CAN_APPROVE = 20;

            // in constructor we will attach the event handler that
            // will check if this employee can process or he needs to
            // pass on to next employee
            public ProjectLeader()
            {
                this.onLeaveApplied += new OnLeaveApplied(ProjectLeader_onLeaveApplied);
            }

            // in this function we will check if this employee can 
            // process or he needs to pass on to next employee
            void ProjectLeader_onLeaveApplied(Employee e, Leave l)
            {
                // check if we can process this request
                if (l.NumberOfDays < MAX_LEAVES_CAN_APPROVE)
                {
                    // process it on our level only
                    ApproveLeave(l);
                }
                else
                {
                    // if we cant process pass on to the supervisor 
                    // so that he can process
                    if (Supervisor != null)
                    {
                        Supervisor.LeaveApplied(this, l);
                    }
                }
            }

            // If we can process lets show the output
            public override void ApproveLeave(Leave leave)
            {
                Console.WriteLine("LeaveID: {0} Days: {1} Approver: {2}",
                    leave.LeaveID, leave.NumberOfDays, "Project Leader");
            }

        }

        class Program
        {
            static void Main(string[] args)
            {
                // lets create employees 
                TeamLeader tl = new TeamLeader();
                ProjectLeader pl = new ProjectLeader();
                HR hr = new HR();

                // Now lets set the hierarchy of employees
                tl.Supervisor = pl;
                pl.Supervisor = hr;

                // Now lets apply 5 day leave my TL
                tl.ApplyLeave(new Leave(Guid.NewGuid(), 5));

                // Now lets apply 15 day leave my TL
                tl.ApplyLeave(new Leave(Guid.NewGuid(), 15));

                // Now lets apply 25 day leave my TL
                tl.ApplyLeave(new Leave(Guid.NewGuid(), 25));

                // Now lets apply 35 day leave my TL
                tl.ApplyLeave(new Leave(Guid.NewGuid(), 35));

                Console.ReadLine();
            }

1 个答案:

答案 0 :(得分:0)

tl.ApplyLeave(new Leave(Guid.NewGuid(), 15));不确定你在这里不明白,它会在tl.ApplyLeave(new Leave(Guid.NewGuid(), 5));之后执行

主管在Main()

中宣布
tl.Supervisor = pl;
pl.Supervisor = hr;

因此,只要满足此条件,就会调用此Supervisor.LeaveApplied(this, l);

// check if we can process this request
if (l.NumberOfDays < MAX_LEAVES_CAN_APPROVE)
{
    // process it on our level only
    ApproveLeave(l);
}
else
{
    // if we cant process pass on to the supervisor 
    // so that he can process
    if (Supervisor != null)
    {
        Supervisor.LeaveApplied(this, l);
    }
}

public void LeaveApplied(Employee s, Leave leave),是Employee s首先是TeamLeader的对象,但是,查看上面的条件语句,Supervisor.LeaveApplied(this, l);主管调用该方法,因为请假大于10天,因此它是ProjectLeader

此外,如果您通过自己单步调试代码并查看每个方法的调用方式,您可以更好地理解它。

修改

再次查看之后,确实不需要public void LeaveApplied(Employee s, Leave leave)它应该只是public void LeaveApplied(Leave leave)因为在该方法的内部是:

if (onLeaveApplied != null)
{
    onLeaveApplied(this, leave);
}

所以我没有看到Employee s的重点。