设计模式之设计原则(下)

   好久没有写博客啦,因最近在忙于弄自己的一个网站,一直没有时间写了,在这里跟广大园友说声抱歉,今天也正好是中秋节,在这里祝大家节日快乐!废话少说,接续上节的继续写下去。
  依赖倒置原则(Dependence Inversion Principle),简称DIP:他的核心思想就是在进行业务设计时,高层模块不应该依赖于底层模块,两者应该依赖与抽象,抽象而不依赖于具体实现,具体实现应该依赖与抽象,这样会使代码变得更稳定,从而大大提高了程序应对业务变化的能力。
我们来看一下一个例子来更深刻的理解一下上面的核心思想:
 1 public class Car
 2 
 3     {
 4 
 5         public string CarName;
 6 
 7  
 8 
 9         public Car(string carname)
10 
11         {
12 
13             this.CarName = carname;
14 
15         }
16 
17         public void 驾驶()
18 
19         {
20 
21             Console.WriteLine(CarName + ":驾驶");
22 
23         }
24 
25  
26 
27     }
28 
29  
30 
31     public class Person
32 
33     {
34 
35         public void drive()
36 
37         {
38 
39             Car bmw=new Car("BMW");
40 
41             bmw.驾驶();
42 
43         }
44 
45     }

  从上面的例子看一下能发现Person类依赖与Car类,这样耦合度高,这样的话比如说Car类发生变化时很容易出现问题,比如说哪天这个Person类不想开汽车了想开火车或者飞机时怎么办,那我们可以改造一下上面的类,Person类不依赖于Car这个具体实现,我们要依赖抽象,依赖与交通工具,我们看看代码:

  1 //交通工具才抽象
  2 
  3     public interface IVehicle
  4 
  5     {
  6 
  7         void 驾驶();
  8 
  9     }
 10 
 11     //汽车
 12 
 13     public class Car : IVehicle
 14 
 15     {
 16 
 17         public string CarName;
 18 
 19  
 20 
 21         public Car(string carname)
 22 
 23         {
 24 
 25             this.CarName = carname;
 26 
 27         }
 28 
 29         public void 驾驶()
 30 
 31         {
 32 
 33             Console.WriteLine(CarName + ":驾驶");
 34 
 35         }
 36 
 37  
 38 
 39     }
 40 
 41     //飞机
 42 
 43     public class Plane : IVehicle
 44 
 45     {
 46 
 47         public string PlaneName;
 48 
 49  
 50 
 51         public Plane(string carname)
 52 
 53         {
 54 
 55             this.PlaneName = carname;
 56 
 57         }
 58 
 59         public void 驾驶()
 60 
 61         {
 62 
 63             Console.WriteLine(PlaneName + ":驾驶");
 64 
 65         }
 66 
 67  
 68 
 69     }
 70 
 71     //火车
 72 
 73     public class Train : IVehicle
 74 
 75     {
 76 
 77         public string TrainName;
 78 
 79  
 80 
 81         public Train(string carname)
 82 
 83         {
 84 
 85             this.TrainName = carname;
 86 
 87         }
 88 
 89         public void 驾驶()
 90 
 91         {
 92 
 93             Console.WriteLine(TrainName + ":驾驶");
 94 
 95         }
 96 
 97  
 98 
 99     }
100 
101     public class Person
102 
103     {
104 
105         private IVehicle machine = null;
106 
107         public Person(IVehicle _vehicle)
108 
109         {
110 
111             machine = _vehicle;
112 
113         }
114 
115         public void drive()
116 
117         {
118 
119             machine.驾驶();
120 
121         }
122 
123     }

 

 

类图如下:

 

客户端调用代码:

 1  Person person1=new Person(new Car("宝马"));
 2 
 3   person1.drive();
 4 
 5  Person person2=new Person(new Plane("飞机"));
 6 
 7  person2.drive();
 8 
 9 Person person3=new Person(new Train("火车"));
10 
11  person3.drive();
12 
13  Console.ReadLine();

输出结果如下:

从以上代码可以看出Person类的驾驶方法来说不需要依赖具体的交通工具,只依赖抽象,具体的哪一个交通工具是从外部传入的。这样其实就是抽象编码。也是依赖倒置的有点。

组合优于继承:他的核心思想就是组合比继承更大的灵活性和稳定结构。

为什么怎么说呢,我们来看看他们各自的优缺点:

继承优点:

1)新的实现很容易,因为大部分是继承而来的。

2)很容易修改和扩展已有的实现

继承的缺点:

1)打破了封装,因为基类想子类暴露额具体的实现细节。

2)白盒重用,因为基类的内部细节通常对子类是可见的。

3)当父类发生改变时子类也做出相应的改变。

4)不能在运行时修改由父类继承来的实现。

组合优点:

1)被包含对象通过包含他们的类来访问

2)黑盒重用,因为被包含对象的内部细节是不可见的

3)很好的封装

4)每一个类都专注于一个任务

5)通过获得和被包含对象的类型相同的对象引用,可以在运行时动态定义组合的方式

组合缺点:

1)系统可能会包含更过的对象

2)为了使组合时可以使用不同的对象,必须小心的定义接口。

posted @ 2014-09-08 11:04  爱拼才会赢-Martin  阅读(838)  评论(2编辑  收藏  举报