设计模式奠基石——UML关系转化为代码

简介: 继承关系是子类(派生类)继承父类(基类),或者子接口继承父接口的关系。即子类对象“is a” 父类对象,比如鸟是动物。

     1、继承关系(泛化关系)


      【说明】:继承关系是子类(派生类)继承父类(基类),或者子接口继承父接口的关系。即子类对象“is a” 父类对象,比如鸟是动物。


      【UML图】:

25.png


       图解:Animal为父类,Bird类、Fish类、Dog类分别继承了Animal类,它们不仅继承了Animal的公用方法Breath(),同时也根据自己的实际需要拓展了相关方法(Fly()方法、Swim()方法、Run()方法)。


      【对应代码】:    

    <span style="font-size:18px;">//Animal类(父类):
       class Animal
       {
        public void Breath() { }
       }
    //Bird类、Fish类和Dog类(子类):
       class Bird : Animal
      {
        public void Fly() { }
      }
      class Fish : Animal
      {
        public void Swim() { }
      }
      class Dog : Animal
      {
        public void Run() { }
      }</span>


     【画龙点睛】:


        ★说明子类可以继承所有父类非private的属性和方法,并且可以根据实际情况进行拓展(增加属性或方法),如上例中的Fly()方法就是鸟类对动物类的拓展;


        ★类只可以有单继承(一个子类只可以继承一个父类,一个父类可以由多个子类继承),接口可以有多继承(一个子接口可以继承多个父接口)。


       2、实现关系


     【说明】:实现关系就是类实现接口的关系。以下引用《大话设计模式》中的例子来说明。


     【UML图】:

26.png


      图解:机器猫、孙悟空、猪八戒都可以变出东西来,但又因为其他动物并不像他们三个一样具有这种超能力,因此并不能直接把这个方法加到父类Animal中去,而需要把“变出东西”这种方法抽象出一个名为“变东西”的接口,到时候让具有这种超能力的动物们(比如机器猫、孙悟空、猪八戒)直接去实现这个接口。

     【对应代码】:      

<span style="font-size: 18px;">   //Animal类、Cat类、Monkey类、Pig类、叮当猫类的代码省略
    interface IChange
    {
        string ChangeThing(string thing);
    }
    class SunWukong:Monkey,IChange//孙悟空继承与猴类,并实现IChange接口
    {
        public string ChangeThing(string thing)  //此处为实现接口的方法,注意不能加override修饰符
        {
            return "我老孙有七十二般变化,可以变出" + thing;
        }
    }
    class ZhuBajie : Pig, IChange//猪八戒继承与猪类,并实现IChange接口
    {
        public string ChangeThing(string thing) //此处为实现接口的方法,注意不能加override修饰符
        {
            return "我老猪有三十六般变化,可以变出" + thing;
        }
    }</span>


     【画龙点睛】:

       ★类可以实现多重接口,即一个类实现多个接口;


       ★因为接口中的方法用来定义对象之间通信的契约,如果指定接口中的方法为私有或保护就没有意义了,所以它们默认为公有方法,即接口不能用new、public、protected、internal、private等修饰符。


       ★为了区分类和接口,接口名称一般都以“I”作为首字母(当然不这样声明也可以)。


        (更多注意事项可参考百度百科“接口”)


       3、依赖关系

     【说明】:如果一个类A需要用到另一个类B,或者说一个类A负责构造类B的实例时,则称类A依赖类B,即A类对象“use a” B类对象。比如人写字需要用到笔,那这个关系就是人类依赖笔类;又比如机器造零件,那机器类就依赖零件类(本例参考简单工厂模式)。


  【UML图】:

      人写字的UML图:

27.png

      机器造零件的UML图:


28.png


   【对应代码】:


      例1:人写字的代码(此处体现依赖的方式为:Pen是People中一个方法中的变量)


<span style="font-size:18px;">    class People
    {
        public void Write()
        {
            Pen pen=new Pen();
            pen.Write();   
        }
    }
    class Pen
    {
        public void Write(){}
        public void Draw(){}
    }</span>


      例2:机器造零件的代码(此处体现依赖的方式为:Part是Machine中一个方法中返回值)

    class Part         //零件类
    {
       private string type;
    }
    class PartA : Part //零件A类(继承零件类)
    { }
    class PartB : Part //零件B类(继承零件类)
    { }
    class Machine     //机器类(职责:根据要求选择性地生产零件A或零件B)
    {
        public static Part CreatePart(string type)
        {
            Part part = null;
            switch (type)
            {
                case "A":
                    part = new PartA();
                    break;
                case "B":
                    part = new PartB();   
                    break;
            }
            return part;     
        }
    }


     【画龙点睛】:

      ★假如A依赖B,依赖关系代码表现形式:

         1、B是A中方法的变量;

         2、B是A中方法的返回值;

         3、B是A中方法的参数。


       4、关联关系

     【说明】:关联关系简单来说就是一个类A“知道”另一个类B的时候,则类A关联类B,UML图表现为实线箭头由类A指向类B。比如许多动物都可以预知地震、海啸等自然灾害,狗在自然灾害前会狂吠不止、老鼠在震前会出窝乱窜……


   【UML图】:

29.png


   【对应代码】:


    class Disaster
    { 
        private string name;
        public Disaster(string name)
        {
            this.name = name;
        }
    }
    class Mouse
    {       
       private Disaster disaster;
       public Disaster TheDisaster
       {          
          get{return disaster;}            
          set{this.disaster = value;}
        }
        public void Run(){}    } 
    class Dog 
    {     
        private Disaster disaster;    
        public Disaster TheDisaster        
        {          
           get{return disaster;}            
           set{this.disaster = value;}
        }       
        public void Bark(){}    }  
    //客户端代码  
    static void Main(string[] args)
        {
         Disaster disaster=new Disaster("Typhoon");      
         Mouse mouse=new Mouse();    
         Dog dog=new Dog();
         mouse.TheDisaster=disaster;
         dog.TheDisaster=disaster;
         if(mouse.TheDisaster!=null)
         mouse.Run(); 
         if(dog.TheDisaster!=null)                    
         dog.Bark();
        }

     【画龙点睛】:


      ★关联关系有单向关联、双向关联、自身关联、多维关联等等。代码体现为,哪个类关联另一个类就直接在类中调用那个类即可;


      ★关联和依赖的区别:


        (1)从类的属性是否增加的角度看:

                 发生依赖关系的两个类都不会增加属性。其中的一个类作为另一个类的方法的参数或者返回值,或者是某个方法的变量而已。

                 发生关联关系的两个类,其中的一个类成为另一个类的属性,而属性是一种更为紧密的耦合,更为长久的持有关系。

        (2)从关系的生命周期来看:

                 依赖关系是仅当类的方法被调用时而产生,伴随着方法的结束而结束了。

                 关联关系是当类实例化的时候即产生,当类销毁的时候,关系结束。相比依赖讲,关联关系的生存期更长。


       5、聚合关系:

     【说明】:如果A对象可以包含B对象,但是B对象不一定要成为A对象的组成部分,那么A对象与B对象之间的关系为聚合关系,即A对象“contain a” B对象,比如一辆自行车包含两个车轮,但这两个车轮不一定要安装在这两自行车上。


     【UML图】:

30.png


     【对应代码】:  


    class Wheel{ }
    class Bicycle
    {
        private Wheel BicycleWheel;
        public Wheel BicycleWheel
        {
            set{BicycleWheel=value;}
            get{return BicycleWheel;}
        }
    }

     【画龙点睛】:


      ★普通关联关系的两个类处于同一层次上,而聚合关系的两个类处于不同的层次,一个是整体,一个是部分,是一种弱的“拥有”关系。


      ★A对象可以包含B对象,但B对象不是A对象的组成部分。具体表现为,如果A由B聚合成,表现为A包含有B的全局对象,但是B对象可以不在A创建的时刻创建。


       6、组合关系

     【说明】:如果A类对象包含B类对象,而且B类对象一定要是A类对象的组成部分,那么A类对象与B类对象之间的关系为聚合关系,即A类对象“contain a” B类对象,比如一个健康的人有两条胳膊和两条腿,而且这两条胳膊和两条腿一定只属于这个人。即A对象“has a” B对象。

     【UML图】:

31.png

     【对应代码】:    


  <span style="font-size:18px;">   class Arm { }
    class Leg { }
    class People
    {
        private Arm myArm;
        private Leg myLeg;
        public People()
        {
            myArm=new Arm();
            myLeg=new Leg();
        }
    }</span>


     【画龙点睛】:


      ★组合是比聚合关系强的关系。它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期。组合关系是一种强的“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期一致。如果A由B组成,表现为A包含有B的全局对象,并且B对象在A创建的时刻创建。


      ★聚合和组合的区别:请参见浅谈UML中的聚合与组合


      在这几种关系中,它们的耦合强度由强到弱为:泛化=实现>组合>聚合>关联>依赖。设计模式就如同搭积木,这几种关系就如同积木,设计模式的作用无非就是为了将这几种关系组合,最大化降低程序耦合度,使代码结构达到最优,便于应对以后的需求变更。


      需要注意的是,其中的关联关系、聚合关系、组合关系的代码体现有一个相似点,就是都是一有个类作为另一个类的成员。这一点需要用心理解清楚,不要混淆。


      大家如果有什么好的说明例子或者建议请您提出宝贵的意见,谢谢。


    【注:本文代码均用C#来实现,与其他语言可能会有差异(如java中子类继承父类使用“class 子类 extends 父类”的结构;java中类实现接口使用“class 类 implements 接口”的结构等】


相关文章
|
4月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
18天前
|
设计模式 Java 程序员
【23种设计模式·全精解析 | 概述篇】设计模式概述、UML图、软件设计原则
本系列文章聚焦于面向对象软件设计中的设计模式,旨在帮助开发人员掌握23种经典设计模式及其应用。内容分为三大部分:第一部分介绍设计模式的概念、UML图和软件设计原则;第二部分详细讲解创建型、结构型和行为型模式,并配以代码示例;第三部分通过自定义Spring的IOC功能综合案例,展示如何将常用设计模式应用于实际项目中。通过学习这些内容,读者可以提升编程能力,提高代码的可维护性和复用性。
【23种设计模式·全精解析 | 概述篇】设计模式概述、UML图、软件设计原则
|
3月前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性和扩展性
【10月更文挑战第13天】 本文将探讨PHP中常见的设计模式及其在实际项目中的应用。通过对比传统编程方式,我们将展示设计模式如何有效地提高代码的可维护性和扩展性。无论是单例模式确保类的单一实例,还是观察者模式实现对象间的松耦合,每一种设计模式都为开发者提供了解决特定问题的最佳实践。阅读本文后,读者将能更好地理解和应用这些设计模式,从而提升PHP编程的效率和质量。
|
3月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP开发领域,设计模式是解决常见问题的高效方案集合。它们不是具体的代码,而是一种编码和设计经验的总结。单例模式作为设计模式中的一种,确保了一个类仅有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的基本概念、实现方式及其在PHP中的应用。
单例模式在PHP中的应用广泛,尤其在处理数据库连接、日志记录等场景时,能显著提高资源利用率和执行效率。本文从单例模式的定义出发,详细解释了其在PHP中的不同实现方法,并探讨了使用单例模式的优势与注意事项。通过对示例代码的分析,读者将能够理解如何在PHP项目中有效应用单例模式。
|
4月前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性与扩展性
设计模式在PHP开发中至关重要,如单例模式确保类仅有一个实例并提供全局访问点,适用于管理数据库连接或日志记录。工厂模式封装对象创建过程,降低系统耦合度;策略模式定义算法系列并使其可互换,便于实现不同算法间的切换。合理选择设计模式需基于需求分析,考虑系统架构,并通过测试驱动开发验证有效性,确保团队协作一致性和代码持续优化。设计模式能显著提升代码质量,解决开发中的设计难题。
42 8
|
4月前
|
设计模式 算法 PHP
PHP中的设计模式:提升代码的灵活性与可维护性
在本文中,我们将深入探讨PHP编程语言中的一种重要概念——设计模式。设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它代表了最佳的实践,被有经验的面向对象的软件开发人员所采用。本文将通过具体的实例,展示如何在PHP项目中应用设计模式,以提高代码的灵活性和可维护性。无论你是PHP初学者还是经验丰富的开发者,都能从中获得有价值的见解。
|
4月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入探索与实践在软件开发的广袤天地中,PHP以其独特的魅力和强大的功能,成为无数开发者手中的得力工具。而在这条充满挑战与机遇的征途上,设计模式犹如一盏明灯,指引着我们穿越代码的迷雾,编写出更加高效、灵活且易于维护的程序。今天,就让我们聚焦于设计模式中的璀璨明珠——策略模式,深入探讨其在PHP中的实现方法及其实际应用价值。
策略模式,这一设计模式的核心在于它为软件设计带来了一种全新的视角和方法。它允许我们在运行时根据不同情况选择最适合的解决方案,从而极大地提高了程序的灵活性和可扩展性。在PHP这门广泛应用的编程语言中,策略模式同样大放异彩,为开发者们提供了丰富的创作空间。本文将从策略模式的基本概念入手,逐步深入到PHP中的实现细节,并通过一个具体的实例来展示其在实际项目中的应用效果。我们还将探讨策略模式的优势以及在实际应用中可能遇到的挑战和解决方案,为PHP开发者提供一份宝贵的参考。
|
4月前
|
设计模式 存储 数据库连接
探索PHP中的设计模式:提高代码的可维护性与扩展性
本文将深入探讨PHP中常用的设计模式,包括单例模式、工厂模式和观察者模式。通过具体的代码示例,展示如何在实际项目中应用这些设计模式,以提高代码的可维护性与扩展性。无论你是PHP初学者还是有一定经验的开发者,都可以通过本文的学习,提升你的编程技巧和项目架构能力。
|
4月前
|
设计模式 算法 搜索推荐
PHP中的设计模式:提高代码可维护性的秘诀
在本文中,我们将探讨PHP设计模式的重要性以及它们如何帮助开发者编写出更加灵活、可维护的代码。我们将介绍几种常见的设计模式,包括单例模式、工厂模式和策略模式,并通过实际示例展示它们在PHP中的应用。最后,我们会讨论何时使用这些设计模式以及在实际项目开发中的最佳实践。
50 1
|
4月前
|
设计模式 Java 测试技术
Java设计模式-UML与设计原则(1)
Java设计模式-UML与设计原则(1)