一、前言
这段时间正在重温设计模式,通过此系列将复习过程中的一些理解记录下来,由于是本人自己的学习信息,如有错误,望雅正。
本文是整个系列的第一篇,用来记录学习设计模式之前的一些基础知识,下面开始进入学习。
二、抽象类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。
-
接口
这是一个接口的图,其中"<<interface>>"表明了接口的身份,"IFly"是接口名,"+Fly():void"是方法,其中"+"表名公开属性,"void"表名没有返回值。
-
类
在类图当中一般分为三个部分,第一块是类名,第二块是属性,第三块是方法,方法有三种权限"+"对应的是public,"-"对应的是private,"#"对应的是protect。
-
关系
对象与对象之间并不是完全独立的存在,它们之间存在这各种关系,包括了:继承、实现、依赖、引用、聚合、组合,在UML中又是通过何种方式实现?
- 继承
继承一般是用来表示子类与父类之间的关系,如下图Frog继承自Animal父类。
- 实现 实现用来表示在类当中实现接口的行为,实现接口在类图当中有两种表现。
-
第一种,通过一根棒棒糖示。
第二种,通过虚线与三角形来表示:
- 依赖
依赖关系表示一个类依赖于另外一个类的关系,依赖关系是单向的,简单来说就是一个类需要使用到另外一个类,比如动物需要氧气(可能有例外,请勿钻牛角尖),在代码中体现可能为Oxygen作为参数进入到Animal类当中。
- 关联
关联关系一般用来表示一个类知道另外一个类,与依赖关系不同的是,关联关系一般是将另外一个类作为本类的一个属性。Computer与Monitor关联,Monitor作为一个属性在Computer当中。
- 组合
组合是一种拥有关系,体现了严格的部分和整体,比如人有两个手,两个脚,鸟有两只翅膀。通过不同的部件组合成一个完整的整体。
- 聚合
聚合是单体与群体之间的管理,比如一群人与一个人的关系,一个订单与多个订单项的关系。
四、面向对象几大原则
运用设计模式的核心就在于面向对象的几大原则,几大原则的文章在园子里也有不少人写了,写出来也有点多,在里面找个:
单一职责原则(SRP):对于一个类来说,应该仅有一个引起它变化的原因。
开闭原则(OCP):对于类来说,应当对扩展开放,对修改关闭。
里氏代换原则(LSP):子类型必须能够替换掉它们的父类型。
依赖倒转原则(DIP):开发应当依赖于抽象,而不应该依赖于具体。
接口隔离原则(ISP):接口应当拥有单一职责,不要将不同类型的接口合为一个大接口。
迪米特法则(LoD):类应当对其他对象尽可能少的了解。如果两个类不必彼此直接进行通信,那么这两个类就不应该直接的相互引用,如果需要互相调用,可以通过第三者转发。
五、结尾
在复习完基础之后,接下来将进入设计模式的温习。未完待续~
如果本文对您有用的话,希望您给个推荐~谢谢~