说起设计模式的六大原则,首先我们要先清楚设计模式是什么?
设计模式它是在面向对象语言的开发过程中,经历各种的场景和问题,提出的解决方法以及思路;
那设计模式的六大原则呢?
设计模式的六大原始是指在面向对象语言开发的过程中,前辈们推荐的一些有指导性的原则,它时长的也会被忽略/违背
单一职责原则:它规定一个类应该只有一个发生变化的原因。所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。简单的说就是,一个类或者一个方法只负责一项职责
第一种违背了单一职责原则我们的写法可能是:
public class People
{
private string _Name;
public People(string name)
{
this._Name = name;
}
public void SpeakDialect()
{
if (this._Name.Equals("河北人"))
Console.WriteLine($"{this._Name}说河北话");
if (this._Name.Equals("北京人"))
Console.WriteLine($"{this._Name}说北京话");
}
}
那么第二种遵守了单一职责原则我们首先声明一个抽象类:
public abstract class AbstarctPeople
{
protected string _Name;
public AbstarctPeople(string name)
{
this._Name = name;
}
public abstract void SpeakDialect();//说方言
}
然后分别实现BeiJingPeople和HeBeiPeople这两个类
public class BeiJingPeople : AbstarctPeople
{
public BeiJingPeople() : base("北京人")
{
}
public override void SpeakDialect()
{
Console.WriteLine($"{this._Name}说北京话");
}
}
public class HeBeiPeople : AbstarctPeople
{
public HeBeiPeople() : base("河北人")
{
}
public override void SpeakDialect()
{
Console.WriteLine($"{this._Name}说河北话");
}
}
以上两种对比可以看出,单一职责原则它的优点好处就是大大降低了类的复杂性,提高了可读性,维护性同时也降低了类变更时的风险性。但是这样拆分后造成代码量的增加。
所以 那究竟什么时候使用呢?
1.如果说类型足够的简单,方法够少,我们可以在类级别的去违背单一职责。
2.如果说类型足够复杂,方法足够多,建议遵守单一职责原则。
里氏替换原则:任何出现使用父类的地方,都可以透明的使用其子类,这里透明的意思就是安全的,不会出现不一致(子类完全拥有父类的所有属性和方法。)
下面一个例子说明:
MarineAnimal类作为父类,
Shark 类继承MarineAnimal类就就是遵守了里氏替换原则(MarineAnimal类里的属性方法可以完全被Shark 类继承);但是Starfish 类继承MarineAnimal类就违背了里氏替换原则(MarineAnimal类里的Swim方法不能被Starfish 继承,因为Starfish 海星是不会在水中游行的,无法完全透明的继承MarineAnimal类)
public class MarineAnimal//海洋动物
{
public int ID { get; set; }
public string Name { get; set; }
public void Swim()
{
Console.WriteLine("水中游行");
}
}
public class Shark : MarineAnimal//鲨鱼
{
public void Crawl()
{
Console.WriteLine("路地爬行");
}
}
public class Starfish : MarineAnimal//海星
{
}
根据上面例子我们总结:
1.父类有的,子类必须要有。
2.子类可以有自己的属性和方法
3.父类实现了的,子类最好不要再写了(就是不要new隐藏)如果非要修改父类的属性或者方法,就通过abstract/virtual
迪米特法则:又叫做最少知道原则,就是一个对象应该对其他的对象保持最少了解,不和陌生人说话,只与直接的朋友通信。
例如以下:Company类的Manage方法里它的直接朋友是Department类,但是Department类的Person类出现在了Company类与之有了关联关系,这样就违背了迪米特法则
public class Company
{
public int ID { get; set; }
public string Name { get; set; }
public List<Department> List { get; set; }
public void Manage()
{
Console.WriteLine($"Manage{this.GetType().Name}");
foreach (var item in List)
{
Console.WriteLine($"{item.GetType().Name}Manage{item.Name}");
List<Person> personList = item.List;
foreach (var p in personList)
{
Console.WriteLine($"{p.GetType().Name}Manage{p.Name}");
}
}
}
}
public class Department
{
public int ID { get; set; }
public string Name { get; set; }
public List<Person> List { get; set; }
}
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
}
如果将以上的代码拆开:不和陌生人关联,只与直接的朋友通信代码如下
public class Company
{
public int ID { get; set; }
public string Name { get; set; }
public List<Department> List { get; set; }
public void Manage()
{
Console.WriteLine($"Manage{this.GetType().Name}");
foreach (var item in List)
{
item.Manage();
}
}
}
public class Department
{
public int ID { get; set; }
public string Name { get; set; }
public List<Person> List { get; set; }
public void Manage()
{
Console.WriteLine($"{this.GetType().Name}Manage{this.Name}");
foreach (var item in List)
{
item.Manage();
}
}
}
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public void Manage()
{
Console.WriteLine($"{this.GetType().Name}Manage{this.Name}");
}
}
这样我们降低了类与类之间的关系,也就是高内聚,降低耦合依赖。
迪米特法则的缺点就是会多出大量跟业务逻辑无关,仅仅是中间传递关系的小方法
从迪米特法则的定义和特点可知,它强调以下两点:
1.从依赖者的角度来说,只依赖应该依赖的对象。
2.从被依赖者的角度说,只暴露应该暴露的方法。
所以,在运用迪米特法则时要注意以下 6 点。
在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标。
在类的结构设计上,尽量降低类成员的访问权限。
在类的设计上,优先考虑将一个类设置成不变类。
在对其他类的引用上,将引用其他对象的次数降到最低。
不暴露类的属性成员,而应该提供相应的访问器(set 和 get 方法)。
谨慎使用序列化(Serializable)功能。