重温设计模式之前言

一、前言

  这段时间正在重温设计模式,通过此系列将复习过程中的一些理解记录下来,由于是本人自己的学习信息,如有错误,望雅正。

  本文是整个系列的第一篇,用来记录学习设计模式之前的一些基础知识,下面开始进入学习。

二、抽象类VS接口

  抽象类和接口是设计模式的基础,在绝大部分的设计模式当中都有设计到抽象类或者接口。抽象类和接口在定义、使用都有些类似,两者时间又有何区别?

  抽象类使用Abstract关键字来定义,在抽象类当中可以定义类属性、已经实现的方法、抽象方法。接口使用Interface关键字来定义,接口名一般使用大写的"I"作为开头(如:IFlay,ISwim),接口中也可拥有属性,但不可拥有已经定义的方法。对于抽象类和接口的区别,我认为应当是:

    抽象类决定你是什么,接口决定你能干什么!

例子:对于青蛙和海鸥来说,他们首先都是动物,然后青蛙能游泳,海鸥能飞翔,转化成代码如下:

/// <summary>

///定义一个动物的基类

/// </summary>

public abstract class Animal

{

  /// <summary>

  ///所有动物都会有一个名字。

  /// </summary>

  public string Name { get; private set; }

 
  public Animal(string Name) {

    this.Name = Name;

    this.Born();

  }

 

  /// <summary>

  ///定义出生方法,所有动物都会有出生的时候。

  /// </summary>

  public void Born() {

    Console.WriteLine(this.Name + " 出生");

    this.First();

  }

 

  /// <summary>

  ///定义一个虚方法,让子类重写动物出生干的第一件事。

  /// </summary>

  public abstract void First();

}

然后定义两个接口,一个IFly,一个ISwim。

/// <summary>

///游泳接口

/// </summary>

public interface ISwim

{

    void Swim();

}

 

/// <summary>

///飞翔接口

/// </summary>

public interface IFly

{

    void Fly();

}

接着定义两个类,青蛙(Frog)和海鸥(Seagull),继承了Animal和分别实现了ISwim和IFly。

/// <summary>

///青蛙类,青蛙能有用,不能飞翔

/// </summary>

public class Frog:Animal,ISwim

{

  public Frog(string Name):base(Name) {}

  public override void First()
  {
    Console.WriteLine(this.Name + " 出生第一件事是睁开眼睛!");

  }

 

 

  public void Swim()

  {

    Console.WriteLine(this.Name + " 会游泳!");

  }

}

/// <summary>

///海鸥

///海鸥能飞,但是没有游泳的技能

/// </summary>

public class Seagull:Animal ,IFly

{

  public Seagull(string Name) : base(Name) { }

 

  public override void First()

  {

    Console.WriteLine(this.Name + " 出生第一件事是讨食");

  }

 

  public void Fly()

  {

    Console.WriteLine(this.Name + " 可以飞行");

  }

}

接下来运行起来瞧瞧:

static void Main(string[] args)

{

  Animal[] animals = new Animal[2] {

    new Frog("青蛙"),new Seagull("海鸥")

  };

  foreach (var item in animals) {

    IFly fly = item as IFly;

    ISwim swim = item as ISwim;
    ///两个IF,回头咱们给他换掉
    if (fly != null)
    {
      fly.Fly();
    }
    else {
      Console.WriteLine(item.Name + " 不会飞翔");
    }     
if (swim != null)     {      swim.Swim();
    }     
else {       Console.WriteLine(item.Name + " 不会游泳");     }   }   Console.ReadKey(); }

运行结果如下:

三、UML基础

  在复习设计模式之前要先复习一下UML的基础,看懂和会画UML类图是面向对象编程的重要基础。UML是面向对象的建模语言,其中包含了类图、用例图、流程图、序列图等等,由于在复习中只使用到了类图,因此本文只涉及到类图。

  画UML的工具很多,有Visio,Rose,PowerDesigner,EA,甚至在Visual Studio中也能操作。本文的类图来自Visio 2007。

  1. 接口

    这是一个接口的图,其中"<<interface>>"表明了接口的身份,"IFly"是接口名,"+Fly():void"是方法,其中"+"表名公开属性,"void"表名没有返回值。

  2. 在类图当中一般分为三个部分,第一块是类名,第二块是属性,第三块是方法,方法有三种权限"+"对应的是public,"-"对应的是private,"#"对应的是protect。

  3. 关系

    对象与对象之间并不是完全独立的存在,它们之间存在这各种关系,包括了:继承、实现、依赖、引用、聚合、组合,在UML中又是通过何种方式实现?      

  • 继承

    继承一般是用来表示子类与父类之间的关系,如下图Frog继承自Animal父类。

  • 实现
  • 实现用来表示在类当中实现接口的行为,实现接口在类图当中有两种表现。
    1. 第一种,通过一根棒棒糖示。

      第二种,通过虚线与三角形来表示:

  • 依赖

  依赖关系表示一个类依赖于另外一个类的关系,依赖关系是单向的,简单来说就是一个类需要使用到另外一个类,比如动物需要氧气(可能有例外,请勿钻牛角尖),在代码中体现可能为Oxygen作为参数进入到Animal类当中。

  • 关联

关联关系一般用来表示一个类知道另外一个类,与依赖关系不同的是,关联关系一般是将另外一个类作为本类的一个属性。Computer与Monitor关联,Monitor作为一个属性在Computer当中。

  • 组合

组合是一种拥有关系,体现了严格的部分和整体,比如人有两个手,两个脚,鸟有两只翅膀。通过不同的部件组合成一个完整的整体。

  • 聚合

聚合是单体与群体之间的管理,比如一群人与一个人的关系,一个订单与多个订单项的关系。

四、面向对象几大原则

  运用设计模式的核心就在于面向对象的几大原则,几大原则的文章在园子里也有不少人写了,写出来也有点多,在里面找个:

    单一职责原则(SRP):对于一个类来说,应该仅有一个引起它变化的原因。

    开闭原则(OCP):对于类来说,应当对扩展开放,对修改关闭。

    里氏代换原则(LSP):子类型必须能够替换掉它们的父类型。

    依赖倒转原则(DIP):开发应当依赖于抽象,而不应该依赖于具体。

    接口隔离原则(ISP):接口应当拥有单一职责,不要将不同类型的接口合为一个大接口。

    迪米特法则(LoD):类应当对其他对象尽可能少的了解。如果两个类不必彼此直接进行通信,那么这两个类就不应该直接的相互引用,如果需要互相调用,可以通过第三者转发。

五、结尾

  在复习完基础之后,接下来将进入设计模式的温习。未完待续~

  如果本文对您有用的话,希望您给个推荐~谢谢~

原文地址:https://www.cnblogs.com/wilea/p/3249011.html