• 面向对象设计原则


    单一职责原则(SRP, Single Responsibility Principle)

    定义

    一个类,最好只做一件事,只有一个引起它变化的原因。

    应用

    数据库管理系统为例,通常情况下根据不同的权限进行数据增删改查。
    比较坏的设计将判断用户权限和对数据的增删改查放在一个类,在遇到权限或对数据操作修改时都需要修改该类

    	public void Add()
    		{
    			if (GetPermission("userId")=="CanAdd")
    			{
    				Console.WriteLine("我有权限添加数据");
    			}
    		}
    

    考虑单一责任原则,将权限判断和对数据操作分到不同的类,通过权限代理实现单一职责

        public interface IDBAction
    	{
    		void Add();
    	}
    	public class DBManager: IDBAction
    	{
    		public void Add()
    		{
    			//执行数据增加
    		}
    	}
    
    	public class DBManagerProxy : IDBAction
    	{
    		private IDBAction dbManager;
    		public DBManagerProxy(IDBAction dbAction)
    		{
    			dbManager = dbAction;
    		}
    
    		public string GetPermission(string userId)
    		{
    			string userRole = string.Empty;
    			return userRole;
    		}
    
    		public void Add()
    		{
    			if (GetPermission("userId") == "CanAdd")
    			{
    				dbManager.Add();
    			}
    		}
    	}
    

    开放封闭原则(OCP, Open Closed Principle)

    定义

    软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开发的,而对修改是封闭的。

    应用

    这里实现个计算器,由客户端和计算端组成。设计应该尽量保证计算端的核心业务不修改。坏的代码无法对功能扩展

    	public class Client
    	{
    		private CalculatorProcess _calculator = new CalculatorProcess();
    
    		public int NumFirst { get; set; }
    		public int NumSecond { get; set; }
    		public int Use(string oper)
    		{
    			int ret = 0;
    			switch (oper)
    			{
    				case "+":
    					ret = _calculator.Add(this.NumFirst, this.NumSecond);
    					break;
    				case "-":
    					ret = _calculator.Sbu(this.NumFirst, this.NumSecond);
    					break;
    				default:
    					break;
    			}
    
    			return ret;
    		}
    	}
    
    	public class CalculatorProcess
    	{
    		public int Add(int a,int b)
    		{
    			return a + b;
    		}
    
    		public int Sbu(int a,int b)
    		{
    			return a - b;
    		}
    	}
    

    对计算端扩展开放,添加乘法

    public class Client
    	{
    		private ICalculatorProcess _calculator;
    
    		public int NumFirst { get; set; }
    		public int NumSecond { get; set; }
    		public int Use(string oper)
    		{
    			int ret = 0;
    			switch (oper)
    			{
    				case "+":
    					_calculator = new Add();
    					ret = _calculator.Operation(this.NumFirst, this.NumSecond);
    					break;
    				case "-":
    					_calculator = new Sub();
    					ret = _calculator.Operation(this.NumFirst, this.NumSecond);
    					break;
    				case "*":
    					_calculator = new Mul();
    					ret = _calculator.Operation(this.NumFirst, this.NumSecond);
    					break;
    				default:
    					break;
    			}
    			return ret;
    		}
    	}
    
    	public interface ICalculatorProcess
    	{
    		int Operation(int a, int b);
    	}
    
    	public class Add : ICalculatorProcess
    	{
    		public int Operation(int a, int b)
    		{
    			return a + b;
    		}
    	}
    
    	public class Sub : ICalculatorProcess
    	{
    		public int Operation(int a, int b)
    		{
    			return a - b;
    		}
    	}
    
    	public class Mul:ICalculatorProcess
    	{
    		public int Operation(int a, int b)
    		{
    			return a * b;
    		}
    	}
    

    依赖倒置原则(DIP, Dependency Inversion Principle)

    定义

    • 高层模块不应该依赖于底层模块,二者都应该依赖于抽象。
    • 抽象不应该依赖于具体,具体应该依赖于抽象。

    应用

    依赖倒置也是著名的好莱坞法则:不要调用我们,我们会调用你。在高层与低层间添加一抽象层(如上面的计算器)。

    接口隔离原则(ISP, Interface Segregation Principle)

    定义

    使用多个小的专门的接口,而不要使用一个大的总接口。
    一个类对另一个类的依赖应该建立在最小的接口上,不要强迫依赖不用的方法,这是一种接口污染。

    应用

    天鹅(Swan)即会游泳又会飞,但是鸭子只会游泳。
    强迫鸭子飞

    接口隔离,做到最小接口

    Liskov替换原则(LSP, Liskov Substitution Principle)

    定义

    子类必须能够替换其基类。

    应用

    主要体现在父类方法应该为virtual方法,子类重写父类方法,则子类完全可以替换父类在此调用自己的方法。

  • 相关阅读:
    机器学习之逻辑回归
    机器学习之线性回归与模型保存
    机器学习之决策树
    机器学习之贝叶斯算法
    机器学习之KNN算法
    算法基础与开发流程
    特征选择与特征降维
    特征预处理
    RSA加密算法和签名算法
    Java中使用OpenSSL生成的RSA公私钥
  • 原文地址:https://www.cnblogs.com/LoveTomato/p/8465245.html
Copyright © 2020-2023  润新知