模糊背景网站,镇巴作风建设网站,做彩票网站是违法的吗,php网站上线PS #xff1a;以作者的亲身来看#xff0c;这东西对于初学者来说有用但不多#xff0c;这些东西#xff0c;更像一种经验的总结#xff0c;在平时开发当中一般是用不到的#xff0c;因此站在这个角度上用处不大。 1.工厂模式
1.1 简单工厂模式
我们把new 对象逻辑封装… PS 以作者的亲身来看这东西对于初学者来说有用但不多这些东西更像一种经验的总结在平时开发当中一般是用不到的因此站在这个角度上用处不大。 1.工厂模式
1.1 简单工厂模式
我们把new 对象逻辑封装到一共工厂里,通过工厂去实例化对象。用户无需知道逻辑只需要传入对应的参数就可得到对应的对象。
坏处: 假如说我们这个Me类有个新的子类,那么我们需要对Me工厂的getMeInstance逻辑修改后面每次增加新的子类也是如此需要增加多个if else判断。一旦子类变多该方法就会变得臃肿可读性变差。 1.2 工厂方法模式
我们再看工厂方法模式,就是在工厂定义一个抽象方法,用来实例化类的。 然后每次新增加一个子类都会创建一个新的对应工厂去实现这个方法return一个新子类。
缺点: 每次增加一新的子类都会增加新的具体工厂,新的具体工厂只能创建一个具体对象。
1.3 抽象工厂模式
不同于工厂方法模式,父抽象工厂只是提供一个接口,而新的子类工厂可以去实例一种产品。 关于工厂模式,我们可以采用ava反射来实例任何一个对象。
2.单例模式
// 单例模式涉及到懒加载解决线程安全的问题。
通过线程锁、 volatile:直接操作变量主内存解决安全问题。
public class SingletonDemo {private static ReentrantLock lock new ReentrantLock(true);private static volatile SingletonDemo singletonDemo; // 考虑到副本 - 主内存引用// 双重锁检查就是考虑,内存public static SingletonDemo getInstance(){Condition condition lock.newCondition();if(singletonDemo null){lock.lock(); // 锁住防止多次实例化try {lock.lock();singletonDemo new SingletonDemo();System.out.println(我创建了);}finally {lock.unlock();}}return singletonDemo;}
3.生成器模式
理解:把一个复杂对象对创造拆分成好几个对象。
就比如说,我们常见的Http对象,我们单一个创建http对象的话由很多字段,所有我们可以给他改成HttpRequest、HttpBody、Reeuqest里面拆分成MethodContype类型等方式。
所以我们可以把他一个对象的创造拆分成好几个对象来构造。,当然一般默认会写默认字段值的这种就叫生成器模式。 一般生成器模式,喜欢加一个Builder内部类,直接用来创建外部对象。
关于内部类有什么好处? 内部类能直接访问外部的成员。
优化代码结构,相关关联的一般写成内部类。
回调机制: 将内部类作为参数作为回调参数传递给。满足条件调用回调函数。
class Main{public static void main(String[] args) {Book book Book.Builder.newBook().name(qhx).price(24);}
}
class Book {private String name;private Integer price;public Book name(String name){this.name name;return this;}public Book price(Integer price){this.price price;return this;}static class Builder{public static Book newBook(){return new Book();}}public String getName() {return name;}public void setName(String name) {this.name name;}public Integer getPrice() {return price;}public void setPrice(Integer price) {this.price price;}}4.原型模式
理解: 原型模式,就是对一个对象进行深层拷贝而已(对于对象来说,需要创建一个新对象。)。
1.比如,这个对象创建很复杂,但是我们又要用这个对象,所以直接深拷贝。
2.或者这个对象,需要多次用到多次创建又很麻烦。 关于原型模式是否能提升速率,那应该跟深拷贝的方法有关。
1.直接去 new对象然后进行手动拷贝...或者通过反射api来进行Bean拷贝。
2.将该对象通过序列化和反序列化的形式。
Book book Book.Builder.newBook().name(qhx).price(24);ByteArrayOutputStream bom new ByteArrayOutputStream();
ObjectOutputStream oom new ObjectOutputStream(bom);
oom.writeObject(book); // 写进去一个对象ByteArrayInputStream bim new ByteArrayInputStream(bom.toByteArray());
ObjectInputStream oim new ObjectInputStream(bim);
Book book1 (Book) oim.readObject();
5.适配器模式
适配器: 用于将用户希望调用的接口,实际上调用的是另一个接口。
目标接口: 定义客户端所期望的接口
适配器: 实现目标接口,并将请求转换为被适配的调用
被适配者: 需要被适配的对象
5.1 类适配器
PS : 看下面,适配器对象实现目标接口,继承了被适配对象。
这样我们调用目标接口的功能,然后实际上调用的是我们继承被适配对象的功能。
// 目标接口
interface AudioPlayer {public void play(String audioType, String fileName);
}// 被适配对象
class Mp3Player {public void playMp3(String fileName) {System.out.println(Playing mp3 file: fileName);}
}// 适配器类
class Mp3PlayerAdapter extends Mp3Player implements AudioPlayer{Overridepublic void play(String audioType, String fileName) {if(audioType.equalsIgnoreCase(mp3)){this.playMp3(fileName);}}
}
5.2 对象适配器
PS: 看下面,适配器对象已经持有被适配对象这样我们调用目标接口功能实际上调用被适配对象的功能。
// 目标接口
interface AudioPlayer {public void play(String audioType, String fileName);
}// 被适配对象
class Mp4Player{public void playMp4(String fileName){System.out.println(Playing mp4 file: fileName);}
}// 适配器
class Mp4PlayerAdapter implements AudioPlayer{private Mp4Player mp4Player;public Mp4PlayerAdapter(Mp4Player mp4Player) {this.mp4Player mp4Player;}Overridepublic void play(String audioType, String fileName) {if(audioType.equalsIgnoreCase(map)){mp4Player.playMp4(fileName);}}
}
5.3 接口适配器
PS: 当不需要实现一个接口的全部方法时,可先设计一个抽象类实现接口并为该接口中每个方法提供一个默认实现空方法那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。
// 3.接口适配器模式// 目标接口
interface EventListener {public void onEvent1();public void onEvent2();public void onEvent3();
}
// 适配器
abstract class EventListenerAdapter implements EventListener {Overridepublic void onEvent1() {}Overridepublic void onEvent2() {}Overridepublic void onEvent3() {}
}// 具体适配器模式
class MouseEventListener extends EventListenerAdapter {Overridepublic void onEvent2() {System.out.println(Mouse clicked);}
}
6.装饰者模式
理解:
跟代理模式有点类似,但是跟多强调的是对被装饰者功能的扩展。
代理模式引入一个代理对象控制对目标对象的访问,主要强调的访问控制和管理如传入参数和返回值的管理。
组成: Component抽象组件定义了被装饰对象和装饰对象的共同接口。 Concrete Component具体组件实现了抽象组件接口是被装饰的对象。 Decorator装饰者实现了抽象组件接口并持有一个抽象组件对象的引用可以动态地给组件添加额外的行为。 Concrete Decorator具体装饰者具体装饰者是具体的装饰对象通过扩展装饰者的功能给被装饰对象添加新的行为。 // 抽象组件
interface Student{void run();
}// 被装饰者
class Boy implements Student{Overridepublic void run() {System.out.println(男孩跑);}
}// 抽象装饰者
abstract class StudentPlus implements Student{protected Student student;public StudentPlus(Student student){this.student student;}Overridepublic void run() {student.run();}
}// 具体装饰者
class BoyPlus extends StudentPlus{public BoyPlus(Student student) {super(student); // 抽象类无法直接new但是有构造器,被继承new}Overridepublic void run() {student.run();bike();}private void bike(){System.out.println(骑自行车跑!);}
}
7.代理模式
理解:
代理对象和被代理对象实现同一个接口,我们调用代理对象实际上调用
被代理对象,我们实际通过代理对象对被代理对象做了一个管控,通过代理对象的接口间接调用被代理对象的接口,完成对调用参数的过滤和对响应参数管控或者扩展其他功能。 组成:
抽象主题Subject定义了目标对象和代理对象的公共接口客户端可以通过该接口访问目标对象或代理对象。
目标对象Real Subject定义了代理对象所代表的真实对象客户端最终希望访问的就是该对象。
代理对象Proxy持有一个指向目标对象的引用并实现了与目标对象相同的接口它可以在调用目标对象之前或之后执行一些额外的逻辑。
7.1 静态代理
我们要实现被代理对象的接口,每次针对被代理对象都需要创建一个代理对象。
public class ProxyMode {public static void main(String[] args) {Service serviceProxy new ServiceProxy(new ServiceImpl());serviceProxy.buyHouse();}
}
// 服务接口
interface Service{void buyHouse();
}// 服务类
class ServiceImpl implements Service{Overridepublic void buyHouse() {System.out.println(买房时);}
}// 代理类
class ServiceProxy implements Service{private Service service;public ServiceProxy(Service service) {this.service service;}Overridepublic void buyHouse() {System.out.println(买房前!);service.buyHouse();System.out.println(买房后!);}
}
7.2 动态代理
我们不用去实现代理对象,jvm在内存里,帮我们创建代理对象...
实际上,我们这种能传进任意对象,进行代理。
ServiceImpl serviceImpl new ServiceImpl();
Service serviceProxy1 (Service)Proxy.newProxyInstance(Service.class.getClassLoader(),new Class[]{Service.class}, new ServiceProxyHandler(serviceImpl)); // 代理处理器
serviceProxy1.buyHouse(); // method
// 服务接口
interface Service{void buyHouse();
}// 服务类
class ServiceImpl implements Service{Overridepublic void buyHouse() {System.out.println(买房时);}
}// 动态代理: 通过java的反射api,在jvm内存里面创建java代理对象,但是我们要实现一个代理类。
class ServiceProxyHandler implements InvocationHandler {private Object object;public ServiceProxyHandler(Object object) {this.object object;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(买房前!);Object result method.invoke(object, args);System.out.println(买房后!);return result;}}
8. 外观模式
PS :跟mvc三层架构比较像诶。 视图层View类似于外观模式中的客户端Client它负责向用户展示界面并接收用户的操作。
控制器层Controller类似于外观模式中的外观类Facade它负责处理用户的操作并调用相应的业务逻辑。
模型层Model则类似于外观模式中的子系统Subsystems它包含了应用的业务逻辑和数据访问接口。
理解:
假如说,我们要操作某银行系统实现一个效果:存钱打开账户,输入存入金额,点击存钱...这个方法是不是很多..
因此,我们可以新建一个外观类,把这些接口统统封装,并对外暴露一个接口存钱接口,用户通过客户端类调用这个接口传入参数就能达到这个效果。 层级: 系统类 - 外观类 - 客户端类。
组成: 外观类Facade外观类是外观模式的核心它提供了一个简单的接口用来访问子系统中的一群接口。外观类将客户端与子系统之间的复杂交互关系封装在内部对客户端隐藏了子系统的复杂性。 子系统Subsystems子系统是指外观类所封装的一组接口用来实现某个复杂的功能。子系统可以包含多个类但对于客户端来说只需要知道外观类提供的简单接口即可。 客户端Client客户端是调用外观类的代码它通过外观类提供的简单接口来和系统进行交互。 // 子系统A
class SubSystemA {public void operationA() {System.out.println(SubSystemA: operationA);}
}// 子系统B
class SubSystemB {public void operationB() {System.out.println(SubSystemB: operationB);}
}// 外观类
class Facade {private SubSystemA subSystemA;private SubSystemB subSystemB;public Facade() {subSystemA new SubSystemA();subSystemB new SubSystemB();}public void operation() {subSystemA.operationA();subSystemB.operationB();}
}// 客户端
class Client {public static void main(String[] args) {Facade facade new Facade();facade.operation();}
}
9. 桥接模式
理解:
一个系统有多个功能,每个功能都有各自的接口/抽象类和他们的实现类/继承类,他们之间通过聚合的方式在一起组成完整的一个系统: 桥接模式是他们直接的具体实现。 组成 Abstraction抽象类定义抽象类的接口维护一个指向Implementor的指针(引用实例)。 RefinedAbstraction扩充抽象类扩展抽象类接口通常通过对抽象类进行子类化来实现[就是抽象类的实现类]。 Implementor实现类接口定义实现类的接口这个接口不一定要与Abstraction的接口完全一致。实际上这两个接口可以完全不同。 ConcreteImplementor具体实现类实现Implementor接口提供具体的实现。 举例:
下面的手机和软件之间的关系。手机有不同的品牌,软件也有不同;
他们的种类各自有个抽象类/接口,Software有个run()方法,然后AppStore和Wx分别有他们的run(),
我们在Phone的抽象类中,拿到了Softaware的引用,并且我能通过setSoftware()传进不同的software实现类,来达到启动不同软件的效果。
Phone apple new Apple();
apple.setSoftware(new Wx());Apple apple1 new Apple();
apple1.setSoftware(new AppStore());interface Software{void run();
}class AppStore implements Software{Overridepublic void run() {System.out.println(商店启动!);}
}class Wx implements Software{Overridepublic void run() {System.out.println(微信启动);}
}abstract class Phone{protected Software software;public void setSoftware(Software software) {this.software software;}abstract public void run();}class Apple extends Phone{Overridepublic void run() {software.run();}
}
10. 组合模式
理解:
组合结构中的类,是整体和部分之间的关系。如: 文件(叶节点)和文件夹(容器节点), 文件夹里面能包含文件和文件夹。
组成 组件Component定义了组合中对象的通用接口可以是抽象类或接口。它声明了一些操作方法如添加、删除、获取子组件等这些方法可以有默认实现。叶节点Leaf代表组合中的叶子对象它没有子组件。叶节点是组合结构的最基本单元通常实现组件接口的方法。容器节点Composite代表组合中的容器对象它可以包含其他子组件。容器节点实现了组件接口并提供了添加、删除、获取子组件等方法。 // 文件夹 - 文件之间: 表示整体和部分之间。 一个文件夹,里面包括多个文件
// 客户端可以一致的对待单个对象和组合对象,因为接口是一样的???
// 扩展很容易: 增加新的组件类型,符合开闭原则,在不用改变现有代码的情况下,能够对public class CompositeMode {}// 组件: 定了组合中对象的通用接口。可以是抽象类或其他接口
interface FileSystemComponent{void printName();int getSize();}// 文件类: 叶节点,他没有子组件,是组合结构中的基本单元,通常实现组件接口的方法。
class File implements FileSystemComponent{private String name;private int size;Overridepublic void printName() {System.out.println(File: name);}Overridepublic int getSize() {return size;}
}
// 文件夹类: 容器节点,代表组合中的容器对象,可以包含其他子组件。容器节点也实现了组件接口,并提供了add/remove/select等方法。
class Folder implements FileSystemComponent{private String name;private ListFileSystemComponent children;public boolean addComponent(FileSystemComponent fileSystemComponent){return children.add(fileSystemComponent);}public boolean removeComponent(FileSystemComponent fileSystemComponent){return children.remove(fileSystemComponent);}public FileSystemComponent selectComponent(int index){return children.get(index);}public Folder(String name) {this.name name;this.children children new ArrayList();}Overridepublic void printName() {System.out.println(Folder: name);for (FileSystemComponent child : children) {child.printName();}}Overridepublic int getSize() {int totalSize 0;for (FileSystemComponent child : children) {totalSize child.getSize();}return totalSize;}
}11.享元模式
理解:
享元工厂创建享元对象,传入内部状态。享元工厂通过内部状态判断享元对象是否存在存在不创建存在创建。根据享元状态创建的享元对象,传入外部参数。
PS: 因为有大量对象,创建太多会占用内存。因此通过享元模式,我们的将享元对象分为内部状态和外部状态。内部状态,可以理解为是属性;而外部状态,就是通过方法传入的参数之类的。享元工厂负责创建和管理享元对象,通过一个池(集合)存储已经创建好的享元对象,确保对象的共享和复用。
组成: 抽象享元Flyweight定义享元对象的接口声明需要接收外部状态参数的方法。 具体享元Concrete Flyweight实现抽象享元接口存储并管理内部状态。 享元工厂Flyweight Factory负责创建和管理享元对象通过一个池如集合来存储已经创建的享元对象确保对象的共享和复用。 客户端Client使用享元对象的客户端维护外部状态并将其传入享元对象。 优点: 减少内存使用通过共享对象的内部状态减少相同或相似对象的数量从而减少内存的使用。 提高性能共享对象可以被多个客户端同时使用减少了对象的创建和销毁的开销提高了系统的性能。 简化对象结构享元模式将对象的状态分为内部状态和外部状态简化了对象的结构使得对象更加轻量级。 // 客户端
public class FlyweightMode {public static void main(String[] args) {Car car1 CarFactory.getCar(长安一号, ChangAn);Car car2 CarFactory.getCar(长安二号, ChangAn);Car car3 CarFactory.getCar(长安二号, ChangAn);car1.run(小王);car2.run(小红);car3.run(小白);}
}
// 抽象享元
interface Car{void run(String driver);
}// 享元实体类
class ChangAn implements Car{private String carName;public ChangAn(String carName) {this.carName carName;}Overridepublic void run(String driver) {System.out.println(driver 开着, carName);}
}// 享元工厂
class CarFactory{private static MapString,Car carMap new HashMap();private CarFactory(){}public static Car getCar(String carName,String type){Car car carMap.get(carName);if(car null){if(type.equals(ChangAn)){car new ChangAn(carName);carMap.put(carName,car);}}return car;}
}
12.策略模式
理解:
通过外包一层,隔绝算法的实现和算法的调用。用户只需要知道怎么使用该接口,并得到什么算法实现的结果。
定义:
它定义了一系列的算法将每个算法封装起来并使它们可以互相替换。通过这种方式客户端程序不需要知道每个算法背后的具体实现而只需要选择合适的算法并调用。
组成: 策略接口Strategy Interface用于定义所有支持的算法的公共接口客户端通过该接口调用算法。 具体策略类Concrete Strategy Class实现策略接口包含了具体的算法实现逻辑。 环境类Context Class包含一个策略对象并提供一个调用策略的方法客户端通过环境类来调用不同的算法。 public class StrategyMode {public static void main(String[] args) {// 根据跟工厂模式,唯一大的不同,工厂模式,他给我们创建对象;策略模式是我们自己创建对象Environment environment new Environment(new QQStrategy());environment.writeData();Environment environment1 new Environment(new WxStrategy());environment1.writeData();}
}// 策略接口
interface Strategy{void write();
}// 具体策略类
class QQStrategy implements Strategy{Overridepublic void write() {System.out.println(数据写入QQ!);}
}class WxStrategy implements Strategy{Overridepublic void write() {System.out.println(数据写入微信!);}
}// 环境类
class Environment {private Strategy strategy;public Environment(Strategy strategy) {this.strategy strategy;}public void writeData(){strategy.write();}
}
13.模版模式
理解:
通过父类定义模版方法,定义抽象方法,由子类去实现这些抽象方法,完成算法结构的实现。
组成: 抽象父类AbstractClass实现了模板方法定义了算法的骨架。 具体类ConcreteClass)实现抽象类中的抽象方法即不同的对象的具体实现细节。 public class TemplateMode {public static void main(String[] args) {People wang new WangPeople();wang.run();}
}
// 抽象父类:定义类的骨架
abstract class People{void run(){this.laShen();this.PaoBu();}abstract void laShen();abstract void PaoBu();}// 具体类: 去实现抽象父类的骨架
class WangPeople extends People{Overridevoid laShen() {System.out.println(小王拉伸);}Overridevoid PaoBu() {System.out.println(小王跑步!);}
}
14.观察者模式
理解:
就是当一个被观察者对象的状态发生改变时,会通知其他观察者对象发生改变。
使用场景 事件驱动编程。观察者模式是事件驱动编程的一种常用实现方式它通过将 事件源和事件处理分离 使得事件源不必知道哪些对象对其状态感兴趣而只需将事件通知给所有已注册的观察者对象即可。 GUI界面开发。在GUI界面开发中用户通过某种操作或输入改变了界面上的控件状态这些状态改变将会被触发并通知给相应的观察者对象观察者对象根据状态变化来做出相应的更新操作从而实现界面的实时更新。 消息队列系统。消息队列系统通常需要处理大量的异步消息这些消息可能来自于不同的发送者而每个发送者又可能有多个接收者。观察者模式可以帮助消息队列系统管理和分发这些消息保证它们能够被正确地传递和处理。 数据库连接池。在数据库连接池中观察者模式可以用来监测数据库连接的状态当某个连接出现问题时观察者模式可以及时通知其他连接池对象进行处理从而保证整个连接池的可用性。 订阅系统。订阅系统是指允许用户订阅某个主题或频道并接收相关信息或内容的系统。观察者模式可以用来实现订阅系统中的事件通知和内容分发功能从而使得用户能够及时获取到他们感兴趣的信息或内容。 看下面,假如window系统启动时,通知cpu日志和风扇(fs)日志的观察者打印info信息。// 或者说,一台电脑启动,被CPU和风扇的事件监听器监听,监听到之后通知CPU和风扇启动。
public class ObserverMode {public static void main(String[] args) {SystemRunLog systemRunLog1 new SystemRunLog();SystemRunLog systemRunLog2 new SystemRunLog();WinSystem winSystem new WinSystem();winSystem.addLog(systemRunLog1);winSystem.addLog(systemRunLog2);winSystem.run();}
}
// 主题
interface SystemP{void run();
}// 具体主题
class WinSystem implements SystemP{ListLog list;public WinSystem() {this.list new ArrayList();}Overridepublic void run(){systemRunInfoLog();}private void systemRunInfoLog() {for (Log log : list) {log.info(启动-);}}// 负责管理观察者public boolean addLog(Log log){return list.add(log);}public boolean removeLog(Log log){return list.remove(log);}}// 观察者
interface Log{void info(String mes);void error(String mes);
}// 具体观察者
class CpuRunLog implements Log{Overridepublic void info(String mes) {System.out.println(cpu info: mes);}Overridepublic void error(String mes) {System.out.println(cpu error: mes);}
}class FsRunLog implements Log{Overridepublic void info(String mes) {System.out.println(fs info: mes);}Overridepublic void error(String mes) {System.out.println(fs error: mes);}
}
15.迭代器模式
理解:
提供一种顺序访问聚合对象中各个元素的方法,而不需要暴露聚合对象的内部表示。
什么是聚合对象?
聚合对象 负责存储和管理一组元素并提供一种方式来获取迭代器对象从而使得外部客户端可以通过迭代器访问和遍历聚合对象中的元素而不必了解其内部表示和结构。
适用场景? 集合类例如列表、数组等需要遍历元素的容器类。 数据库查询结果集当需要逐行处理数据库查询结果时可以使用迭代器模式来遍历结果集。 文件解析当需要逐行读取文件内容时可以使用迭代器模式来实现逐行解析。 public class IteratorMode {public static void main(String[] args) {ArrayListString objects new ArrayList();objects.add(qhx);objects.add(qhx);objects.add(qhx);Aggregate concreteAggregate new ConcreteAggregate(objects);IteratorString iterator concreteAggregate.createIterator();while (iterator.hasNext()){Object next iterator.next();System.out.println(next);}}
} // 迭代器接口
interface IteratorT{T next();boolean hasNext();
}// 具体迭代器
class ConcreteIteratorT implements IteratorT{private ListT list;private int index;public ConcreteIterator(ListT list) {this.list list;this.index 0;}Overridepublic T next() {if(hasNext()){return list.get(index);}return null;}Overridepublic boolean hasNext() {return index list.size();}
}// 聚合类
interface Aggregate {Iterator createIterator();
}// 具体聚合类
class ConcreteAggregateT implements Aggregate {private ListT list;public ConcreteAggregate(ListT list) {this.list list;}Overridepublic Iterator createIterator() {return new ConcreteIterator(list);}
}
16.责任链模式
理解:
允许多个对象按照顺序处理请求。在这个模式中每个对象都有机会处理请求可以选择自己处理或者将其传递给链中的下一个对象。这样请求就能在一系列对象之间传递直到有一个对象处理它为止。也就是多个对象成链状组装在一起共同处理事务当满足条件的事务对象就会处理不满足就向下一个对象传递。
组成: 抽象处理者Handler定义一个处理请求的接口并包含一个对下一个处理者的引用。它可以是抽象类或接口规范处理者的行为。 具体处理者Concrete Handler继承自抽象处理者实现处理请求的方法。每个具体处理者都会根据自己的能力来判断是否能够处理该请求如果能够处理则进行处理否则将请求传递给下一个处理者。 客户端Client创建处理者对象并组成责任链将请求发送给链的第一个处理者。 //假设我们有一个购买审批系统需要按照不同的金额级别对购买请求进行审批。
public class ResponsibilityChainMode {public static void main(String[] args) {ClientL clientL new ClientL();clientL.sendRequest(5000);}
} // 客户端:负责用户发送请求
class ClientL {private Handler firstHandler;public ClientL() { // 创建客户端时,就初始化责任链()this.firstHandler new ManagerHandler();Handler handler2 new DirectorHandler();firstHandler.setNextHandler(handler2);}// 发送请求void sendRequest(int amount){firstHandler.handlerRequest(new PurchaseRequest(amount));}
}// 抽象处理着:拿到下个处理着的引用、处理请求的方法
abstract class Handler{public Handler nextHandler;public void setNextHandler(Handler nextHandler) {this.nextHandler nextHandler;}public abstract void handlerRequest(PurchaseRequest request);
}// 具体处理着经理
class ManagerHandler extends Handler{Overridepublic void handlerRequest(PurchaseRequest request) {if(request.amount 1000){System.out.println(Manager 可以处理!);}else if(nextHandler ! null){ // 传给nextHandler.handlerRequest((request));}}
}// 具体处理着管理者
class DirectorHandler extends Handler{Overridepublic void handlerRequest(PurchaseRequest request) {if(request.amount 5000){System.out.println(Director 可以处理!);}else if(nextHandler ! null){ // 传给nextHandler.handlerRequest((request));}}
}// 请求
class PurchaseRequest {Integer amount; // 金额public PurchaseRequest(Integer amount) {this.amount amount;}
}17.命令模式
组成: 命令Command定义了执行操作的接口包括一个执行方法通常为 execute() 具体命令Concrete Command实现了命令接口将一个接收者对象绑定到一个动作并在执行方法中调用接收者的相关操作。 接收者Receiver执行实际操作的对象。命令对象将请求委派给接收者来执行具体的操作。 调用者Invoker持有命令对象并调用其执行方法来触发请求操作。 客户端Client创建具体命令对象并将其与接收者关联起来然后将命令对象交给调用者进行处理。 ps:行为请求者不应该依赖于单个具体的行为实现者而是应该通过抽象接口或中介对象来间接地调用实现者。
举例
假设我们有一个家电控制系统其中包括电视、音响和灯光等设备。现在我们希望实现一个遥控器可以通过按钮来控制不同的设备例如打开电视、关闭音响、调暗灯光等操作。
public class CommandMode {public static void main(String[] args) {RemoteControl remoteControl new RemoteControl();TVCommand tvCommand new TVCommand();TV tv new TV();tvCommand.setTv(tv);remoteControl.setCommand(tvCommand);remoteControl.pressButton();}
}
// 定义一个命令抽象类
interface Command {void execute();
}// 针对电视设备的具体命令类。
class TVCommand implements Command{private TV tv;public void setTv(TV tv) {this.tv tv;}Overridepublic void execute() {tv.run();}
}// 电视设备(命令接受者)
class TV {public void run(){System.out.println(电视启动);}
}// 电视遥控器(命令调用者)
class RemoteControl {private Command command;public void setCommand(Command command) {this.command command;}public void pressButton(){command.execute();}
}
好像明白了,命令模式,还是遵循一个调用实例拿到一个抽象对象的引用。
只不过,你看上述,设备抽象接口化好像不太合适,因此中间又加了一层命令抽象化,电视控制器调用具体的命令实现。命令实现拿着具体设备的引用。
进而 遥控器 - 命令 - 设备。
18.状态模式
组成: Context上下文上下文是一个包含状态对象的类它可以 调用状态对象的方法并在状态对象内部状态发生改变时更新自身的状态。 State状态状态是一个接口或抽象类定义了具体状态需要实现的方法。具体的状态类通过继承和实现来实现这些方法。 Concrete State具体状态具体状态是状态接口的不同实现每个具体状态都有自己的行为。 理解
上下文对象持有状态类,而上下文的行为,依赖于状态类(属性),状态的改变会影响上下文对象的行为改变。
PS:也就是说跟策略模式的实现逻辑类似,只不过客观主体不同那个在于能调用不同的策略,而这个在于包装对象的行为,依赖于不同状态对象的行为。
public class StateMode {public static void main(String[] args) {Order order new Order(new PendingPaymentState());order.processOrder(); // 输出订单待支付order.setState(new PaidState());order.processOrder(); // 输出订单已支付order.setState(new ShippedState());order.processOrder(); // 输出订单已发货}
}
// 状态接口
interface State {void handle();
}// 具体状态类待支付状态
class PendingPaymentState implements State {public void handle() {System.out.println(订单待支付);// TODO: 处理待支付状态的逻辑}
}// 具体状态类已支付状态
class PaidState implements State {public void handle() {System.out.println(订单已支付);// TODO: 处理已支付状态的逻辑}
}// 具体状态类已发货状态
class ShippedState implements State {public void handle() {System.out.println(订单已发货);// TODO: 处理已发货状态的逻辑}
}// 上下文类订单
class Order {private State state;public Order(State state) {this.state state;}public void setState(State state) {this.state state;}public void processOrder() {state.handle();}
}
19.备忘录(快照)模式
理解:
有时候需要记录某个时刻的状态,并且在之后去恢复这个状态。
也就是说,备忘录模式提供了一种状态恢复的一种方案。
PS:遵循单一责任原则,每个类根据责任划分,符合解耦,而且这样代码阅读性比较高。
组成: 发起人Originator它是 拥有内部状态的对象需要保存和恢复状态 。它提供了创建备忘录对象以及从备忘录对象中恢复状态的方法。 备忘录Memento它是用于存储发起人对象内部状态的对象。备忘录可以包含发起人对象的部分或全部状态信息。 管理者Caretaker它负责存储备忘录对象以便在需要时进行检索和管理。 案列:
public class MementoMode {public static void main(String[] args) {TextEditor editor new TextEditor();TextStateManager stateManager new TextStateManager();LinkedListObject objects new LinkedList();editor.setText(Hello, World!); // 设置文本stateManager.saveState(editor); // 保存状态editor.setText(Hello, GPT-3.5!); // 修改文本System.out.println(editor.getText()); // 输出Hello, GPT-3.5!stateManager.restoreState(editor); // 恢复状态System.out.println(editor.getText()); // 输出Hello, World!}
}
// 发起人(文本编辑器类)
class TextEditor{private String text;public void setText(String text) {this.text text;}public String getText() {return text;}public void restore(Memento memento) {text memento.getText();}
}// 备忘录文本状态类
class Memento {private String text;public Memento(String text) {this.text text;}public String getText() {return text;}
}// 管理者文本状态管理类
class TextStateManager {private StackMemento stack new Stack();public void saveState(TextEditor textEditor) {stack.push(new Memento(textEditor.getText()));}public void restoreState(TextEditor textEditor) {if (!stack.isEmpty()) {textEditor.restore(stack.pop());}}
}
20.访问者模式
理解:
针对访问者对不同元素的访问,提供给了不同代码操作;因此,实际上我们考虑访问者(用户调用)和被访问元素类的解耦。
组成 抽象访问者Visitor定义了对每个具体元素ConcreteElement访问时所产生的具体行为。它包含了访问者的核心逻辑即具体业务方法用于访问并处理不同类型的元素对象。 具体访问者ConcreteVisitor实现了抽象访问者Visitor所定义的接口即定义了对每个具体元素ConcreteElement访问时所产生的具体行为。它通过重写抽象访问者中的具体业务方法实现了对不同类型的元素对象的访问和处理。 抽象元素Element定义了一个accept()方法该方法接受一个访问者Visitor作为参数并调用该访问者的visit()方法来实现对该元素的访问。它是被访问的对象的抽象表示其中包含了具体访问者所需要的数据。 具体元素ConcreteElement实现了抽象元素Element所定义的接口即实现了accept()方法。它是被访问的对象的具体表示其中包含了具体访问者所需要的数据。 对象结构Object Structure定义了一个容纳元素对象的集合并提供了一些基本操作如添加、删除、遍历等。它可以是一个复杂的数据结构或一个简单的集合其中包含了各种类型的元素对象。 实例:
public class VisitorMode {public static void main(String[] args) {// 但是,针对每种设计模式,我才遵循思想,不遵循绝对设计原则ConcreteVisitor concreteVisitor new ConcreteVisitor();ConcreteElementA concreteElementA new ConcreteElementA();concreteElementA.accept(concreteVisitor);// 针对访问了不同元素,提供了不同的行为逻辑。}
}// 抽象访问者:定义了针对某个具体元素访问所产生的具体行为
interface Visitor {void visit(ConcreteElementA element);void visit(ConcreteElementB element);
}// 具体访问者
class ConcreteVisitor implements Visitor {Overridepublic void visit(ConcreteElementA element) {System.out.println(Visitor is visiting ConcreteElementA);// 对ConcreteElementA进行具体的操作}Overridepublic void visit(ConcreteElementB element) {System.out.println(Visitor is visiting ConcreteElementB);// 对ConcreteElementB进行具体的操作}
}// 抽象元素: 定义了一个accept()方法,该方法以访问者作为参数,调用visitor方法来完成元素的访问。
interface Element{void accept(Visitor visitor);
}// 具体元素A
class ConcreteElementA implements Element{Overridepublic void accept(Visitor visitor) {visitor.visit(this);}
}// 具体元素B
class ConcreteElementB implements Element {Overridepublic void accept(Visitor visitor) {visitor.visit(this);}
}// 对象结构:定义了一个容纳元素对象的集合
class ObjectStructure {private ListElement elements new ArrayList();public void addElement(Element element) {elements.add(element);}public void removeElement(Element element) {elements.remove(element);}public void accept(Visitor visitor) {for (Element element : elements) {element.accept(visitor);}}
}
21.中介者模式
// 谈谈我对集中处理和分布式处理的理解,集中处理的好处是,所有文件集中配置,肯定好管理,但是一旦项目大了,需要集中的东西业也越来越多,和这个时候,我们再集中处理代码可读性不高,因此我们可以按照功能、业务划分模块,在这个模块,我们再集中一起处理,这样代码可读性明显更高!!
为服务,就是在此基础上形成的,代码量变大,针对每个功能模块单独成分成一个模块(一般是直接打包成为一个服务!)。
理解:
中介者模式适用于对象之间存在复杂的交互关系且希望减少对象之间的直接耦合的情况。通过引入中介者对象可以将对象之间的交互逻辑进行集中和封装提高系统的灵活性和可维护性。
一群对象,通过中介者类进行互相交通信?
组成: 中介者Mediator 定义了对象之间的协调和通信接口通常包含多个通信方法用于处理不同的交互场景。中介者对象持有对各个对象的引用负责将接收到的请求转发给合适的对象进行处理。 具体中介者Concrete Mediator 实现了中介者接口负责实际的协调和通信逻辑。它通常需要了解并持有对各个相关对象的引用以便根据不同的交互情况进行适当的分发和转发。 同事类Colleague 表示一个参与交互的对象每个同事类都知道中介者对象并且与其他同事类通过中介者进行通信。同事类之间可以有不同的实现但它们之间不直接交互而是通过中介者进行间接通信。 具体同事类Concrete Colleague 实现了同事类接口负责实际的业务逻辑并通过中介者对象来与其他同事类进行通信和协调。 代码:
public class MediatorMode {public static void main(String[] args) {// 用户先注册聊天室ChatRoomMediator chatRoom new ChatRoom();User qhx new User(qhx, chatRoom);User wls new User(wls, chatRoom);User wxh new User(wxh, chatRoom);chatRoom.addUser(qhx);chatRoom.addUser(wls);chatRoom.addUser(wxh);qhx.send(hello!);}
}// 中介者接口
interface ChatRoomMediator {public void sendMessage(String message, User user);public void addUser(User user);
}// 具体中介者
class ChatRoom implements ChatRoomMediator {private ListUser users;public ChatRoom() {this.users new ArrayList();}Overridepublic void sendMessage(String message, User user) {for (User u : users) {if (u ! user) {u.receive(message);}}}Overridepublic void addUser(User user) {this.users.add(user);}
}// 同事类
class User {private String name;private ChatRoomMediator chatRoom;public User(String name, ChatRoomMediator chatRoom) {this.name name;this.chatRoom chatRoom;}public void send(String message) {chatRoom.sendMessage(message, this);}public void receive(String message) {System.out.println(name received message: message);}
}