使用重载方式实现继承体系的代码重用 

 

代码重用是现在软件开发中一个十分常见的话题,其深远意义和优势是大家共同追寻的高层次开发境界。我也经常通过总结开发工作中的实际代码来学习如何让自己的代码得到最大化的重用,在总结过程中我发现,绝大多是的重用都是方法级的。为此我总结了一下在编程过程中针对重用这个话题的一些归类,也希望朋友们提自己的建议,当然我也会在日后的开发中继续总结和归纳。

 

这个重用的思路其实也不是我凭空而来的,是我在认识面向对象后结合继承体系而总结出的,在这里写出来希望大家喜欢。

 

首先我先总结一下我认为的三种重用方式,在逐一介绍:

方法一:多个方法调用一个通用方法。(这也是使用最多,最直接的重用手段。)

方法二:多种类型的实体使用同一方法,将差异分来进行,将相同的地方组合在一起。(开始使用继承系统进行方法重用和隔离变化,但是不狗彻底。)

方法三:使用继承体系将不同类型的实体当参数,进行方法重载,子类型实体隔离变化,父类型实体进行代码重用。(使得代码重用最大化,并且阅读简单,将通用和变化完全隔离。)

 

首先我们看一下需要结果图:

 

 

根据上图我先写一个没有重用的代码:

   public void Show()
        {
            "宠物狗".WriteLine();
            "让主人高兴".WriteLine();
            "狗叫".WriteLine();
            "啃骨头吃肉".WriteLine();

            "导盲犬".WriteLine();
            "给主人带路".WriteLine();
            "狗叫".WriteLine();
            "啃骨头吃肉".WriteLine();
        }

(这里解释一下,我扩展了System.string类型,"啃骨头吃肉".WriteLine();
就等于 Console.WriteLine("啃骨头吃肉".);)

方法一的重用是我们普遍用的,为:

    public void Show()
        {
            "宠物狗".WriteLine();
            "让主人高兴".WriteLine();
            ShoweDog();

            "导盲犬".WriteLine();
            "给主人带路".WriteLine();
            ShoweDog();
        }

        public void ShoweDog()
        {
            "狗叫".WriteLine();
            "啃骨头吃肉".WriteLine();
        }

 

由上面的代码我们看到,方法一虽然只写了一次“狗叫”和“啃骨头吃肉”就完成了两次对狗的描述,但是我们可以在进行优化,因为方法一的重用不是我认为最优的方法。于是我设计了个体系结构如图:

我们将“导盲犬”和“宠物犬”分成两个实体并且都继承了“狗”,此时用实体封装了狗的动作,并且调用如下代码:

 

  public void Show()
        {
            this.ShowPetDog(new PetDog());
            this.ShowSeeingEyeDog(new SeeingEyeDog());
        }

        public void ShowPetDog(PetDog petDog)
        {
            petDog.MakeHostHappy();
            ShoweDog(petDog);
        }

        public void ShowSeeingEyeDog(SeeingEyeDog seeingEyeDog)
        {
            seeingEyeDog.SeeingWay();
            ShoweDog(seeingEyeDog);
        }

        public void ShoweDog(Dog dog)
        {
            dog.EatMeat();
            dog.Call();
        } 

 

上面的代码已经使用体系结构进行了方法重用,但是我还是感到不满意,因为在使用的时候仍然需要给方法命名,增加了方法的个数,为调用函数增加了难度。

于是我使用了方法三,代码如下:

   public void Show()
        {
            this.ShoweDog(new PetDog());
            this.ShoweDog(new SeeingEyeDog());
        }

        public void ShoweDog(PetDog petDog)
        {
            petDog.MakeHostHappy();
            ShoweDog((Dog)petDog);
        }

        public void ShoweDog(SeeingEyeDog seeingEyeDog)
        {
            seeingEyeDog.SeeingWay();
            ShoweDog((Dog)seeingEyeDog);
        }

        public void ShoweDog(Dog dog)
        {
            dog.EatMeat();
            dog.Call();
        }

 

到此方法被统一了,只要我知道了实体的体系结构就可以使用其体系中的任意类型来对方法进行调用,无需了解其内容操作。“导盲犬”、“宠物犬”和“狗”都可以当参数使用,因为方法被重载了,如果定义结构的话,使用方将是十分方便的。

 

上面的是个十分简单的例子,很多朋友会感觉方法四比方法二的代码多得多,这是因为这个例子太简单了。如果在真实的业务中,比如说方法四的实体变成了三层甚至到达四层以上时,或者继承父类的子类在十个甚至更多的时候,重载的使用就变得非常方便了。拿我为例,我在公司的项目中,四层以上的实体体系,十个以上子类都是十分常见的事情,所以对于重载和方法路由是使用会都大大减少代码量,并且能够大量减少碍眼的“if-else”和“switch”。