此篇已收录至《你必须知道的.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();
}
}

  (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("转帐用户"));
}
}

  (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());
}
}

  (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();
}
}

  (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(); }
}

  (3)规则建议:

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

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

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

本章思维导图

作者:周旭龙

出处:http://www.cnblogs.com/edisonchou/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

《你必须知道的.NET》读书笔记二:小OO有大原则的更多相关文章

  1. 你必须知道的.net读书笔记之第二回深入浅出关键字---对抽象编程:接口和抽象类

    请记住,面向对象思想的一个最重要的原则就是:面向接口编程. 借助接口和抽象类,23个设计模式中的很多思想被巧妙的实现了,我认为其精髓简单说来就是:面向抽象编程. 抽象类应主要用于关系密切的对象,而接口 ...

  2. 你必须知道的.net读书笔记第四回:后来居上:class和struct

     基本概念 1.1. 什么是class? class(类)是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段.属性.方法.属性.构造函数.索引器.操作符等.因为是基本的概念,所以不必在此 ...

  3. [你必须知道的NOSQL系列]专题二:Redis快速入门

    一.前言 在前一篇博文介绍了MongoDB基本操作,本来打算这篇博文继续介绍MongoDB的相关内容的,例如索引,主从备份等内容的,但是发现这些内容都可以通过官方文档都可以看到,并且都非常详细,所以这 ...

  4. 必须知道的.net——学习笔记1

    1.对象的生成(出生) Person aperson=new Person("小张",25) 构造过程:分配存储空间—初始化附加成员—调用构造函数 2.对象的旅程(在一定的约定与规 ...

  5. C#刨根究底:《你必须知道的.NET》读书笔记系列

    一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...

  6. 《你必须知道的.NET》读书笔记一:小OO有大智慧

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.对象  (1)出生:系统首先会在内存中分配一定的存储空间,然后初始化其附加成员,调用构造函数执行初 ...

  7. 《你必须知道的.NET》读书笔记三:体验OO之美

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.依赖也是哲学 (1)本质诠释:“不要调用我们,我们会调用你” (2)依赖和耦合: ①无依赖,无耦合 ...

  8. 《你必须知道的.NET》读书笔记:从Hello World认识IL

    通用的语言基础是.NET运行的基础,当我们对程序运行的结果有异议的时候,如何透过本质看表面,需要我们从底层来入手探索,这时候,IL便是我们必须知道的基础. 一.IL基础概念 1.1 什么是IL? IL ...

  9. 《你必须知道的.NET》读书实践:一个基于OO的万能加载器的实现

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.关于万能加载器 简而言之,就是孝顺的小王想开发一个万能程序,可以一键式打开常见的计算机资料,例如: ...

随机推荐

  1. SQL关于limit的用法

    SELECT * FROM table  LIMIT [offset,] rows | rows OFFSET offset    在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时 ...

  2. PHP的运行机制与原理(底层) [转]

    说到php的运行机制还要先给大家介绍php的模块,PHP总共有三个模块:内核.Zend引擎.以及扩展层:PHP内核用来处理请求.文件流.错误处理等相关操作:Zend引擎(ZE)用以将源文件转换成机器语 ...

  3. mysq安装以及修改密码

    安装版MySQL是不能一键安装的,下载下来是压缩包,解压后只要进行相关配置就可以正常使用: 文章主要是记录一下,以防自己忘记: 1.首先在mysql官网--http://dev.mysql.com/d ...

  4. [ MySql学习心得 ] --One

    一.安装MySql 1.解压版安装 下载地址: http://dev.mysql.com/downloads/mysql/ 安装及配置教程:http://jingyan.baidu.com/artic ...

  5. OD使用教程11

    首先把安装好的软件拖入PEID,看看它是用什么语言写的    然后用OD载入程序,查找关键字,步骤看上一个笔记 双击到达代码处,发现这在一个跳转里面.可能第一反应是修改跳转,经试验后发现这是没用的所以 ...

  6. SAP项目管理模块培训教材

    SAP项目管理模块培训教材(PLM210.PLM220.PLM230)分享: http://sap.npbok.com/

  7. eclipse 搭建Swt 环境

    我本是想用java开发一个记事本,开发记事本使用到SWT插件,我从网上找了许多的资料去集成插件,创建我的第一个SWT项目,以下是我搭建SWT环境的过程. 一.查看当前使用的exlipse 版本型号 在 ...

  8. bash快捷建

    bash快捷建 ctrl键组合ctrl+a:光标移到行首.ctrl+b:光标左移一个字母ctrl+c:杀死当前进程.ctrl+d:退出当前 Shell.ctrl+e:光标移到行尾.ctrl+h:删除光 ...

  9. Accordion - 手风琴

    //手风琴效果 <div style="overflow:hidden;height:400px;width:948px;"> <div class=" ...

  10. 让C++程序打印自身源码

    本人原创文章,欢迎阅读,禁止转载. 这绝对是惊艳到让你眼前一亮(为了简洁,故意没考虑资源问题和编译警告). #include <iostream> #include <fstream ...