一.五大设计模式原则
SRP:单一职责原则
OCP:开闭原则
LSP: 里氏替换原则
ISP: 接口隔离原则
DIP:依赖倒置原则
这些设计模式原则之前我的博客上应该都写过,上课的时候专门把五种SOILD组合在一起,面向软件维护。
二.面向可维护性的设计模式
1.面向可维护性的创建模式
创建模式解决的是软件运行中构建对象的问题,上次没有提过。
工厂模式
问题:客户端不知道要创建哪个具体的子类,或者说客户端不应该详细了解创建类信息。
解决使用:工厂类来处理这个问题。
抽象工厂类:里面有一个抽象创建方法。
具体工厂类:里面有具体对每个子类进行创建。
工厂模式还可以不创建类使用静态工厂方法实现,依靠参数来区别子类,但并不推荐。
抽象工厂模式
问题:客户端需要一组互相关联的类。
抽象工厂模式中的类:里面有很多工厂方法。但这些工厂方法的出来的子类型,在同一个抽象工厂里是符合搭配的。
抽象工厂模式本质是很多工厂的搭配组合。
无论是工厂还是抽象工厂是符合OCP设计原则的,要增加新类,直接增加工厂即可。
结构性设计模式
之前面向复用的结构性模式有,装饰器,适配器,外观。
现在面向可维护性的,代理模式
代理模式
代理模式可能说的多一些,但实际上并没有讲那么多。
问题:不希望用户操纵一些贵重,私密的对象。
解决方案:为其创建代理对象,实现同一接口,委托给原对象。
实际上就是创建一个同一接口类,但该类的工作由代理类实现。但可以扩展了。比如对于贵重的可以再代理类里缓存。
Subject接口:共同接口,客户端使用
realsubject:真实实现
proxy:代理对象委派给realsubject
下面是赠送内容不喜欢可以跳过
摘选
goto A;
代理模式可以细分:
远程代理:将工作委派给远程对象
保护代理:进行安全模式检查
缓存代理:加速调用
虚拟智能代理:增加功能,例如记录性能指标
我们上面实现了静态代理,但还有功能更为强大的动态代理模式,需要用到反射机制。
动态代理方法使用java.lang.proxy代理库。其主要的是,你是在运行前不知道代理类的。我还在学习这个机制,下面会写一篇博客讲动态代理模式。
A:行为型模式
之前的行为型模式包括:迭代器模式,策略模式,模板模式
观察者模式
问题:subject对象,很多observer对象,observer对象状态需要根据subject对象状态而改变。
就像股市一样,股民随时看着股市,采取不同策略。股民实时知道股票涨跌,股票涨与跌,随时影响股民的行为。
抽象subject: 有notify方法负责通知observer类(调用update),注册observer类,删除observer类
具体subject:给出自己状态。
抽象observer类:有update()方法随时更新自己的状态。
具体observer类:实现update()方法,里面根据subject类状态改变而改变。
实现过程,每次obsever传入subject的attach方法完成注册,subject状态改变调用notify通知所有attach过的observer,表示当前状态变了,调用update(),update回调subject状态,并自我修改。
有几个注意的:1.双向委托,subject需要保管observer类,以便调用update通知。obsever类需要subject类了解当前subject所处状态。
2.一对多委托subject类需要向多个update()类进行调用。
Java 8之前提供现成的接口。Observer和Observable在Java 9标记为废弃。
有人说因为支持事件模型的功能很简单,例如,只是支持事情发生变化的概念,但是不能提供更多哪些内容发生了改变。并且不是线程安全。我很汗颜呀,人家觉得过于简单,我觉得复杂。我还不会多线程。
参考:deprecate Observer and Observable
访问者模式
目的:把数据结构与操作分离,对特定object的特定操作,运行时动态绑定二者,灵活更改操作。
我在网上看到的适用设计里是这么说的:1.应该该数据结构稳定,不会轻易变化,但随时会增加新方法。2.该操作与对象本身关联不大,需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。
其实我想了想觉得网上说的很有道理:访问者模式首先不应该改变类。只是该方法需要的数据是访问得到的。比如说有一个公司员工类,里面有员工表现,工龄,薪水。我要增加一个根据数据算绩效的方法。显然这就可以做成访问者。我要增加一个涨薪水的方法就不适合访问者了,因为修改了ADT表示且与类直接相关。
访问者模式:
1.被访问的element接口:里面包含一个accept方法接受不同访问者,调用其visit传递自己。
2.具体element子类型
3.抽象访问者接口:一个visit方法。
4.具体访问者:根据不同要求来编写visit方法,接受一个element子类型参数。用来访问。
5.struct;一组element集合。
策略与访问者模式
策略与访问者都是行为模式,并且都在运行时动态绑定操作。
但策略的目的是:对ADT的一个功能实现不同算法。该功能一定是ADT的核心组成对外委派。
而访问者的目的是:扩展一些对ADT本身没有影响,甚至要避免影响的操作。
访问者是站在客户端灵活增加操作,策略是核心操作的外部实现。