设计模式

面向对象的好处:易维护、易扩展、易复用、灵活性好
面向对象的两个方向性思维:
底层思维 1.语言构造 2.编译转换 3.对象内存 4.运行机制
抽象思维 1.面向对象 2.组件封装 3.设计模式 4.架构模式
三大面向对象机制:
封装,隐藏内部实现
继承,复用现有代码
多态,改写对象行为
好的面向对象设计-------对应变化,提高复用
复用是好的设计,变化是复用的天敌。
面向对象设计最大的优势在于:抵御变化!
面向对象设计原则:
单一职责原则:类的职责要单一,不能将太多的职责放在一个类中
注重的是职责
开闭原则:
里氏代换原则:
依赖倒转原则:
接口隔离原则:
合成复用原则:
迪米特法则:
单一职责原则(类单一,方法单一)
定义:不要存在多余一个导致类变更的原因。通俗的说,即一个类只负责一项职责。
低耦合,高内聚
遵循单一职责原则的优点:
1.可以降低类的复杂度,一个类只负责一项职责其逻辑肯定要比负责多项职责简单的多
2.提高类的可读性,提高系统的可维护性
3.变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响
里氏代换原则
定义:所有引用基类的地方必须能透明地使用其子类的对象
面对新的需求是尽量去扩展不要去修改
子类可以扩展父类的功能,但不能改变父类原有的功能
父类能出现的地方都可以用子类来代替,而且换成子类也不会出现任何错误或异常,而使用者也无需知道是父类还是子类,但反过来则不成立。总之,就是抽象。
1.子类必须完全实现父类的抽象方法,但不能覆盖父类的非抽象方法
2.子类中可以增加自己特有的方法
3.当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数要更宽松
4.当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格
优点:
1.提高代码重用性,子类拥有父类的方法和属性
2.提高代码的可扩展性,子类可形似于父类,但异于父类,保留自我的特性
缺点:
1.继承是侵入性的,只要继承就必须拥有父类的所有方法和属性,在一定程度上约束了子类,降低了代码的灵活性
2.增加了耦合,当父类的常量 变量或者方法被修改了,需要考虑子类的修改,所以一旦父类有了变动,很有可能会照成
缺点:降低代码的灵活性
增加了耦合
接口是实现行为的
依赖倒转原则
定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象
相对于细节的多变性,抽象类的东西要稳定的多。以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多。抽象指的是接口或者抽象类细节就是具体的实现类,使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。依赖倒转原则的核心思想是面向接口编程
接口隔离原则
定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上
把大接口拆分为小接口,在继承需要用到的接口
含义:建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。我们要为各个类建立专用的接口,而不是试图去建立一个很庞大的接口供所有依赖它的类去调用。
注重对接口依赖的隔离
采用接口隔离原则对接口进行约束是,要注意以下几点:
1.接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性是不争的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度
2.为依赖接口的类定制服务只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系
3.提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。运用接口隔离原则,一定要适度,接口设计的过大或过小都不好。设计接口的时候,只有多花些时间去思考和筹划,才能准确地实践这一原则
迪米特法则
定义:一个对象应该对其他对象保持最少的了解
软件编程的总的原则:低耦合,高内聚。无论是面向过程编程还是面向对象编程,只有使各个模块之间的耦合尽量的低,才能提高代码的复用率。
迪米特法则又叫最少知道原则,就是一个类对自己依赖的类知道的越少越好。对于被依赖的类来说,无论逻辑多么复杂,都尽量的将逻辑封装在类的内部,对外除了提供public方法,不对外泄露任何信息
耦合的方式很多,依赖、关联、组合、聚合等
依赖:new对方的实例,调对方的方法
关联:单向、双向
组合和聚合都属于关联,组合是一种特殊的关联,聚合是特殊的组合
继承脚本用单例或写成静态的
开闭原则
定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭
软件实现应该对扩展开放,对修改关闭
软件实体包括以下几个部分:
项目或软件产品中按照一定的逻辑规则划分的模块
抽象和类
方法
开闭原则告诉我们应尽量通过扩展软件实体的行为来实现变化,而不是通过修改现有代码来完成变化,它是为软件实体的未来事件而制定的对现行开发设计进行约束的一个原则
为什么使用开闭原则?
第一:开闭原则非常有名,只要是面向对象编程,在开发时都会强调开闭原则
第二:开闭原则是最基础的设计原则,其他的五个设计原则都是开闭原则的具体形态,也就是说其他的五个设计原则是指导设计的工具和方法,而开闭原则才是其精神领袖
第三:开闭原则可以提高复用性
在面向对象的设计中,所有的逻辑都是从原则逻辑组合而来,不是在一个类中独立实现一个业务逻辑。只有这样的代码才可以复用,粒度越小,被复用的可能性越大。他可以减少代码的重复,避免相同的逻辑分散在多个角落。减少维护人员的工作量,缩小逻辑粒度,直到一个逻辑不可以分为止,这样才能提高复用率
第四:开闭原则可以提高维护性
第五:面向对象开发的要求
万物皆对象,我们要把所有的事物抽象成对象,然后针对对象进行操作,但是万物皆发展变化,有变化就要有策略去应付
如何使用开闭原则
第一: 抽象约束
抽象是对一组事物的通用描述
第二:元数据【metadata】控件模块行为
第三:制定项目章程
第四:封装变化
对变化封装包含两层含义:
1.将相同的变化封装到一个接口或抽象类中
2.将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类中。
封装变化,也就是受保护的变化,找出预计有变化或不稳定的点,我们为这些变化点创建稳定的接口
工厂模式:(特效,读表,怪物)
概念:这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行
主要解决:接口选择的问题
何时使用:我们明确地计划不同条件下创建不同实例时
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品
关键代码:创建过程在其子类执行
优点:
1.一个调用者想创建一个对象,只要知道其名称就可以了
2.扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以
3.屏蔽产品的具体实现,调用者只关心产品的接口
缺点:
每次增加一个产品时,都需要一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事!
注意事项:
作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。
单例模式:
这种类型属于创建型模式,这种模式设计到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问位移的对象的方式,可以直接访问,不需要实例化该类的对象
注意:
1.单例类只能有一个实例
2.单例类必须自己创建自己的唯一实例
3.单例类必须给所有其他对象提供这一实例
意图:保证一个类只有一个实例,并提供一个访问它的全局访问点
主要解决:一个全局使用的类频繁的创建与销毁
何时使用:当你想控制实例数目,节省系统资源的时候
如何解决:判断系统是否已经有这个
优点:
1.在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例
2.避免对资源的多重占用
缺点:
没有接口不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例
观察者:
概念:当对象间存在一对多关系时,则使用观察者模式。比如,当一个对象被修改是,则会自动通知它的依赖对象。观察者模式属于行为型模式
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所以依赖于它的对象都得到通知并被自动更新
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
关键代码:在抽象类里有一个arryList存放观察者们。
优点:
1.观察者和被观察者是抽象耦合的
2.建立一套触发机制
缺点:
1.如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间
2.如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃
3.观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么方生变化的,而仅仅只是知道观察目标发生了变化
策略模式
概念:定义了家族算法,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
意图:定义一系列的算法,把他们一个一个封装起来,并且使它们可相互替换
主要解决:在有多种算法相似的情况下,使用if…else 所带来的复杂和难以维护
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为
如何解决:将这些算法封装成一个一个的类,任意地转换
关键代码:实现同一个接口
优点:
1.算法可以自由切换
2.避免使用多重条件判断
3.拓展性好
缺点:
1.策略类会增多
2.所有策略类都需要对外暴露
使用场景:
1.如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为
2.一个系统需要动态地在几种算法中选择一种
3.如果一个对象有许多行为。如果不用恰当的模式,这些行为就只好使用这些行为就只好使用多重的条件选择语句来实现
装饰者模式
概念:允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,他是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提,提供了额外的功能
意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活
何时使用:
在不想增加很多子类的情况下拓展类
如何解决:
将具体功能职责划分,同时继承装饰者模式
关键代码:
1.Component类充当抽象角色,不应该具体实现
2.修饰类引用和继承Component类,具体拓展类重写父类方法
优点:
装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式时继承的一个替代模式,装饰模式可以动态拓展一个实现类的功能
缺点:多层装饰比较复杂
使用场景:
1.扩展一个类的功能
2.动态增加功能,动态撤销

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值