设计模式的六大原则
1、依赖倒置原则
/// <summary>
/// 高层模块不应该依赖底层模块
/// 二者都应该依赖其抽象
/// </summary>
public class Student
{
public int Age { get; set; }
public string Name { get; set; }
public double Scores { get; set; }
public void GetAge()
{
Age = 18;
Console.WriteLine(Age);
}
/// <summary>
/// 假如要增加一个GetName方法,你在原有的类上增加,
/// 你这个看起来简单,你觉得自己能hold住,实际上,牵一发而动全身
/// 真正已经运行的程序,你添加新的功能可能会出问题
/// </summary>
public void GetName()
{
Name = "张三";
Console.WriteLine(Name);
}
}
/// <summary>
/// 最好的解决方案就是增加一个接口
/// </summary>
public interface IStudent
{
void GetName();
}
public class StudentExtend : IStudent
{
public int Age { get; set; }
public string Name { get; set; }
public double Scores { get; set; }
public void GetAge()
{
Age = 18;
Console.WriteLine(Age);
}
public void GetName()
{
Name = "张三";
Console.WriteLine(Name);
}
}
依赖倒置原则:依赖倒置原则是SOLID设计原则中的"D",它建议代码应该依赖于抽象(接口或抽象类),而不是具体的实现。这样做可以降低模块间的耦合度,提高代码的灵活性和可扩展性。
原始 Student 类:在原始的 Student 类中,GetAge 和 GetName 方法是直接在这个类中实现的。如果这个类已经被许多客户端代码使用,那么在未来对它的任何更改都可能影响到这些客户端。
添加接口 IStudent:通过定义一个接口 IStudent 并包含 GetName 方法,您创建了一个抽象层。这个接口可以被不同的类实现,而不影响现有的客户端代码。
扩展 StudentExtend 类:StudentExtend 类实现了 IStudent 接口,这意味着它提供了接口中定义的方法的具体实现。这样,如果未来需要添加更多方法,您可以在不修改原始 Student 类的情况下进行。
解耦和灵活性:使用接口作为中介,StudentExtend 类的实现与使用它的客户端代码解耦。客户端代码只需要知道 IStudent 接口,而不需要知道具体的实现类。这使得更换或扩展实现变得更加容易。
开闭原则:通过依赖接口,您的设计遵循了开闭原则,即软件实体应对扩展开放,对修改封闭。这意味着您可以在不改变现有代码的基础上增加新功能。
实际应用:在实际的应用程序中,如果需要对 Student 类添加新的行为,您可以通过定义新的接口和实现这些接口的类来扩展功能,而不影响现有的使用 Student 类的代码。
2、接口隔离原则
/// <summary>
/// 接口隔离原则有点像单一职责,但是还是要防止封装过度
/// </summary>
public interface IPhone
{
void GetNumber();// 获取电话号码
void SendContent();//发送短信
void Call(); //打电话
void PlayGame();//打游戏
}
public class Phone : IPhone
{
public void GetNumber()
{
Console.WriteLine("获取电话号码");
}
public void SendContent()
{
Console.WriteLine("发送短信");
}
public void Call()
{
Console.WriteLine("打电话");
}
public void PlayGame()
{
Console.WriteLine("打游戏");
}
}
/// <summary>
/// 如果只有一部需要打电话、发送短信的老年机,毕竟老年人不玩游戏,这个时候,接口应该隔离
/// </summary>
public interface IPhoneExtend1
{
void SendContent();//发送短信
void Call(); //打电话
}
public interface IPhoneExtend2
{
void GetNumber();// 获取电话号码
void PlayGame();//打游戏
}
/// <summary>
/// 老年手机
/// </summary>
public class Phone1 : IPhoneExtend1
{
public void SendContent()
{
Console.WriteLine("发送短信");
}
public void Call()
{
Console.WriteLine("打电话");
}
}
/// <summary>
/// 学生手机
/// </summary>
public class Phone2 : IPhoneExtend1,IPhoneExtend2
{
public void GetNumber()
{
Console.WriteLine("获取电话号码");
}
public void SendContent()
{
Console.WriteLine("发送短信");
}
public void Call()
{
Console.WriteLine("打电话");
}
public void PlayGame()
{
Console.WriteLine("打游戏");
}
}
3、迪米特原则
/// <summary>
/// 迪米特原则,最少知道原则
/// 团队的组长知道项目进度
/// 老板也要知道项目进度
/// 项目进度组长直接告诉老板就行
/// 所以正确的写法应当是项目进度的类暴露给团队组长
/// 再由团队组长告知老板,项目进度这个类不需要出现在老板的类中
/// </summary>
public class Sample {
public static void GetProcess() {
Boss boss = new Boss();
TeamLeader teamLeader = new TeamLeader();
boss.CommandTeamLeader(teamLeader);
}
}
public class Boss{
public void CommandTeamLeader(TeamLeader teamLeader) {
// teamLeader.sayProccess(new Program());
teamLeader.SayProccess();
}
}
public class TeamLeader{
//void sayProccess(Program program) {
// program.getProccess();
//}
public void SayProccess() {
new Program().GetProccess();
}
}
public class Program{
public void GetProccess() {
Console.WriteLine("当前的项目进度为 50%");
}
}
4、里氏替换原则
/// <summary>
/// 1、现在学生类只有一个方法,获取学生成绩
/// 2、现在进行扩展,添加一个功能,
/// 3、我们只需要获取理科成绩
/// </summary>
public class Student
{
public int Age { get; set; }
public string Name { get; set; }
public double Scores { get; set; }
/// <summary>
/// 获取学生成绩
/// </summary>
/// <returns></returns>
public double GetScores()
{
return Scores;
}
//获取理科成绩
public double GetScienceScore()
{
return Scores;
}
}
/// <summary>
/// 现在扩展一个功能,由子类完成
/// 这个功能在原来的GetScores上添加
/// 那么,这个扩展的方法可能导致原有的方法发生故障
/// 解决方法,尽量不要重载、重写父类方法
/// </summary>
public class StudentExtend : Student
{
public double NewScores()
{
return default;
}
}
/// <summary>
/// 理科
/// </summary>
public class ScienceStudent : Student
{
public double GetScienceScore()
{
return Scores;
}
}
/// <summary>
/// 文科
/// </summary>
public class VincoStudent : Student
{
public double GetVincoScore()
{
return Scores;
}
}
5、开闭原则
public interface IStudent
{
void GetStudent();
}
public class Student:IStudent
{
public void GetStudent()
{
}
}
///简单来说就是对扩展开放,对修改关闭
IStudent stu=new Student();
stu.GetStudent();
//你可以重新写一个类去实现IStudent,而不要去修改IStudent和Student
6、单一职责原则
/// <summary>
/// 一个类只负责一项职责,就一个类而言,只有一个引起它变化的原因
/// </summary>
public class Sample
{
/// <summary>
/// 简单来说就是各司其职
/// 不要让一个类有太多的功能
/// 多写一个抽象类分离出去
/// 使用继承去分门别类
/// </summary>
public class Student
{
public int Age { get; set; }
public string Name { get; set; }
public double Scores { get; set; }
public Student()
{
}
/// <summary>
/// 获取学生成绩
/// </summary>
/// <returns></returns>
public double GetScores()
{
return Scores;
}
}
}