设计模式的六大原则

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;
        }
    }
    
}
posted @ 2024-07-02 09:05  孤沉  阅读(5)  评论(0编辑  收藏  举报