zoukankan      html  css  js  c++  java
  • 【模板模式】 Template Pattern

    模板模式 又叫模板方法模式,在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情冴下,重新定义算法中的某些步骤(这个我觉得很抽象,很抽象)


    e:学会说“不”,把时间用在更重要的事情上


    案例:在一组监控的程序中,我们需要记录程序启动和结束一些信息(日志能通过上下文的信息根据约定自动生成)

     //Ingore the unreasonable class name, just for presentation
        public abstract class BaseClass
        {
            protected void LogStart()
            {
                Console.WriteLine("Log Start Infomation");
            }
    
            protected void LogEnd()
            {
                Console.WriteLine("Log End Infomation");
            }
    
            public abstract void DoWork();
    
        }
    
    
        public class FirstSubClass : BaseClass
        {
            public void Execute()
            {
                base.LogStart();
    
                DoWork();
    
                base.LogEnd();
            }
    
            public override void DoWork()
            {
                Console.WriteLine(this.GetType().Name + "Do Work");
            }
        }
    View Code

    这里的不当之处在哪里?如你所见,子类负责在Execute()方法执行中的特定点调用基类,这样导致子类的编写人员需要记住这些方法,并在合适的时候调用(子类程序员好累有木有,要记住好多东西),另外一个不当之处,如果我们并不想子类能隐藏或者重写我们的日志记录,这里就会有一个隐患出现:

     public class FirstSubClass : BaseClass
        {
            protected new void LogStart()
            {
                Console.WriteLine("111Log Start Infomation");
            }
            public void Execute()
            {
                LogStart();
    
                DoWork();
    
                LogEnd();
            }
    
            public override void DoWork()
            {
                Console.WriteLine(this.GetType().Name + "Do Work");
            }
        }
    View Code

    我们重写了一下子类,用new关键字把父类的LogStart()方法隐藏了,这样的话我们调用的时候会直接调用子类的LogStart()。我们用模板模式来解决一下这两个问题:

       //Ingore the unreasonable class name, just for presentation
        public abstract class BaseClass
        {
            private void LogStart()
            {
                Console.WriteLine("Log Start Infomation");
            }
    
            private void LogEnd()
            {
                Console.WriteLine("Log End Infomation");
            }
    
            public abstract void DoWork();
            public void Execute()
            {
                LogStart();
    
                DoWork();
    
                LogEnd();
            }
    
        }
    
    
        public class FirstSubClass : BaseClass
        {
    
            public override void DoWork()
            {
                Console.WriteLine(this.GetType().Name + "Do Work");
            }
        }
    View Code

    我们把LogStart(),LogEnd()的权限都设置成private,这样子类就不能改变我们固定的算法了(这是完全根据业务需求来决定),把Execute提到父类,让父类来控制流程,而只让子类填写可变的算法(函数),我们子类编写人员只要根据父类的限定(abstract的方法)来编写对应的算法就好了,这样在写单元测试的时候也更加的单一化,只需要对子类自身实现的算法进行有效性测试就可以了。

    若有不对,不足之处请指出,请不要只写一个:漏洞百出此类评价,谢谢大家的指点和帮助!
  • 相关阅读:
    HDU 2639 Bone Collector II (01背包,第k解)
    POJ 2184 Cow Exhibition 奶牛展(01背包,变形)
    hihoCoder #1165 : 益智游戏 (挑战赛11 B题)
    UVA 562 Dividing coins 分硬币(01背包,简单变形)
    POJ Charm Bracelet 挑饰品 (常规01背包)
    hiho一下 第四十四周 博弈游戏·Nim游戏(直接公式解)
    UVA 624 CD(01背包,要记录路径)
    118 Pascal's Triangle 帕斯卡三角形 杨辉三角形
    117 Populating Next Right Pointers in Each Node II 每个节点的右向指针 II
    116 Populating Next Right Pointers in Each Node 每个节点的右向指针
  • 原文地址:https://www.cnblogs.com/guochenkai/p/3904498.html
Copyright © 2011-2022 走看看