zoukankan      html  css  js  c++  java
  • 《你必须知道的.NET》读书笔记二:小OO有大原则

    此篇已收录至《你必须知道的.Net》读书笔记目录贴,点击访问该目录可以获取更多内容。

    一、单一职责原则

      (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因

      (2)常用模式:Facade模式、Proxy模式

      (3)基本方法:Extract Interface 抽取接口、Extract Class 抽取类、Extract Method 抽取方法

      (4)DEMO:数据库管理系统中根据不同权限进行CRUD操作(这里是使用Proxy模式重构后的代码)

        public interface IDBAction
        {
            void Add();
            bool Delete();
            void View();
        }
    
        public class DBManager : IDBAction
        {
            public DBManager(string id)
            {
            }
    
            public void Add()
            {
                //执行数据增加
                Console.WriteLine("增加数据成功。");
            }
    
            public bool Delete()
            {
                //执行数据删除
                return true;
            }
    
            public void View()
            {
                //执行数据查看
            }
        }
    
        public class DBManagerProxy : IDBAction
        {
            private string id;
            private IDBAction dbManager;
    
            public DBManagerProxy(IDBAction dbAction)
            {
                dbManager = dbAction;
            }
    
            //处理权限判断的逻辑
            public string GetPermission(string id)
            {
                return null;
                //return "CanAdd";
            }
    
            public void Add()
            {
                if (GetPermission(id) == "CanAdd")
                {
                    dbManager.Add();
                }
            }
    
            public bool Delete()
            {
                if (GetPermission(id) == "CanDelete")
                {
                    dbManager.Delete();
                }
    
                return true;
            }
    
            public void View()
            {
                if (GetPermission(id) == "View")
                {
                    dbManager.View();
                }
            }
        }
    
        public class DBClient
        {
            public static void Main()
            {
                IDBAction DBManager = new DBManagerProxy(new DBManager("CanAdd"));
                DBManager.Add();
            }
        }
    View Code

      (5)规则建议:

        ①一个类只有一个引起它变化的原因,否则就应当考虑重构;

        ②测试驱动开发,有助于实现合理分离功能的设计;

        ③可以通过Facade模式或Proxy模式进行职责分离

    二、开放封闭原则  

      (1)核心思想:软件实体应该是可扩展的,而不可修改的-->即对扩展开放,对修改封闭。在面向对象的编程中,即对抽象编程,而不对具体编程

      (2)常用模式:Template Method模式、Strategy模式

      (3)DEMO:银行窗口业务办理场景

        class Client
        {
            private string ClientType;
    
            public Client(string clientType)
            {
                ClientType = clientType;
            }
    
            public IBankProcess CreateProcess()
            {
                //实际的处理
                switch (ClientType)
                {
                    case "存款用户":
                        return new DepositProcess();
                        break;
                    case "转帐用户":
                        return new TransferProcess();
                        break;
                    case "取款用户":
                        return new DrawMoneyProcess();
                        break;
                }
                return null;
            }
        }
    
        interface IBankProcess
        {
            void Process();
        }
    
        //按银行按业务进行分类
        class DepositProcess : IBankProcess
        {
            public void Process()
            {
                //办理存款业务
                Console.WriteLine("处理存款。");
            }
        }
    
        class TransferProcess : IBankProcess
        {
            public void Process()
            {
                //办理转帐业务
                Console.WriteLine("处理转帐。");
            }
        }
    
        class DrawMoneyProcess : IBankProcess
        {
            public void Process()
            {
                //办理取款业务
            }
        }
    
        class FundProcess : IBankProcess
        {
            public void Process()
            {
                //办理基金业务
            }
        }
    
        class EasyBankStaff
        {
            private IBankProcess bankProc = null;
    
            public void HandleProcess(Client client)
            {
                //业务处理
                bankProc = client.CreateProcess();
                bankProc.Process();
            }
        }
    
        class BankProcess
        {
            public static void Main()
            {
                EasyBankStaff bankStaff = new EasyBankStaff();
                bankStaff.HandleProcess(new Client("转帐用户"));
            }
        }
    View Code

      (4)规则建议:

        ①Liskov替换原则和合成/聚合复用原则为OCP实现提供保证;

        ②可以通过Template Method和Strategy模式进行重构;

        ③封装变化是实现OCP的重要手段;

    三、依赖倒置原则

      (1)核心思想:依赖于抽象-->抽象不应该依赖于具体,具体应该依赖于抽象;

      (2)基本方法:在依赖之间定义一个抽象的接口,高层模块调用接口的方法,低层模块实现接口的定义;

      (3)DEMO:银行窗口不同业务客户场景

        interface IClient
        {
            IBankProcess CreateProcess();
        }
    
        class DepositClient : IClient
        {
            IBankProcess IClient.CreateProcess()
            {
                return new DepositProcess();
            }
        }
    
        class TransferClient : IClient
        {
            IBankProcess IClient.CreateProcess()
            {
                return new TransferProcess();
            }
        }
    
        class DrawMoneyClient : IClient
        {
            IBankProcess IClient.CreateProcess()
            {
                return new DrawMoneyProcess();
            }
        }
    
        class FundClient : IClient
        {
            IBankProcess IClient.CreateProcess()
            {
                return new FundProcess();
            }
        }
    
        interface IBankProcess
        {
            void Process();
        }
    
        //按银行按业务进行分类
        class DepositProcess : IBankProcess
        {
            public void Process()
            {
                //办理存款业务
                Console.WriteLine("处理存款。");
            }
        }
    
        class TransferProcess : IBankProcess
        {
            public void Process()
            {
                //办理转帐业务
                Console.WriteLine("处理转帐。");
            }
        }
    
        class DrawMoneyProcess : IBankProcess
        {
            public void Process()
            {
                //办理取款业务
            }
        }
    
        class FundProcess : IBankProcess
        {
            public void Process()
            {
                //办理基金业务
            }
        }
    
        class EasyBankStaff
        {
            private IBankProcess bankProc = null;
    
            public void HandleProcess(IClient client)
            {
                //业务处理
                bankProc = client.CreateProcess();
                bankProc.Process();
            }
        }
    
        class BankProcess
        {
            public static void Main()//Main_2_4_1
            {
                EasyBankStaff bankStaff = new EasyBankStaff();
                bankStaff.HandleProcess(new TransferClient());
            }
        }
    View Code

      (4)规则建议:

        ①必须权衡在抽象和具体之间的取舍,方法不是一成不变的;

        ②依赖于抽象就是要对接口编程,不要对实现编程

    四、接口隔离原则

      (1)核心思想:使用多个小的专门的接口,而不使用一个大的总接口;接口应该是内聚的,应该避免出现“胖”接口;不要强迫依赖不用的方法,这是一种接口污染;

      (2)基本方法:委托分离与多重继承分离(推荐)

      (3)DEMO:不同年龄段人士使用电脑场景

        interface IComputerLearn
        {
            void ToLearn();
        }
    
        interface IComputerWork
        {
            void ToWork();
        }
    
        interface IComputerBeFun
        {
            void ToBeFun();
        }
    
        class Adult
        {
            private IComputerLearn myLearn;
            private IComputerWork myWork;
            private IComputerBeFun myFun;
    
            public void UseComputer()
            {
                //主要是工作
                myWork.ToWork();
                //还可以娱乐
                myFun.ToBeFun();
            }
        }
    
        class Child
        {
            private IComputerLearn myLearn;
    
            public void UseComputer()
            {
                //只有学习,不会依赖其他的方法
                myLearn.ToLearn();
            }
        }
    View Code

      (4)规则建议:

        ①将功能相近的接口合并,可能造成接口污染;

        ②接口隔离能够保证系统扩展和修改的影响不会扩展到系统其他部分;

    五、Liskov替换原则

      (1)核心思想:子类必须能够替换其基类

      (2)DEMO:父类提供虚函数,子类覆写虚函数

        class FatherClass
        {
            public virtual void Method()
            {
                //父类的行为
                Console.WriteLine("Father Method.");
            }
        }
    
        class SonClass : FatherClass
        {
            public override void Method()
            {
                //子类的行为
                Console.WriteLine("Son Method.");
            }
        }
    
        class GrandsonClass : SonClass
        {
            public override void Method()
            {
                Console.WriteLine("Grandson Method.");
            }
        }
    
        class Test_LSP
        {
            public static void DoSomething(FatherClass f)
            {
                f.Method();
            }
    
            public static void Main_2_6_2()//Main_2_6_2
            {
                DoSomething(new SonClass());
                SonClass son = new SonClass();
                FatherClass father = son is FatherClass ? (FatherClass)son : null;
                father.Method();
    
                FatherClass f2 = new FatherClass();
                SonClass son2 = f2 is SonClass ? (SonClass)f2 : null;
                son2.Method();
    
            }
        }
    View Code

      (3)规则建议:

        ①违反了Liskov替换原则必然导致违反开放封闭原则;

        ②Liskov替换能够保证系统具有良好的扩展性;

        ③子类的异常必须控制在父类可以预计的范围,否则将导致替换违规;

    本章思维导图

  • 相关阅读:
    产品经理的职责有哪些?到底该做什么?(转) 写的非常好,非常专业
    互联网界产品经理和项目经理(转) 总结的非常好
    各式结构化数据 动态 接入-存储-查询 的处理办法 (第二部分)
    各式结构化数据 动态 接入-存储-查询 的处理办法 (第一部分)
    不规矩的xml与JAVA对象互相转换的小技巧-使用Marshaller
    大数据架构-使用HBase和Solr将存储与索引放在不同的机器上
    小程序项目别的页面初始化拿到的值为两种状态(已解决)
    vue项目引入第三方js插件,单个js文件引入成功,使用该插件方法时报错(问题已解决)
    qs.stringify和JSON.stringify的使用和区别
    百度地图API-javascript-web地图的应用
  • 原文地址:https://www.cnblogs.com/edisonchou/p/3751874.html
Copyright © 2011-2022 走看看