大牛分享的几种设计模式及知识要点(四)

大牛分享的几种设计模式及知识要点(四)_第1张图片

一、组合模式((Composite Pattern) )

定义:Compose objects into tree structures to represent part-whole

hierarchies.Composite lets clients treat individual objects and compositions of

objects uniformly.(将对象组合成树形结构以表示“部分-整体”的层次结构,使得用

户对单个对象和组合对象的使用具有一致性。)

● Component 抽象构件角色

定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性,比如我们

例子中的 getInfo 就封装到了抽象类中。

● Leaf 叶子构件

叶子对象,其下再也没有其他的分支,也就是遍历的最小单位。

● Composite 树枝构件

树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构。

树枝构件的通用代码:

public class Composite extends Component {

//构件容器

private ArrayList componentArrayList = new

ArrayList();

//增加一个叶子构件或树枝构件

public void add(Component component){

this.componentArrayList.add(component);

}

//删除一个叶子构件或树枝构件

public void remove(Component component){

this.componentArrayList.remove(component);

}

//获得分支下的所有叶子构件和树枝构件

public ArrayList getChildren(){

return this.componentArrayList;

}

}

使用场景:

● 维护和展示部分-整体关系的场景,如树形菜单、文件和文件夹管理。

● 从一个整体中能够独立出部分模块或功能的场景。

注意:

只要是树形结构,就考虑使用组合模式。

文末福利:kx33389,加她就能免费领取分布式、微服务、源码分析、性能优化、高并发高可用等技术的资料

二、观察者模式(Observer Pattern )

定义:Define a one-to-many dependency between objects so that when one

object changes state,all its dependents are notified and updated automatically.

(定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于

它的对象都会得到通知并被自动更新。)

● Subject 被观察者

定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽

象类或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观

察者。

● Observer 观察者

观察者接收到消息后,即进行 update(更新方法)操作,对接收到的信息进行处

理。

● ConcreteSubject 具体的被观察者

定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。

● ConcreteObserver 具体的观察者

每个观察在接收到消息后的处理反应是不同,各个观察者有自己的处理逻辑。

被观察者通用代码:

public abstract class Subject {

//定义一个观察者数组

private Vector obsVector = new Vector();

//增加一个观察者

public void addObserver(Observer o){

this.obsVector.add(o);

}

//删除一个观察者

public void delObserver(Observer o){

this.obsVector.remove(o);

}

//通知所有观察者

public void notifyObservers(){

for(Observer o:this.obsVector){

o.update();

}

}

}

使用场景:

● 关联行为场景。需要注意的是,关联行为是可拆分的,而不是“组合”关系。

● 事件多级触发场景。

● 跨系统的消息交换场景,如消息队列的处理机制。

注意:

● 广播链的问题

在一个观察者模式中最多出现一个对象既是观察者也是被观察者,也就是说消息最

多转发一次(传递两次)。

● 异步处理问题

观察者比较多,而且处理时间比较长,采用异步处理来考虑线程安全和队列的问

题。

大牛分享的几种设计模式及知识要点(四)_第2张图片

三、门面模式(Facade Pattern )

定义:Provide a unified interface to a set of interfaces in a subsystem.Facade

defines a higher-level interface that makes the subsystem easier to use.(要求一

个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个

高层次的接口,使得子系统更易于使用。)

● Facade 门面角色

客户端可以调用这个角色的方法。此角色知晓子系统的所有功能和责任。一般情况

下,本角色会将所有从客户端发来的请求委派到相应的子系统去,也就说该角色没

有实际的业务逻辑,只是一个委托类。

● subsystem 子系统角色

可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类

的集合。子系统并不知道门面的存在。对于子系统而言,门面仅仅是另外一个客户

端而已。

使用场景:

● 为一个复杂的模块或子系统提供一个供外界访问的接口

● 子系统相对独立——外界对子系统的访问只要黑箱操作即可

● 预防低水平人员带来的风险扩散

注意:

●一个子系统可以有多个门面

●门面不参与子系统内的业务逻辑

文末福利:kx33389,加她就能免费领取分布式、微服务、源码分析、性能优化、高并发高可用等技术的资料 

四、备忘录模式(Memento Pattern )

定义:Without violating encapsulation,capture and externalize an object's internal

state so that the object can be restored to this state later.(在不破坏封装性的前提

下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该

对象恢复到原先保存的状态。)

● Originator 发起人角色

记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备

忘录数据。

● Memento 备忘录角色(简单的 javabean)

负责存储 Originator 发起人对象的内部状态,在需要的时候提供发起人需要的内部

状态。

● Caretaker 备忘录管理员角色(简单的 javabean)

对备忘录进行管理、保存和提供备忘录。

使用场景:

● 需要保存和恢复数据的相关状态场景。

● 提供一个可回滚(rollback)的操作。

● 需要监控的副本场景中。

● 数据库连接的事务管理就是用的备忘录模式。

注意:

●备忘录的生命期

●备忘录的性能

不要在频繁建立备份的场景中使用备忘录模式(比如一个 for 循环中)。

clone 方式备忘录:

● 发起人角色融合了发起人角色和备忘录角色,具有双重功效

多状态的备忘录模式

● 增加了一个 BeanUtils 类,其中 backupProp 是把发起人的所有属性值转换到

HashMap 中,方便备忘录角色存储。restoreProp 方法则是把 HashMap 中的值返

回到发起人角色中。

BeanUtil 工具类代码:

public class BeanUtils {

//把 bean 的所有属性及数值放入到 Hashmap 中

public static HashMap backupProp(Object bean){

HashMap result = new

HashMap();

try {

//获得 Bean 描述

BeanInfo

beanInfo=Introspector.getBeanInfo(bean.getClass());

//获得属性描述

PropertyDescriptor[]

descriptors=beanInfo.getPropertyDescriptors();

//遍历所有属性

for(PropertyDescriptor des:descriptors){

//属性名称

String fieldName = des.getName();

//读取属性的方法

Method getter = des.getReadMethod();

//读取属性值

Object fieldValue=getter.invoke(bean,new

Object[]{});

if(!fieldName.equalsIgnoreCase("class")){

result.put(fieldName, fieldValue);

}

}

} catch (Exception e) {

//异常处理

}

return result;

}

//把 HashMap 的值返回到 bean 中

public static void restoreProp(Object bean,HashMap

propMap){

try {

//获得 Bean 描述

BeanInfo beanInfo =

Introspector.getBeanInfo(bean.getClass());

//获得属性描述

PropertyDescriptor[] descriptors =

beanInfo.getPropertyDescriptors();

//遍历所有属性

for(PropertyDescriptor des:descriptors){

//属性名称

String fieldName = des.getName();

//如果有这个属性

if(propMap.containsKey(fieldName)){

//写属性的方法

Method setter = des.getWriteMethod();

setter.invoke(bean, new

Object[]{propMap.get(fieldName)});

}

}

} catch (Exception e) {

//异常处理

System.out.println("shit");

e.printStackTrace();

}

}

}

多备份的备忘录:略

封装得更好一点:保证只能对发起人可读

●建立一个空接口 IMemento——什么方法属性都没有的接口,然后在发起人

Originator 类中建立一个内置类(也叫做类中类)Memento 实现 IMemento 接口,

同时也实现自己的业务逻辑。

粉丝福利

给大家免费分享一套阿里架构师传授的一套教学资源。帮助大家在成为架构师的道路上披荆斩棘。

这套视频课程详细讲解了(Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构)等这些成为架构师必备的内容!

而且还把框架需要用到的各种程序进行了打包,根据基础视频可以让你轻松搭建分布式框架环境,像在企业生产环境一样进行学习和实践。

大牛分享的几种设计模式及知识要点(四)_第3张图片

你可能感兴趣的:(大牛分享的几种设计模式及知识要点(四))