设计模式(收集了知识点解密中...)

内聚:自己的东西自己保管,自己的事情自己做。

在面向对象编程中,对象自身是内聚的,是保管好自己的数据,完成好自己的操作的,而对外界呈现出自己的状态和行为。但是,没有绝对的自力更生,对外开放也是必要的!

依赖:一个对象,往往需要跟其他对象打交道,既包括获知其他对象的状态,也包括仰赖其他对象的行为,而一旦这样的事情发生时,我们便称该对象依赖于另一对象。

耦合:只要两个对象之间存在一方依赖一方的关系,那么我们就称这两个对象之间存在耦合。

耦合度:耦合的程度就是耦合度,也就是双方依赖的程度。

强耦合:妈妈和baby是强耦合。妈妈要随时关注baby的睡、醒、困、哭、尿等等状态,baby则要仰赖妈妈的喂奶、哄睡、换纸尿裤等行为,从程序的意义上说,二者互相依赖。

低耦合:你跟快递小哥之间则是弱耦合。

解耦合:从某种意义上来说,耦合天生就与自由为敌,无论是其他对象依赖于你,还是你依赖其他对象。比如有人嗜烟、酗酒,你有多依赖它们就有多不自由;因此,要想自由,就必须要降低耦合,而这个过程就叫做解耦和。

依赖倒置(Dependence Inversion Principle):解耦和最重要的原则就是依赖倒置原则;
高层模块不应该依赖底层模块,他们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象。

《资本论》中都曾阐释依赖倒转原则——在商品经济的萌芽时期,出现了物物交换。假设你要买一个IPhone,卖IPhone的老板让你拿一头猪跟他换,可是你并没有养猪,你只会编程。所以你找到一位养猪户,说给他做一个养猪的APP来换他一头猪,他说换猪可以,但是得用一条金项链来换——所以这里就出现了一连串的对象依赖,从而造成了严重的耦合灾难。解决这个问题的最好的办法就是,买卖双发都依赖于抽象——也就是货币——来进行交换,这样一来耦合度就大为降低了。

原则:抽象不应该依赖于细节,细节应当依赖于抽象。换言之,要针对接口编程,而非针对实现编程。

满足两个条件:
1.高层模块不应该依赖于低层模块,两个都应该依赖于抽象。
2.抽象不应该依赖细节,细节应该依赖于抽象。

在java中,抽象指的是接口或者抽象类,细节就是具体的实现类,使用接口或者抽象类的目的是制定好规范,而不去涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。

控制反转(Inversion of Control):控制反转跟依赖倒置是如出一辙的两个概念,当存在依赖倒置的时候往往也存在着控制反转。但是控制反转也有自己的独特内涵。比如你去下馆子,你是Client,餐馆是server。你点菜,餐馆负责做菜,程序流程的控制权属于server;而如果你去自助餐厅,程序流程的控制权就转到Client了,也就是控制反转,同时我们也将这个调用称为“回调”。

依赖注入(Dependency Injection):依赖注入,就其广义而言,即是通过“注入”的方式,来获得依赖。我们知道,A对象依赖于B对象,等价于A对象内部存在对B对象的“调用”,而前提是A对象内部拿到了B对象的引用。B对象的引用的来源无非有以下几种:A对象内部创建(无论是作为字段还是作为临时变量)、构造器注入、属性注入、方法注入。后面三种方式统称为“依赖注入”,而第一种方式我也生造了一个名词,称为“依赖内生”,二者根本的差异即在于,我所依赖的对象的创建工作是否由我自己来完成。当然,这个是广义的依赖注入的概念,而我们一般不会这样来使用。我们通常使用的,是依赖注入的狭义的概念。不过,直接陈述其定义可能会过于诘屈聱牙,我们还是从具体的例子来看。

比如OMCS网络语音视频框架,它实现了多媒体设备(麦克风、摄像头、桌面、电子白板)的采集、编码、网络传送、解码、播放(或显示)等相关的一整套流程,可以快速地开发出视频聊天系统、视频会议系统、远程医疗系统、远程教育系统、网络监控系统等等基于网络多媒体的应用系统。然而,OMCS直接支持的是通用的语音视频设备,而在某些系统中,需要使用网络摄像头或者特殊的视频采集卡作为视频源,或者其它的声音采集设备作为音频源,OMCS则提供了扩展接口——用户自己实现这个扩展的接口,然后以“依赖注入”的方式将对象实例注入到OMCS中,从而完成对音、视频设备的扩展。

接口隔离:使用多个专门的接口比使用单一的总接口要好。

原则:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。

面向接口编程

(why)为什么要用设计模式:合理组织代码,修改封闭,对扩展点进行扩展开放。

(where)何处使用设计模式:为了合理的利用设计模式,我们应该明白一个概念,叫做扩展点。扩展点不是天生就有的,而是设计出来的。我们设计一个软件的架构的时候,我们也要同时设计一下哪些地方以后可以改,哪些地方以后不能改。倘若你的设计不能满足现实世界的需要,那你就要重构,把有用的扩展点加进去,把没用的扩展点去除掉。这跟你用不用设计模式没关系,跟你对具体的行业的理解有关系。

设计模式的6个基本原则

  • 单一职责原则(Single Responsibility Principle)

一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。
单一职责原则告诉我们:一个类不能太“累”! 一个类的职责越重(这往往从构造器所需要的依赖就能体现出来),它被复用的可能性就越小。
不能否认,这个工具需要相对较高的学习成本,但是学会了依赖注入工具并理解了IOC(控制反转),DI(依赖注入)的思想之后,它将成为你开发过程中无往不胜的利器。

  • 里氏代换原则(Liskov Substitution Principle)

任何基类可以出现的地方,子类一定可以出现。
里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

向上转型是Java的基础,我们经常也用到,实际上,在进行设计的时候,尽量从抽象类继承,而不是从具体类继承。同时,保证在软件系统中,把父类都替换成它的子类,程序的行为没有变化,就足够了。

  • 依赖倒转原则(Dependence Inversion Principle)

抽象不应该依赖于细节,细节应当依赖于抽象。换言之,要针对接口编程,而非针对实现编程。

它的原则是:
1.高层模块不应该依赖于低层模块,两个都应该依赖于抽象。

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

在java中,抽象指的是接口或者抽象类,细节就是具体的实现类,使用接口或者抽象类的目的是制定好规范,而不去涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。

  • 接口隔离原则(Interface Segregation Principle)

接口隔离原则:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。

这个应该是最好理解的原则了,它的意义就是:使用多个专门的接口比使用单一的总接口要好。

  • 迪米特法则,又称最少知道原则(Demeter Principle)

迪米特法则:一个软件实体应当尽可能少地与其他实体发生作用。(这个应该很好理解,就是降低各模块之间的耦合)

  • 开闭原则(Open Close Principle)

一个软件应对扩展开放、对修改关闭,用head first中的话说就是:代码应该如晚霞中 的莲花一样关闭(免于改变),如晨曦中的莲花一样开放(能够扩展).

设计模式的分类:

范围 创建型 结构型 行为型
Factory Method(工厂方法) Adapter(类) (适配器) Interpreter(解释器)
Template Method(模版方法)
对象 Abstract Factory(抽象工厂)
Builder(建造者)
Prototype(原型)
Singleton(单例)
Adapter(对象)(适配器)
Bridge(桥接)
Composite(组合)
Decorator(装饰者)
Facade(外观)
Flyweight(享元)
Proxy(代理)
Chain of Responsibility(职责链)
Command(命令)
Iterator(迭代器)
Mediator(中介者)
Memento(备忘录)
Observer(观察者)
State(状体)
Strategy(策略)
Visitor(访问者)

再细点分类:

范围 创建型 结构型 行为型
对象创建 Singleton(单例)
Prototype(原型)
Factory Method(工厂方法)
Abstract Factory(抽象工厂)
Builder(建造者)
接口适配 Adapter(适配器)
Bridge(桥接)
Facade(外观)
对象去耦 Mediator(中介者)
Observer(观察者)
抽象集合 Composite(组合) Iterator(迭代器)
行为扩展 Decorator(装饰) Visitor(访问者)
Chain of Responsibility(职责链)
算法封装 Template Method(模板方法)
Strategy(策略)
Command
性能与对象访问 Flyweight(享元)
Proxy(代理)
对象状态 Memento(备忘录)
State(状态)
其它 Interpreter(解释器)

创建型模式的理解:与对象(类)的创建有关。

结构型模式的理解:通过将不同类或对象的组合,采用继承或者组合接口,或者组合一些对象,以实现新的功能。用一句话陈述,就是对不同职责的对象(以对象/抽象类/接口的形式)之间组合调度的实现方式。

并非所有对象的组合都是结构型模式:
实际上,并非所有对对象的组合都属于结构型模式,构型模式的意义在于,对一些对象的组合,以实现新功能的方式—— 通过运行时,通过改变组合的关系,这种灵活性产生不同的效果,这种机制,普通的对象组合是不可能实现的。

行为模式的理解:为了提高类之间的协作效率。

行为模式定义:行为模式涉及到算法和对象间职责的分配,行为模式不仅描述对象或类的模式,还描述它们之间的通信模式。这些模式刻划了在运行时难以跟踪的复杂的控制流,将你的注意力从控制流转移到对象间的联系方式上来。

外观模式的定义:为子系统中的一组接口提供一个一致的界面,外观模式定义一个高层接口,这个接口使得这一子系统更容易使用。

什么是容器Facade:

什么是依赖注入AOP:

posted @   xiao_linxin  阅读(107)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示

目录导航