C#知识点-19(七大设计原则、通过反射破坏单例设计模式、基于Task的异步编程模型、Winform中的异步)

通过反射,破坏单例设计模式

    internal class Program
    {
        static void Main(string[] args)
        {
            //懒汉式

            //for (int i = 0; i < 10; i++)
            //{
            //    Thread th = new Thread(() => {
            //        LazyManClass lazyManClass = LazyManClass.GetLazyMan();
            //    });
            //    th.Start();
            //}

            //通过反射,破解单例设计模式
            //Assembly(获取要反射的程序集DLL--->Class Method INterface Delegate Event。。。。) Type

            Type type = typeof(LazyManClass);

            ConstructorInfo[] ci = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
            //正常的调用静态方法创建对象
            //LazyManClass lazyManClass = LazyManClass.GetLazyMan();
            //ci[0]就是私有的构造函数
            //通过调用私有的构造函数,跳过判断,直接创建对象
            LazyManClass l1 = (LazyManClass)ci[0].Invoke(null);

            //在第二次创建对象之前,获取b的值,重新修改为false
            FieldInfo fi = type.GetField("b", BindingFlags.NonPublic | BindingFlags.Static);
            //修改字段的值
            //参数1:要修改的字段
            //参数2:修改后的值
            fi.SetValue(fi, false);
            LazyManClass l2 = (LazyManClass)ci[0].Invoke(null);
            fi.SetValue(fi, false);
            LazyManClass l3 = (LazyManClass)ci[0].Invoke(null);
            fi.SetValue(fi, false);
            LazyManClass l4 = (LazyManClass)ci[0].Invoke(null);

            Console.WriteLine(l1.GetHashCode());
            Console.WriteLine(l2.GetHashCode());
            Console.WriteLine(l3.GetHashCode());
            Console.WriteLine(l4.GetHashCode());

            Console.ReadKey();
        }
    }

    class LazyManClass
    {
        private LazyManClass()
        {
            if (b == false)
            {
                b = true;
            }
            else
            {
                throw new Exception("有人破坏单例设计模式!!!!!");
            }

            //if (_lazyManClass != null)
            //{
            //    throw new Exception("有人破坏单例设计模式!!!!!");
            //}
            Console.WriteLine("我被创建了一次");
        }

        private static LazyManClass _lazyManClass = null;
        private static object o = new object();
        private static bool b = false;

        public static LazyManClass GetLazyMan()
        {
            if (_lazyManClass == null)
            {
                lock (o)
                {
                    if (_lazyManClass == null)
                    {
                        return _lazyManClass = new LazyManClass();
                    }
                }
            }
            return _lazyManClass;
        }
    }

基于Task的异步编程模型

    internal class Program
    {
        static async Task Main(string[] args)
        {
            //以同步的方式,开发异步的代码
            //下载一个网页的数据---->写入到指定的路径下

            //异步会传染
            //异步方法的返回值类型必须放到Task<T>中 ,如果没有返回值,则写Task---->void    Task<int> int
            Console.WriteLine("Main函数调用异步方法之前的线程" + Thread.CurrentThread.ManagedThreadId);
            int r = await DownHTML_WriteFile("http://www.taobao.com", @"C:\Users\ThinkPad\Desktop\abcabc.txt");
            Console.WriteLine("Main函数调用异步方法之后的线程" + Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("数据的长度是{0}", r);

              Task 底层就是线程池
            //Task task = new Task(() =>
            //{
            //    Console.WriteLine("开始了一个任务");
            //});

            //task.ContinueWith((t) =>
            //{
            //    Console.WriteLine("我是任务1");
            //    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            //}).ContinueWith((t) =>
            //{
            //    Console.WriteLine("我是任务2");
            //    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            //}).ContinueWith((t) => {
            //    Console.WriteLine("我是任务3");
            //    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            //});

            //task.Start();


            //Task.Run(() =>
            //{
            //    Console.WriteLine("开始了一个任务");
            //});

            //Task.Factory.StartNew(() => {
            //    Console.WriteLine("开始了一个任务");
            //});


            //任务:I/O密集型  Input/OutPut------>写入一个文件   读取一个文件  读取一个数据  写入一个数据库 
            //任务:   计算密集型

            Console.ReadKey();
        }

        //Task:异步执行的任务
        //async 异步方法 [MehodImp(。。。。。sync....)]
        //await 等待异步方法执行后的结果
        static async Task<int> DownHTML_WriteFile(string url, string path)
        {

            //状态机设计模式
            WebClient wc = new WebClient();
            Console.WriteLine("开始异步任务1之前的线程是" + Thread.CurrentThread.ManagedThreadId);
            //DownloadStringTaskAsync :基于任务的异步方法
            Task<string> task = wc.DownloadStringTaskAsync(url);
            string htmlStr = await task;  //等待任务执行---->开启一个新线程----->等待任务的执行
            Console.WriteLine("开始异步任务1之后的线程是" + Thread.CurrentThread.ManagedThreadId);
            //Console.WriteLine(htmlStr);
            using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                byte[] buffer = Encoding.Default.GetBytes(htmlStr);
                Console.WriteLine("开始异步任务2之前的线程是" + Thread.CurrentThread.ManagedThreadId);
                //fsWrite.Write();同步方法
                await fsWrite.WriteAsync(buffer, 0, buffer.Length); //又开了一个新线程
                Console.WriteLine("开始异步任务2之后的线程是" + Thread.CurrentThread.ManagedThreadId);
            }



            //把数据的长度返回
            return htmlStr.Length;
        }
    }

Winform中的异步

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        //EventHandler   void object EventArgs

        //void:winform中事件的void,不许修改。可以标记为async,但是不能修改。
        private async void button1_Click(object sender, EventArgs e)
        {
            int n = await DownHTML_WriteFile("a", "b");
        }
        static async Task<int> DownHTML_WriteFile(string url, string path)
        {
            WebClient wc = new WebClient();
            Console.WriteLine("开始异步任务1之前的线程是" + Thread.CurrentThread.ManagedThreadId);
            //DownloadStringTaskAsync :基于任务的异步方法
            Task<string> task = wc.DownloadStringTaskAsync(url);
            string htmlStr = await task;  //等待任务执行---->开启一个新线程----->等待任务的执行
            Console.WriteLine("开始异步任务1之后的线程是" + Thread.CurrentThread.ManagedThreadId);
            //Console.WriteLine(htmlStr);
            using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                byte[] buffer = Encoding.Default.GetBytes(htmlStr);
                Console.WriteLine("开始异步任务2之前的线程是" + Thread.CurrentThread.ManagedThreadId);
                //fsWrite.Write();同步方法
                await fsWrite.WriteAsync(buffer, 0, buffer.Length); //又开了一个新线程
                Console.WriteLine("开始异步任务2之后的线程是" + Thread.CurrentThread.ManagedThreadId);
            }

            //把数据的长度返回
            return htmlStr.Length;
        }

    }

七大设计原则

单一职责原则

应该有且只有一个引起类变更的原因。一个类,只负责一件事

好处:

1、提高了代码的可读性,提高系统的可维护性

2、降低类的复杂性,一个模块只负责一个职责,提高系统的可扩展性和可维护性

3、降低变更引起的风险。变更时必然的,如果单一职责做的好,当修改一个功能的时候可以显著的降低对另一个功能的影响

{
    internal class Program
    {
        static void Main(string[] args)
        {
            //Dial
            //HangUp
            //SendMessage
            //ReciveMessage

            TelPhone tel = new TelPhone();
            tel.Dial = new DialClass(); //new DialMindClass();
            tel.Tel_Dial();
            Console.ReadKey();
        }
    }

    interface IDial
    {
        void Dial();
    }

    class DialClass:IDial
    {
        public void Dial()
        {
            Console.WriteLine("使用按键拨打电话");
            //使用意念拨打电话
        }
    }

    class DialMindClass:IDial
    {
        public void Dial()
        {
            Console.WriteLine("意念拨打电话");
        }
    }


    interface IHangUp
    {
        void HangUP();
    }

    class HangUpClass:IHangUp
    {
        public void HangUP()
        {
            Console.WriteLine("使用按键,挂断电话");
        }
    }

    interface ISendMessage
    {
        void SendMessage();
    }

    class SendClass: ISendMessage
    {
        public void SendMessage()
        {
            Console.WriteLine("发送短信");
        }
    }

    interface IRecMessage
    {
        void ResMsg();
    }

    class RecClass:IRecMessage
    {
        public void ResMsg()
        {
            Console.WriteLine("接收短信");
        }
    }

    class TelPhone   //引起类变更的原因,只有一个
    {
        //外部的变化:客观存在的。
        //内部的变化:
        //导入依赖
        //public DialClass Dial { get; set; }
        //public HangUpClass HangUP { get; set; }
        //public SendClass SendMessage { get; set; }
        //public RecClass RecMessage { get; set; }
        //public DialMindClass DialMind { get; set; }

        //面向接口编程------->面向抽象编程 ---->【封装变化】  --->最少的代码,写出最通用的功能  ---->高内聚、低耦合--->可扩展
        public IDial Dial { get; set; }
        public IHangUp HangUp { get; set; }
        public ISendMessage SendMessage { get; set; }
        public IRecMessage RecMessage { get; set; }

        //开闭原则:对扩展开放,对修改关闭
        public void Tel_Dial()
        {
            this.Dial.Dial();
        }
        public void Tel_HangUp()
        {
            this.HangUp.HangUP();
        }
        public void Tel_Send()
        {
            this.SendMessage.SendMessage();
        }
        public void Tel_Rec()
        {
            this.RecMessage.ResMsg();
        }

    }


}
开放封闭原则(OCP)

1、开放封闭原则是面向对象所有原则的核心

2、对功能扩展开放;对修改代码封闭

3、需求改变时,在不改变软件实体源代码(类、接口、方法等)的前提下,通过扩展功能,使其满足新的需求

使⽤代码,描述不同需求的⽤户去银⾏办理不同的业务

{
    internal class Program
    {
        static void Main(string[] args)
        {
            //不同需求的用户,去银行找柜员办理业务  银行处理系统

            Client client = new Client() { Purpose = "存钱" };
            BankStuff bankStuff = new BankStuff();
            BankProcess bankProcess = new BankProcess();
            bankStuff.BankProcess = bankProcess;

            bankStuff.ProcessClient(client);

            Console.ReadKey();
            

        }
    }

    //不同需求的用户
    class Client
    {
        public string Purpose { get; set; }
    }

    //银行柜员
    class BankStuff
    {
        public BankProcess BankProcess { get; set; }
        //调用银行处理系统,处理用户的需求
        public void ProcessClient(Client client)
        {
            //判断用户的需求
            //switch是一定不符合开闭的原则代码,你的程序中,只要出现了switch或者if elseif之类的多条件判断  OCP
            //shit Mountain  屎山
            switch (client.Purpose)
            {
                case "存钱":
                    this.BankProcess.CunMoney();
                    break;
                case "取钱":
                    this.BankProcess.QuMoney();
                    break;
                default:
                    Console.WriteLine("无法处理您的需求");
                    break;
            }
        }
    }


    //银行处理系统
    class BankProcess
    {
        public void CunMoney()
        {
            Console.WriteLine("处理存钱");
        }
        public void QuMoney()
        {
            Console.WriteLine("处理取钱");
        }
    }

}

银行办理业务2.0

{
    internal class Program
    {
        static void Main(string[] args)
        {
            Client c = new Client() { Purpose = "取钱" };
            BankStuff bankStuff = new BankStuff();
            BankProcess bankProcess = new BankProcess();
            bankStuff.BankProcess = bankProcess;
            bankStuff.ProcessClient(c);
            Console.ReadKey();
        }
    }


    //不同需求的用户
    class Client
    {
        public string Purpose { get; set; }
    }

    class BankStuff
    {
        public BankProcess BankProcess { get; set; }
        //调用银行处理系统,处理用户的需求
        public void ProcessClient(Client client)
        {
            //判断用户的需求
            //switch是一定不符合开闭的原则代码,你的程序中,只要出现了switch或者if elseif之类的多条件判断  OCP
            //shit Mountain  屎山
            switch (client.Purpose)
            {
                case "存钱":
                    //this.BankProcess.CunMoney();
                    this.BankProcess.CunMoney = new CunClass();
                    this.BankProcess.Cun();
                    break;
                case "取钱":
                    this.BankProcess.QuMoney = new QuClass();
                    this.BankProcess.Qu();
                    //this.BankProcess.QuMoney();
                    break;
                default:
                    Console.WriteLine("无法处理您的需求");
                    break;
            }
        }
    }


    interface ICunMoney
    {
        void CunMoney();
    }
    class CunClass : ICunMoney
    {
        public void CunMoney()
        {
            Console.WriteLine("处理存钱");
        }
    }
    interface IQuMoeny
    {
        void QuMoney();
    }
    class QuClass : IQuMoeny
    {
        public void QuMoney()
        {
            Console.WriteLine("处理取钱");
        }
    }

    interface IBuyJJ
    {
        void BuyJJ();
    }
    class BuyClass: IBuyJJ
    {
        public void BuyJJ()
        {
            Console.WriteLine("买基金");
        }
    }
    class BankProcess
    {
        public ICunMoney CunMoney { get; set; }
        public IQuMoeny QuMoney { get; set; }
        public IBuyJJ BuyJJ { get; set; }

        public void Cun()
        {
            this.CunMoney.CunMoney();
        }

        public void Qu()
        {
            this.QuMoney.QuMoney();
        }

        public void Buy()
        {
            this.BuyJJ.BuyJJ();
        }
    }




}
依赖倒置原则

开放封闭原则是面向对象设计的终极目标,而依赖倒置原则是实现开放封闭原则的基础

如果开放封闭原则是设计大楼的蓝图,那么依赖倒置原则就是大楼的钢铁架构

1、高层模块(调用者)不应该依赖于低层模块(被调用者),两个都应该依赖于抽象

2、抽象不应该依赖细节,细节应该依赖于抽象

3、依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独立,互不影响,实现模块间的松耦合

{
    internal class Program
    {
        static void Main(string[] args)
        {
            //歌手歌唱不同国家的歌曲

            Singer singer = new Singer();
            singer.SingingChinese(new ChineseSong());
            singer.SingingChinese(new JapanSong());

            Console.ReadKey();
        }
    }

    interface ISong
    {
        string SingingASong();
    }


    class ChineseSong:ISong
    {
        public string SingingASong()
        {
            return "中国歌曲";
        }
    }
    class KoreaSong:ISong
    {
        public string SingingASong()
        {
            return "思密达";
        }
    }
    class JapanSong:ISong
    {
        public string SingingASong()
        {
            return "aligaduo";
        }
    }

    class Singer  //调用者
    {
        //调用者和被调用者,强耦合----->
        //使用抽象【接口/抽象类】封装变化

        //抽象不应该依赖细节,细节应该依赖于抽象   面向抽象编程
        public void SingingChinese(ISong cs) //被调用者
        {
            Console.WriteLine("正在唱"+cs.SingingASong());
        }

      //  通过抽象,使各个模块或者类的实现彼此独立,互不影响,实现模块间的松耦合



    }



}

关于依赖:

1、一个优秀的面向对象程序设计,核心的原则之一就是将变化隔离(封装),使变化部分发生变化时,其他部分不受影响

2、为了实现这个目的,需要使用面向接口编程。使用后,客户类不再直接依赖于服务类,而是依赖一个抽象的接口。这样,客户类就不能在内部直接实例化服务类

3、但是客户类在运行的过程中,又需要具体的服务类来提供服务,因为接口是不能实例化的,就产生了一个矛盾:客户类不允许实例化服务类,但是客户类又需要服务类的服务

4、为了解决这个矛盾,我们设计了一种解决方案,既:客户类注定义一个注入点,用于服务类的注入,而客户类的客户类(Program类)负责根据情况,实例化服务类,注入到客户类中,从而解决了这个矛盾

依赖关系如何传递?(依赖注入)

1、通过接口传递(接口注入)

2、通过构造方法传递

3、通过属性的Set方法传递

里氏替换原则

1、如果S是T的子类型,则T类型的对象可以替换为S类型的对象

2、所有引用父类对象的地方,都可以使用其子类型代替

3、子类可以替换父类

接口分离原则

1、客户端不应该依赖它不需要的接口

2、一个类对另一个类的依赖应该建立在最小接口上

3、接口尽量细分,不要在一个接口中放很多方法

{
    internal class Program
    {
        static void Main(string[] args)
        {
        }
    }

    interface IScore
    {
       

        //修改某个学生的成绩
        void ChangeScore();

        //void Login();

    }

    //1、接口要符合高内聚
    //2、接口要符合单一职责原则
    //3、还要考虑实现类权限的问题,对接口中的方法进行分类细分。

    interface ISuperScore
    {
        //添加某个学生的成绩
        void AddScore();

        //删除某个学生的成绩
        void DeleteScore();
    }

    interface IQueryScore
    {
        void QueryScore();
    }





    class Teacher : IScore,IQueryScore
    {
        public void AddScore()
        {
            throw new NotImplementedException();
        }

        public void ChangeScore()
        {
            throw new NotImplementedException();
        }

        public void DeleteScore()
        {
            throw new NotImplementedException();
        }

        public void QueryScore()
        {
            throw new NotImplementedException();
        }
    }

    class Student : IQueryScore
    {
        public void QueryScore()
        {
            throw new NotImplementedException();
        }
    }
}
迪米特原则(最小知识原则)

1、它要求一个对象应该对其他对象有最少的了解

2、降低类之间的耦合

3、迪米特原则实际上就是一个类在创建方法和属性时要遵守的原则(只和直接朋友通信)

直接朋友:

1、成员对象

2、方法参数

3、方法返回值

4、注意:出现在局部变量中的类,不是直接朋友

{
    internal class Program
    {
        static void Main(string[] args)
        {
            //总公司员工类 :ID
            //总公司员工管理类
            //1、添加总公司员工
            //2、打印总公司每个员工
            //3、打印分公司每个员工
            //分公司员工类 :ID
            //分公司员工管理类
            //1、添加分公司员工


            HeadEmployeeManager headEmployeeManager = new HeadEmployeeManager();
            headEmployeeManager.PrintEmployees();
            Console.ReadKey();
        }
    }

    //总公司员工类 天高皇帝远
    class HeadEmployee
    {
        public int ID { get; set; }
    }

    //总公司员工管理类
    //谁是HeadEmployeeManager的直接朋友
    //成员对象  方法的参数类型  方法的返回值类型

    //List<HeadEmployee> listHeadEmployee  直接朋友
    //List<HeadEmployee> 直接朋友
    //BodyEmployeeManager bodyEmployeeManager  不是直接朋友
    //  List<BodyEmployee> listBodyEmployees  不是直接朋友
    class HeadEmployeeManager
    {
        //总公司员工集合
        private List<HeadEmployee> listHeadEmployee = new List<HeadEmployee>();
        //添加总公司员工
        public List<HeadEmployee> AddHeadEmployees()
        {
            for (int i = 0; i < 10; i++)
            {
                listHeadEmployee.Add(new HeadEmployee() { ID = i + 1 });
            }
            return listHeadEmployee;
        }
        //打印总公司员工和分公司员工
        public void PrintEmployees()
        {
            this.AddHeadEmployees();
            Console.WriteLine("==========================以下是总公司员工ID=====================================================");
            //打印总公司员工
            for (int i = 0; i < listHeadEmployee.Count; i++)
            {
                Console.WriteLine(listHeadEmployee[i].ID);
            }
            Console.WriteLine("==========================以下是分公司员工ID=====================================================");
            //3、打印分公司每个员工
            //3.1 创建分公司员工管理类的对象
            BodyEmployeeManager bodyEmployeeManager = new BodyEmployeeManager();
            //3.2 调用AddBodyEmployee添加分公司成员,并获取返回值
            List<BodyEmployee> listBodyEmployees = bodyEmployeeManager.AddBodyEmployees();
            //3.3 循环分公司员工的集合
            for (int i = 0; i < listBodyEmployees.Count; i++)
            {
                Console.WriteLine(listBodyEmployees[i].ID);
            }

        }
    }

    class BodyEmployee
    {
        public int ID { get; set; }
    }

    class BodyEmployeeManager
    {
        private List<BodyEmployee> listBodyEmployee = new List<BodyEmployee>();

        public List<BodyEmployee> AddBodyEmployees()
        {
            for (int i = 0; i < 5; i++)
            {
                listBodyEmployee.Add(new BodyEmployee() { ID = i + 1 });
            }
            return listBodyEmployee;
        }
    }


}
合成复用原则

1、合成复用原则,又称组合\聚合复用原则

2、尽量使用对象组合,而不是继承来达到复用

3、继承的问题:a、破坏了系统的封装性,基类发生了变化,子类的实现也会发生变化

b、继承是静态的,不能在程序运行时发生变化

4、合成复用原则是将已有的对象纳入到新对象中,作为新对象的对象成员来实现的,新对象可以调用已有对象的功能,从而达到复用

类与类之间的关系:泛化、实现、组合、聚合、关联、依赖

泛化:Animal是Tiger的泛化,Tiger是Animal的特化

实现:类与接⼝的关系,表示类实现了接口

组合:组合是整体和部分的关系,部分没有独⽴的⽣命周期,组合是把部分作为整体类的对象

聚合:聚合也是整体与部分的关系,但是个体有独⽴的⽣命周期,聚合是把个体对象的指针(引⽤)作为整体类的属性

关联:关联是⼀种拥有关系,它使⼀个类知道另⼀个类的属性和⽅法。

依赖:依赖是一种使用关系

类与类之间的关系
{
    internal class Program
    {
        static void Main(string[] args)
        {
        }
    }
    class Animal //泛化
    {
        public char Gender { get; set; }

        public void Eat()
        {
            Console.WriteLine("动物都能吃");
        }
        public void Sleep()
        {
            Console.WriteLine("动物都能睡觉");
        }
    }

    class Tiger:Animal ,IClimb //特化
    {
        //Tiger和Leg是组合关系,强拥有关系,两个对象的生命周期必须是一样的。

        public Leg Legs { get; set; }
        //在老虎的构造函数中,传入Leg的对象,表示Tiger跟Leg同时出生。
        public Tiger(Leg leg)
        {
            this.Legs = leg;
        }

        //属性注入、构造注入、传参注入
        //关联
        public Food Food { get; set; }

        //依赖
        public Water Water { get; set; }

        public string Name { get; set; }

        public void Climb()
        {
            Console.WriteLine("老虎会爬树");
        }
    }

    class Food
    {
        public string Name { get; set; }
        public string Color { get; set; }
    }
    class Water
    {
        public double Weight { get; set; }
    }

    class TigerGroup
    {
        //聚合关系
        public Tiger[] Tigers { get; set; }
    }

    class Leg
    {
        public int Count { get; set; }
    }

    interface IClimb
    {
        void Climb();
    }
}

合成复用原则
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //继承问题:
            //1、可能会造成子类功能泛滥
            //2、可能会造成子类数量爆炸
            //3、打破了类的封装性   //sealed   B:A   


            //创建油车对象
            YouCar youCar = new YouCar(new Blue());
            youCar.Move();
            Console.ReadKey();
        }
    }

    interface IColor
    {
        string GetColor();
    }

    class White : IColor
    {
        public string GetColor()
        {
            return "白色";
        }
    }

    class Red : IColor
    {
        public string GetColor()
        {
            return "红色";
        }
    }

    class Blue : IColor
    {
        public string GetColor()
        {
            return "蓝色";
        }
    }

    abstract class Car
    {
        public IColor Color { get; set; }
        public Car(IColor color) //组合,强拥有关系
        {
            this.Color = color;
        }

        public abstract void Move();
    }


    class DianCar : Car
    {
        public DianCar(IColor color) : base(color)
        { }

        public override void Move()
        {
            //是什么颜色的电动汽车在跑
            Console.WriteLine(this.Color.GetColor() + "的电动汽车,工业垃圾,在用电奔跑");  //发动机、底盘、变速箱
        }
    }

    class YouCar : Car
    {
        public YouCar(IColor color) : base(color)
        { }

        public override void Move()
        {
            //是什么颜色的电动汽车在跑
            Console.WriteLine(this.Color.GetColor() + "汽油车再用油奔跑");  //发动机、底盘、变速箱
        }
    }


}

设计原则总结

1、设计原则是「高内聚、低耦合」的具体落地。

2、单一职责原则要求在软件系统开发、设计中,一个类只负责一个功能领域的相关职责。

3、开放封闭原则要求一个软件应该对扩展开放,对修改封闭,即在不修改源代码的情况下,完成系统功能的扩展。

4、里式替换原则决定了子类可以赋值给父类,

5、依赖倒置原则要求抽象不应该依赖于细节,细节应该依赖于抽象。要面向接口编程,不要面向实现编程。

6、迪米特原则要求一个对象尽可能少的与其他对象发生相互作用。

7、接口隔离原则要求客户端不应该依赖那些他不需要的接口,即将一些大的接口细化成一些小的接口供客户端使用。

8、合成复用原则要求我们尽量使用对象的组合,而非继承来达到复用的目标。

相关推荐
马剑威(威哥爱编程)7 小时前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
gjh12087 小时前
单例模式和适配器模式的简单介绍
单例模式·适配器模式
无尽的大道1 天前
单例模式详解:如何优雅地实现线程安全的单例
单例模式
Hello.Reader2 天前
单例模式全面解析
单例模式
编程修仙2 天前
java的单例设计模式
java·单例模式·设计模式
L_cl3 天前
Python学习从0到1 day27 Python 高阶技巧 ③ 设计模式 — 单例模式
学习·单例模式·设计模式
ktkiko114 天前
Java中的设计模式——单例模式、代理模式、适配器模式
java·单例模式·设计模式
傻傻虎虎5 天前
【真题笔记】21年系统架构设计师案例理论点总结
单例模式·系统架构·uml·命令模式
Mr. zhihao5 天前
享元模式及其运用场景:结合工厂模式和单例模式优化内存使用
单例模式·享元模式
南城花随雪。6 天前
Spring框架之单例模式 (Singleton Pattern)
java·spring·单例模式