一、逻辑
如上图,整个的逻辑就是这样。
二、具体的实现代码
背景:实现一个不同类型的文件解析器的功能。
文件的类型包括 AVI Mp4 PNG 三种类型
具体的解析方法,直接打印就可以了
文件类型,FileType
package study_model.chain;
public enum FileType {
AVI,
MP4,
PNG
}
文件类,MyFile
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class MyFile {
private String name;
private String path;
private FileType fileType;
}
抽象类,AbstractParser
package study_model.chain.demo1;
public abstract class AbstractParser<T> {
// 有一个属性,就是它自己
private AbstractParser<T> parser;
// 这里本质就是一个set方法
public void addParse(AbstractParser<T> parse){
this.parser = parse;
}
// 判断当前这个实现类是否能够处理
public abstract boolean isDo(T t);
// 当前实现类具体处理的方式
public abstract void doParse(T t);
//
public void parse(T t){
// 先判断是否能处理,能,则直接处理
if(isDo(t)){
doParse(t);
return;
}
if(this.parser!=null){
// 不能处理,则调用下一个解析器处理
this.parser.parse(t);
}
}
}
1、抽象类
2、抽象类的属性,就是抽象类。这样做的目的就是,将来把A节点的属性,设置成B节点,这样我们就把A节点、B节点 串起来了
3、抽象方法:判断当前实现类是否能处理,这个由子类实现
4、抽象方法:具体的处理方式
5、逻辑:判断当前实现类是否能处理,能,则直接处理。
不能处理,则调用属性(下一个节点)的处理方法
实现类,AVIParser
package study_model.chain.demo1;
import study_model.chain.FileType;
import study_model.chain.MyFile;
public class AVIParser extends AbstractParser<MyFile>{
@Override
public boolean isDo(MyFile myFile) {
return myFile.getFileType()== FileType.AVI;
}
@Override
public void doParse(MyFile myFile) {
System.out.println("avi myFile = " + myFile);
}
}
实现类,Mp4Parser
package study_model.chain.demo1;
import study_model.chain.FileType;
import study_model.chain.MyFile;
public class Mp4Parser extends AbstractParser<MyFile>{
@Override
public boolean isDo(MyFile myFile) {
return myFile.getFileType()== FileType.MP4;
}
@Override
public void doParse(MyFile myFile) {
System.out.println("mp4 myFile = " + myFile);
}
}
实现类,PNGParser
package study_model.chain.demo1;
import study_model.chain.FileType;
import study_model.chain.MyFile;
public class PNGParser extends AbstractParser<MyFile>{
@Override
public boolean isDo(MyFile myFile) {
return myFile.getFileType()== FileType.PNG;
}
@Override
public void doParse(MyFile myFile) {
System.out.println("png myFile = " + myFile);
}
}
Manager
package study_model.chain.demo1;
import study_model.chain.MyFile;
public class ParserManager {
private AbstractParser<MyFile> parser;
// 构造器,私有,不能被new
private ParserManager(){
// 构建一个调用链
Mp4Parser mp4Parser = new Mp4Parser();
AVIParser aviParser = new AVIParser();
PNGParser pngParser = new PNGParser();
// 设置 avi为mp4下一个节点
mp4Parser.addParse(aviParser);
// 设置png为avi的下一个节点
aviParser.addParse(pngParser);
parser = mp4Parser;
}
// ClassHolder属于静态内部类,在加载类Demo03的时候,只会加载内部类ClassHolder,
// 但是不会把内部类的属性加载出来
private static class ClassHolder{
// 这里执行类加载,是jvm来执行类加载,它一定是单例的,不存在线程安全问题
// 这里不是调用,是类加载,是成员变量
private static final ParserManager holder =new ParserManager();
}
public static ParserManager of(){//第一次调用getInstance()的时候赋值
return ClassHolder.holder;
}
public void parse(MyFile myFile){
parser.parse(myFile);
}
}
1、这里使用了单例模式
2、主要是将各个节点串起来。将A实现类的属性,设置成B。调用的时候,只调用A的处理就可以了。
APP
package study_model.chain.demo1;
import study_model.chain.FileType;
import study_model.chain.MyFile;
public class App {
public static void main(String[] args) {
MyFile myFile = MyFile.builder()
.name("aaa")
.path("/root/tmp")
.fileType(FileType.PNG)
.build();
ParserManager.of().parse(myFile);
}
}