设计模式-读书笔记2

embedded/2024/12/24 0:58:03/

结构型模式

适配器模式 不兼容结构的协调 220v接入20v的笔记本电脑 别名包装器 Wrapper

适配器类Adapter 适配者类Adaptee 目标抽象类 Target

//demo1
class Adapter extends Target{private Adaptee  adaptee; //维持对一个适配者对象的引用public Adapter (Adaptee adaptee){this.adaptee = adaptee;}public void request(){ // 转发调用adaptee.specificRequest();}
}

当target 和adaptee双向调用时,双向适配器模式

//demo2
class Adapter implements Target,Adaptee{private Adaptee  adaptee; //同时维持对适配者和目标类的引用private Target target;public Adapter (Adaptee adaptee){this.adaptee = adaptee;}public void request(){ // 转发调用adaptee.specificRequest();}
}

缺省适配器模式:当不需要实现一个接口所提供的所有方法时,可先设计一个抽象类实现接口,并为接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求,它适用于不想使用一个接口中的所有方法的情况,又称单接口适配器模式

桥接模式 处理多维度变化 颜色、系统 分类抽象接口和实现

//demo1
//实现类接口
interface ImageImp{public void doPaint(Matrix m); //显示像素矩阵m
}
//具体实现类
class WindowImp implements ImageImp{public void doPaint(Matrix m){sout("在windows系统上显示")}
}
//抽象类
abstract class Image{protected ImageImp imp; //定义实现类接口对象public void setImageImp(ImageImp imp){this.imp = imp;}public abstract void parseFile(String fileName); //声明抽象业务方法
}
//扩充抽象类
class JPGImage extends Image{public void parseFile(String fileName){Matrix m = new Matrix;imp.doPaint(m); //调用实现类的方法sout("格式为jpg")}
}

组合模式 树形结构的处理 处理文件夹及下面的文件

定义一个抽象构建类,既可以代表叶子,又可以代表容器

//demo1
//抽象构件
abstract class Component{public abstract void add(Component a); //新增public abstract void del(Component a); //删除public abstract void operation(); //业务方法
}
//叶子构件
class Leaf extends Component{add。。。。。。。。
}
//容器构件
class Composite extends Component{private ArrayList<Component> list = new ArrayList<Component>();add{list.add(c)}。。。。。。。。public void operation(){//容器构件具体业务方法的实现//递归调用成员构件的业务的方法for(Object obj:list){((Component)obj).operation();}}
}

P162 12.5 22:08留

透明组合模式:抽象构件类Compenent 有所有方法,提供默认实现

安全组合模式:抽象构件类Compenent 没有管理成员对象的方法,如叶子节点leaf不需要的add等方法

装饰模式 扩展系统功能 对象结构型

动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更加灵活

抽象构件Compoent:是具体构件和抽象装饰类地共同父类

具体构件ConcreteComponent:

抽象装饰类:Decorator 给具体构件增加职责,但具体职责在其子类中实现

具体装饰类:ConcreteDecorator

//demo1抽象装饰类的设计
class Decorator implements Component{private Component component; // 维持一个对抽象构件对象的引用,注入一个抽象构件类型的对象public Decorator(Component component){this.component = component;}public void operation(){component.operation(); //调用原有业务方法}
}
//具体装饰类中
class ConcreteDecorator extends Decorator{public ConcreteDecorator(Component component){super(component);}public void operation(){super.operation(); //调用原有业务方法addedBehavior(); //调用新增业务方法}public void addedBehavior(){.....}
}
//使用
Component component, componentSB;  //使用抽象构件定义
component = new Window(); // 定义具体构件
componentSB = new ConcreteDecorator(); //定义装饰后的构件
componentSB.display();
//也可以
Component componentBB;  //全部使用抽象构件定义
componentBB = new ConcreteDecorator2(componentSB); //将装饰了一次之后的对象继续注入到另一个装饰类中进行第2次装饰

透明装饰模式

上面使用抽象构件类型定义对象,而不是具体构件类型,如

ConcreteDecorator2 componentBB = new ConcreteDecorator2(componentSB);

但是这无法调用具体装饰类中的新增行为

半透明装饰模式

Component component; //使用抽象类型定义
component = new Window();
ConcreteDecorator componentSB = new ConcreteDecorator();  //使用具体装饰类型定义

这不能实现对一个对象的多次装饰(传入调用)

外观模式 提供统一入口 facade

外观角色

//demo1
class Facade{private SubSystemA obj1 = new SubSystemA();private SubSystemB obj2 = new SubSystemB();public void method(){obj1.method();obj2.method();}
}

设计为单例类,定义了一个静态的Facade类型的成员变量instance,其构造函数为私有private

如果要一个子系统变为另一个,原有不再使用,这需要引入一个抽象外观类,客户端针对抽象外观类编程,而在运行时再确定具体外观类

//demo1
abstarct class AbstractFacade{public abstract void method();
}
Class newFacade extends AbstractFacade{}

享元模式 实现对象的复用,通过共享技术有效支持大量细粒度对象的复用

FlyWeight 抽象享元类

ConcreteFlyWeight 具体享元类

UnsharedConcreteFlyWeight 非共享具体享元类

FlyweightFactory 享元工厂类,通常只有一个

//demo1
class FlyweightFactory {//定义一个HashMap用于存储享元对象,实现享元池private HashMap flyweights = new HashMap();public FlyWeight getflyweight(String key){//如果对象存在,则直接从享元池获取if(flyweights.containskey(key)){return (Flyweight)flyweights.get(key);}else{//如果对象不存在,先创建一个新的对象添加到享元池中,然后返回FlyWeight fw = new ConcreteFlyWeight();flyweights.put(key, fw);return fw;}}
}

内部状态:“a"始终是"a”

外部状态:"a"有的是红色的

//demo2
class FlyWeight{//内部状态inState作为成员变量,同一个享元对象其内部状态是一致的private String instate;public FlyWeight (String instate){this.instate = instate;}
}
//demo3
//外部状态exstate 在使用时由外部设置,不保存在享元对象中,即使是同一个对象,在每一次调用时可以传入不同的外部状态
public void operation(String exstate){}

单纯享元模式:所有具体享元类都是可共享的

符合享元模式:其中包含的每个单元享元类外部状态相同,其内部状态不同,符合享元对象本身不共享

//demo4
String s1 = "ab";
String s2 = "a"+"b";
s1 == s2  true

代理模式 对象的间接访问

Proxy类

//demo1
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

返回一个动态创建的代理类的实例

第一个参数是代理类的类加载器

第2个参数是代理类所实现的接口列表(与真实主题类接口列表一致)

第3个参数是代理类所指派的调用处理程序类

//demo2
interface AbstractDao //抽象主题角色
class UserDaoo implements AbstractDao {} //真实角色  有个findUserById方法
//自定义请求处理程序类
class DaoLogHandler implements InvocationHandler{private Object object;public DaoLogHandler(){};public DaoLogHandler(Object object){this.object = object;}
}

实现invoke方法,调用在真实主题类中定义的方法

//demo3
public Object invoke(Object proxy, Method method, Object[] args) throw Throwable{//proxy是代理类的实例//method需要代理的方法//args代理方法的参数数组Object result = method.invoke(object, args);   // object转发调用return null;
}

实现

//demo4
AbstraceDao dao = new UserDao();
InvocationHandler handler = new InvocationHandler(dao);
AbstraceDao proxy = null;
//动态创建代理对象,用来代理一个AbstractUserDao类型的真实主题对象
proxy = (AbstractDao)Proxy.newInstance(AbstraceDao.class.getClassLoader(), new Class[]{AbstractDao.class}, handler);
proxy.findUserById(); // 调用代理对象的业务方法

远程代理:访问远程主机

虚拟代理:如上,例如一个对象需要很久时间才能完成加载,用一个资源少的对象来代理一个消耗资源多的对象

保护代理:访问权限

缓冲代理:提供临时存储空间,以供多个客户端共享结果

智能引用代理:提供额外操作

与装饰不同,它目的在动态增加功能,且新职责在同一个问题域,而代理是不同问题域,目的在控制对象的访问

行为型模式

职责链模式 请求的链式处理

请求处理对象仅需维持一个指向后继者的引用,而不需要维持它对所有的候选处理者的引用,可简化对象的互相连接

//demo1
abstract class Handler{//维持对下家的引用protected Handler succesor;public void setSuccesor(Handler succesor){this.succesor = succesor;}public abstract void handleRequest(String request){if(请求满足条件){//处理请求}else{this.succesor.handlerRequest(request); //转发请求}}
}

命令模式 请求发送者与接收者解耦

//demo1
//抽象命令类
abstract class Command{public abstract void execute();
}
//调用者
class Invoker{private Command command;//构造注入public Invoker(Command command){this.command = command}//设值setter注入public void setCommand(Command command){this.command = command}//业务方法 用于调用命令类的execute方法public void call(){command.execute();}
}
//具体命令类 
class ConcreteCommand extends Command{private Receiver receiver; //维持一个对请求接收者对象的引用;public void execute(){receiver.action();  //调用请求接收者的处理方法}
}
class Receiver{public void action(); //具体操作}

将请求发送者和接收者完全解耦

命令队列:将多个请求排队,增加一个CommandQueue类

//demo2
class CommandQueue{//定义一个ArrayList来存储命令队列private ArrayList<Command> commands = new ArrayList<Command>();public void addCommand ~ //循环调用每一个命令对象的execute()方法public void execute(){for(Object command:commands){((Command)command).execute();}}    
}
//请求发送者Invoker中
private CommandQueue cq;
//调用方法
public void call(){cq.execute();
}

解释器模式

自定义语言的实现

//demo1
//抽象表达式 
abstract class AbstractExpression{public abstarct void interpret(Context ex);
}
//终结符表达式
class TerminalExpression extends AbstractExpression{public void interpret(Context ctx){}
}
//非终结符表达式
class NonTerminalExpression extends AbstractExpression{   //一个类对应一个规则private AbstractExpression left;private AbstractExpression right;//构造注入.....public void interpret(Context ctx){//递归调用每一个组成部分的interpret方法,在递归调用时指定组成部分的连接方式,即非终结符的功能}
}

迭代器模式 遍历聚合对象中的元素 存储数据和遍历数据分离

提供一种方式来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标cursor

//demo1
//抽象迭代器
interface Iterator{public void first();
}
//具体迭代器
class ConcreteIterator implements Iterator{private ConcreteAGG objects;   //维持一个对具体聚合对象的引用,以便于访问存储在聚合对象中的数据private int cursor; // 定义一个游标,用于记录当前访问位置public ConcreteIterator(ConcreteAGG objects){this.objects = objects;}public void first(){......}
}
//抽象聚合类
interface AGG{Iterator createIterator();
}
//具体聚合类
class ConcreteAGG implements AGG{public Iterator createIterator(){return new ConcreteIterator(this);}
}
//或在具体聚合类中使用内部类实现迭代器
private class Itr implements Iterator<E>{int cursor=0;。。。。。
}

如JDK内置的迭代器一样,Collection接口中有add方法 Iterator iterator()

以上不支持逆向遍历 ListIterator接口可支持

ListIterator i = c.listIterator();

P298 记录昨天下午看的内容 20:30留

中介者模式 协调多个对象之间的交互 网状变为星型

抽象中介者

//demo1
abstract class Mediator{protected ArrayList<Colleague> colleagues;  // 用于存储同事对象//注册方法,用于增加同事对象public void register(Colleague colleague){colleagues.add(colleague);}//声明抽象的业务方法public abstract void operation();
}
//具体中介者
class ConcreteMediator extends Mediator{//实现业务方法,封装同事之间的调用public void operation(){.....((Colleague)colleagues.get(0)).method(); //通过中介者调用同事类的方法}
}
//抽象同事类
abstract class Colleague{protected Mediator mediator; //维持一个抽象中介者的引用//构造注入public Colleague(Mediator mediator){this.mediator = mediator;}public abstract void method();   //声明自身方法,处理自己的行为public void method2(){mediator.operation();  // 定义依赖方法,与中介者进行通信}
}
//具体同事类
class ConcreteColleague extends Colleague{public ConcreteColleague(Mediator mediator){super(mediator);}//实现自身方法public void method1(){.....}
}

增加新的同事类:

法1:直接在具体中介者中改

法2:增加具体中介者的子类,进行方法覆盖

备忘录模式 撤销功能的实现 别名Token

在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就能在以后将对象恢复到原先保存的状态

//demo1
//原发器
public class Originator{private String state;public Originator(){};  // 创建备忘录对象public Memento createMemento(){return new Memento(this);}//根据备忘录对象恢复原发器状态public void restoreMemento(Memento m){state = m.state;}setState......getState.....
}
//为了保证备忘录的封装性,要与原发器一个包
class Originator{private String state;public Memento(Originator o){  //只由原发器控制,而不是负责人state = o.getState();}setState。。。。getState....
}
//负责人
public class Caretaker{private Memento memento;public Memento getMemento(){return memento;}public void setMemento(Memento memento)......
}

如果要多次撤销,负责人中定义ArraysList集合来存储多个备忘录

private ArrayList mementoList = new ArrayList();

观察者模式 对象间的联动

一对多 每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新

别名:发布-订阅 模型-视图 源-监听器 从属者

//demo1
//目标
abstract class Subject{//定义一个观察者集合用于存储所有观察者对象protected ArrayList observers<Observer> = new ArrayList();//注册方法,用于向观察者集合中增加一个观察者public void attach(Observer observer){observers.add(observer);}//注销方法   删除  detach   remove//声明抽象通知方法public abstract void notify();
}
//具体目标类
class ConcreteSubject extends Subject{//实现通知方法public void notify{//遍历观察者集合,调用每一个观察者的响应方法for(Object obs:observers){((Observer)obs).update();}}
}
//抽象观察者
interface Observer{//声明相应方法public void update()
}
//具体观察者
class ConcreteObserver implements Observer{实现.......
}

java.util.Observable 接口只有一个方法,充当抽象观察者 void update(Observable o, Object args)

java.util.Observable类,包含新增删除

发布者:事件源

订阅者:事件监听器

通过事件对象传递

P340 21:48 留

对象状态及其转换 状态模式

允许一个对象在其内部状态时,改变它的行为,对象看起来似乎修改了它的类

//demo1
//抽象状态类
abstract class State{//声明抽象业务方法,不同的具体状态类可以用不同的方法实现public abstarct void handle();
}
//具体状态类
class ConcreteState extends State{public void handle(){//具体方法实现代码}
}
//环境类,实际上是真正拥有状态的对象
class Context{private State state; // 维持一个对抽象状态对象的引用private int value; //其他属性值,该属性值的变化可能会导致对象状态发生变化//设置状态对象public void setState(State state){this.state = state;}public void request(){//其他代码state.handle(); //调用对象的业务方法}
}

状态的转换,2种方式:一是统一由环境类来负责

//demo2
public void changeState(){//判断属性值,根据数据值进行状态转换if(value==0){this.setState(new ConcreteStateA());}else if(value==1){this.setState(new ConcreteStateB());}
}

二是具体状态类负责

//demo3
public void changeState(Context ctx){//根据环境对象中的属性值进行状态转换if(ctx.getValue()==1){ctx.setState(new ConcreteStateB());}elseif .......
}

共享状态:定义为环境类的静态成员对象,比如开关要么开,要么关

算法的封装与切换 策略模式 policy

将每一个算法封装起来,并让它们互相切换

//demo1
//抽象策略类
abstract class AbstractStrategy{public abstract void algorithm; //声明抽象算法
}
//具体策略类
class ConcreteStrategyA extends AbstractStrategy{//算法的具体实现public void algorithm(){//算法A}
}
class Context{private AbstractStrategy strategy; //维持一个对抽象策略类的引用public void setStrategy......//setter注入//调用策略类中的算法public void algorithm(){strategy.algorithm();}
}

可插入式

模板方法模式 定义算法的框架

子类可以不改变一个算法的结构,即可重定义该算法的特定步骤

//demo1
//抽象类
abstract class AbstractClass{public void templateMethod(){  //模板方法primitiveOperation1();primitiveOperation2();primitiveOperation3();}//基本方法-具体方法public void primitiveOperation1{//实现代码}//基本方法-抽象方法public abstract void primitiveOperation2();//基本方法-钩子方法,默认为空,子类实现,或者返回布尔public void primitiveOperation3{.......}
}
class ConcreteClass extends AbstractClass{public void ~2{实现代码}public void ~3{实现代码}
}

访问者模式 操作复杂对象结构

双重分派机制

//demo1
//抽象访问类
abstract class Visitor{public abstract void visit(ConcreteElementA elementA);public abstract void visit(ConcreteElementB elementB);public void visit(ConcreteElementC elementC){//元素C操作代码}
}

使用visit重载两个方法操作A、B 具体访问类中 class ConcreteVisitor extends Visitor

//demo2
//抽象元素类
interface Element {public void accept(Visitor visitor);
}
//具体元素类
class ConcreteElementA implements Element{public void accept(Visitor visitor){visitor.visit(this);}public void operationA(){//业务方法}
}

结束 12:10 22:00留


http://www.ppmy.cn/embedded/148210.html

相关文章

VSCode:Markdown插件安装使用 -- 最简洁的VSCode中Markdown插件安装使用

VSCode&#xff1a;Markdown插件安装使用 1.安装Marktext2.使用Marktext 本文&#xff0c;将在Visual Studio Code中&#xff0c;安装和使用Markdown插件&#xff0c;以Marktext插件为例。 1.安装Marktext 打开VSCode&#xff0c;侧边栏中找到扩展模块(或CtrlShiftX快捷键)&am…

解释 Git 的基本概念和使用方式。

Git是一个分布式版本控制系统&#xff0c;它可以跟踪和管理项目中的代码变动。它具有以下基本概念和使用方式&#xff1a; 1. 仓库&#xff08;Repository&#xff09;&#xff1a;Git将代码存储在仓库中&#xff0c;仓库可以被认为是一个项目的工作空间。一个项目可以有多个仓…

Python的sklearn中的RandomForestRegressor使用详解

文章目录 Python的sklearn中的RandomForestRegressor使用详解一、引言二、RandomForestRegressor简介1、随机森林回归原理2、RandomForestRegressor的主要参数 三、构建和训练模型1、数据准备2、数据划分3、模型训练 四、模型评估1、预测2、评估指标 五、特征重要性分析六、可视…

面向微服务的Spring Cloud Gateway的集成解决方案:用户登录认证与访问控制

&#x1f3af;导读&#xff1a;本文档详细描述了一个基于Spring Cloud Gateway的微服务网关及Admin服务的实现。网关通过定义路由规则&#xff0c;利用负载均衡将请求转发至不同的后端服务&#xff0c;并集成了Token验证过滤器以确保API的安全访问&#xff0c;同时支持白名单路…

SEO初学者-SEO基础

SEO 基础SEO 初期设置SEO怎么做如何跟踪 SEO 效果免费的 SEO 工具 如果您希望人们通过 Google 找到您的网站&#xff0c;您需要了解 SEO 的基础知识。这些知识比您想象的要简单。 什么是 SEO&#xff1f; 搜索引擎优化 (SEO) 是增加网站自然搜索流量的过程。在这一过程中&am…

PostgreSQL表达式的类型

PostgreSQL表达式是数据库查询中非常重要的组成部分&#xff0c;它们由一个或多个值、运算符和PostgreSQL函数组合而成&#xff0c;用于计算出一个单一的结果。这些表达式类似于公式&#xff0c;可以用查询语言编写&#xff0c;并用于查询数据库中的特定数据集。 PostgreSQL表…

Redis篇--常见问题篇2--缓存雪崩(过期时间分散,缓存预热,多级缓存)

1、概述 缓存雪崩是指在短时间内&#xff0c;大量的缓存同时失效或过期&#xff0c;导致大量的请求穿透到后端数据库或服务&#xff0c;从而引发系统负载骤增&#xff0c;甚至可能导致系统崩溃。这种情况通常发生在缓存的过期时间设置不合理时&#xff0c;所有缓存的过期时间相…

机器学习之KNN算法

K-Nearest Neighbors (KNN) 是一种常见的机器学习算法&#xff0c;广泛应用于分类和回归问题。KNN是一种基于实例的学习方法&#xff0c;它利用训练数据集的实例来进行分类或回归预测。在KNN中&#xff0c;预测的结果依赖于距离度量函数计算出的最近邻实例的标签或值。下面我们…