政务网站建设云计算中心/沈阳关键词seo排名
目录
一、需求介绍
二、实现过程
1. 工厂方法中已经存在的类
2.工厂方法之外的其他业务类
三、总结提升
一、需求介绍
我们在学习设计模式的时候都接触过事件与委托,也都学习过工厂三兄弟:简单工厂、 工厂方法和抽象工厂。我们就拿工厂方法来说,每个运算类的工厂百分之八十的内容都是一样的。这样就引起了我们通过模板动态的生成工厂类, 想用哪个运算就生成哪个运算对应的工厂然后执行就可以了。实现的方式有很多种,我们今天通过使用事件与委托的形式进行实现,也就是当我们有一个类添加进来之后我们就会触发自动创建工厂的方法。也就相当于我们把自动创建工厂的方法通过委托注册到了事件当中。
二、实现过程
整体结构
1. 工厂方法中已经存在的类
工厂接口
package AutomaticCreateFactoryzhuce;/*** @BelongsProject: DesignPattern* @BelongsPackage: FactoryMethod* @Author: Administrator* @Description: 描述什么人干什么事儿* @CreateTime: 2023-03-08 22:36* @Version: 1.0*/
public interface IFactory {Operation createOperation();
}
运算类工厂(其他工厂基本上是一样的):目前没有加法类的工厂我们后面会添加加法类工厂然后热加载运行
package AutomaticCreateFactoryzhuce.OperationFactory;import AutomaticCreateFactoryzhuce.IFactory;
import AutomaticCreateFactoryzhuce.Operation;
import AutomaticCreateFactoryzhuce.OperationSubclass.OperationDiv;public class DivFactory implements IFactory {/*** @Author:Wuzilong* @Description: 除法运算类* @CreateTime: 2023/4/7 8:22* @param: * @return: **/@Overridepublic Operation createOperation() {return new OperationDiv();}
}
运算父类
package AutomaticCreateFactoryzhuce;import lombok.Data;/*** @BelongsProject: DesignPattern* @BelongsPackage: SimpleFactory* @Author: Wuzilong* @Description: 运算父类* @CreateTime: 2023-03-07 11:12* @Version: 1.0*/
@Data
public class Operation {private double numberA=0;private double numberB=0;public double getResult() throws Exception {double result=0;return result;}
}
运算子类
package AutomaticCreateFactoryzhuce.OperationSubclass;import AutomaticCreateFactoryzhuce.Operation;/*** @BelongsProject: DesignPattern* @BelongsPackage: SimpleFactory* @Author: Wuzilong* @Description: 除法类* @CreateTime: 2023-03-07 11:20* @Version: 1.0*/public class OperationDiv extends Operation {@Overridepublic double getResult() throws Exception {double result=0;result=getNumberA()/getNumberB();return result;}
}
2.工厂方法之外的其他业务类
编译类:将java文件编译成class文件,方便创建出来反射的时候使用
package AutomaticCreateFactoryzhuce;import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;/*** @BelongsProject: DesignPattern* @BelongsPackage: AutomaticCreateFactoryV2* @Author: Wuzilong* @Description: 将java文件编译成class文件* @CreateTime: 2023-03-18 22:15* @Version: 1.0*/public class Compiler extends ClassLoader {public void compiler(String compilerPath,String javaPath){JavaCompiler javac = ToolProvider.getSystemJavaCompiler();int status = javac.run(null, null, null, "-d",compilerPath,javaPath);if(status!=0){System.out.println("没有编译成功!");}}
}
自动创建工厂和客户端类
package AutomaticCreateFactoryzhuce;import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;/*** @BelongsProject: DesignPattern* @BelongsPackage: AutomaticCreateFactory* @Author: Wuzilong* @Description: 自动创建工厂和客户端类* @CreateTime: 2023-03-15 16:57* @Version: 1.0*/public class CreateClass {public void createClass() throws Exception {// 工厂文件模板String factoryTemplate = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//Template//FactoryTemplate";//客户端文件模板String clientTemplate ="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//Template//ClientTemplate";//运算子类的抽象类名String className = "FactoryTemplate";//运算子类中要实例化的类的抽象类名String reClass="OperationClass";//客户端的抽象类名String clientName="Client";//客户端中要实例化的类的抽象类名String newName="OperFactory";//创建工厂的方法createFile(factoryTemplate,className,reClass);//创建客户端的方法createFile(clientTemplate,clientName,newName);}public void createClass(String newClassName) throws Exception {// 工厂文件模板String factoryTemplate = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//Template//FactoryTemplate";//客户端文件模板String clientTemplate ="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//Template//ClientTemplate";//运算子类的抽象类名String className = "FactoryTemplate";//运算子类中要实例化的类的抽象类名String reClass="OperationClass";//客户端的抽象类名String clientName="Client";//客户端中要实例化的类的抽象类名String newName="OperFactory";//创建工厂的方法createFile(factoryTemplate,className,reClass,newClassName);//创建客户端的方法createFile(clientTemplate,clientName,newName,newClassName);}private static void createFile(String filePath,String className,String reClass) throws Exception {String packagePath="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//OperationSubclass//";//反射的类路径List<String> classPath=new ArrayList();//要创建的java类的名字List<String> target=new ArrayList<>();File file = new File(packagePath);//判断是不是文件夹if (file.isDirectory()){File[] files = file.listFiles();for (int i=0; i<files.length;i++){String fileNamePath=files[i].getAbsolutePath();if (files[i].getAbsolutePath().endsWith(".java")){String operClassPath = fileNamePath.substring(fileNamePath.indexOf("OperationSubclass"), fileNamePath.indexOf(".java"));String createClassName = operClassPath.replace("OperationSubclass\\", "");target.add(createClassName);classPath.add("AutomaticCreateFactoryzhuce.OperationSubclass."+createClassName);}}}// 创建java类的存放路径String targetURL = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//OperationFactory//";//存放class文件的路径String classURL="D://项目//设计模式//Java//DesignPattern//target//classes//";int isClient=0;for (int i = 0; i < target.size(); i++) {try {BufferedReader bufReader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));//数据流读取文件//StringBuffer动态的字符串数组StringBuffer strBuffer = new StringBuffer();//将java编译成class的类Compiler compiler = new Compiler();//截取计算类的后三位String substring = target.get(i).substring(target.get(i).length() - 3);String classNameStr=substring+"Factory";for (String temp = null; (temp = bufReader.readLine()) != null; temp = null) {//判断当前行是否存在想要替换掉的字符if(temp.contains(className)){if (className.contains("Client")){//替换类名temp = temp.replace(className, classNameStr+"Client");}else{//替换类名temp = temp.replace(className, classNameStr);}}else if(temp.contains(reClass)){if (reClass.contains("Factory")){//替换返回需要实例化的类名temp = temp.replace(reClass, classNameStr);isClient+=1;}else{Class classObject=null;try{classObject = Class.forName(classPath.get(i));}catch (Exception e){compiler.compiler(classURL,packagePath+target.get(i)+".java");classObject = Class.forName(classPath.get(i));}//反射获取计算类的名称//替换返回需要实例化的类名temp=temp.replace(reClass, classObject.getSimpleName());}}//把读取的每一行添加到数组中strBuffer.append(temp);//换行符strBuffer.append(System.getProperty("line.separator"));}bufReader.close();PrintWriter printWriter = null;String createClassName=null;if (isClient>0){//创建java对象并存放在对应的路径当中printWriter = new PrintWriter(targetURL+classNameStr+"Client"+".java");createClassName=targetURL+ classNameStr+"Client"+".java";}else{printWriter = new PrintWriter(targetURL+classNameStr+".java");createClassName=targetURL+ classNameStr+".java";}//将获取数据的数组写入到创建的java对象中printWriter.write(strBuffer.toString().toCharArray());printWriter.flush();printWriter.close();compiler.compiler(classURL,createClassName);} catch (Exception e) {e.printStackTrace();}}}private static void createFile(String filePath,String className,String reClass,String newClassName) {String packagePath="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//OperationSubclass//";// 创建java类的存放路径String targetURL = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//OperationFactory//";//存放class文件的路径String classURL="D://项目//设计模式//Java//DesignPattern//target//classes//";int isClient=0;try {BufferedReader bufReader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));//数据流读取文件//StringBuffer动态的字符串数组StringBuffer strBuffer = new StringBuffer();//将java编译成class的类Compiler compiler = new Compiler();//截取计算类的后三位String substring =newClassName.substring(newClassName.length() - 3);String classNameStr=substring+"Factory";for (String temp = null; (temp = bufReader.readLine()) != null; temp = null) {//判断当前行是否存在想要替换掉的字符if(temp.contains(className)){if (className.contains("Client")){//替换类名temp = temp.replace(className, classNameStr+"Client");}else{//替换类名temp = temp.replace(className, classNameStr);}}else if(temp.contains(reClass)){if (reClass.contains("Factory")){//替换返回需要实例化的类名temp = temp.replace(reClass, classNameStr);isClient+=1;}else{newClassName=newClassName.replace("//",".");Class classObject=null;try{classObject = Class.forName(newClassName);//新创建出来的类的相对路径}catch (Exception e){compiler.compiler(classURL,packagePath+newClassName+".java");classObject = Class.forName(newClassName);}//反射获取计算类的名称//替换返回需要实例化的类名temp=temp.replace(reClass, classObject.getSimpleName());}}//把读取的每一行添加到数组中strBuffer.append(temp);//换行符strBuffer.append(System.getProperty("line.separator"));}bufReader.close();PrintWriter printWriter = null;String createClassName=null;if (isClient>0){//创建java对象并存放在对应的路径当中printWriter = new PrintWriter(targetURL+classNameStr+"Client"+".java");createClassName=targetURL+ classNameStr+"Client"+".java";}else{printWriter = new PrintWriter(targetURL+classNameStr+".java");createClassName=targetURL+ classNameStr+".java";}//将获取数据的数组写入到创建的java对象中printWriter.write(strBuffer.toString().toCharArray());printWriter.flush();printWriter.close();compiler.compiler(classURL,createClassName);} catch (Exception e) {e.printStackTrace();}}}
创建类的模板:当前使用的是txt文件,也可以使用其他文件例如mv等
运算子类
package AutomaticCreateFactoryzhuce.OperationFactory;import AutomaticCreateFactoryzhuce.IFactory;
import AutomaticCreateFactoryzhuce.Operation;
import AutomaticCreateFactoryzhuce.OperationSubclass.OperationClass;public class FactoryTemplate implements IFactory {@Overridepublic Operation createOperation() {return new OperationClass();}
}
每个运算类对应的客户端模板
package AutomaticCreateFactoryzhuce.OperationFactory;import AutomaticCreateFactoryzhuce.IFactory;
import AutomaticCreateFactoryzhuce.Operation;
import AutomaticCreateFactoryzhuce.OperationFactory.OperFactory;public class Client {public void createMethod() throws Exception {IFactory operFactory=new OperFactory();Operation operation = operFactory.createOperation();operation.setNumberA(3);operation.setNumberB(2);double result=operation.getResult();System.out.println("自动生成工厂方法的运行结果:"+result);}
}
监听类
package AutomaticCreateFactoryzhuce;import java.nio.file.*;
import java.util.EventListener;
import java.util.EventObject;/*** @BelongsProject: DesignPattern* @BelongsPackage: AutomaticCreateFactoryzhuce* @Author: Wuzilong* @Description: 监听是否有新的类* @CreateTime: 2023-03-27 09:29* @Version: 1.0*/public class Listener {public void run() {WatchKey key;try {String path = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//OperationSubclass//";//创建一个watchservice对象,用于监听目录事件WatchService watchservice = FileSystems.getDefault().newWatchService();//监控目录下是否有创建的文件Paths.get(path).register(watchservice, StandardWatchEventKinds.ENTRY_CREATE);while (true) {key = watchservice.take();//没有文件增加时,阻塞在这里//key.pollEvents()用于获取文件变化事件for (WatchEvent<?> event : key.pollEvents()) {//返回触发事件的文件或目录的路径(相对路径)String filename = path + event.context();System.out.println("增加文件的文件夹路径" + filename);String newClassName = filename.substring(filename.indexOf("AutomaticCreateFactoryzhuce"), filename.indexOf(".java"));Event eventObject = new Event();eventObject.addDelegate(new Delegate(new CreateClass(),"createClass",newClassName));eventObject.addClass();}if (!key.reset()) {break; //中断循环}}} catch (Exception e) {e.printStackTrace();}}
}
委托类
package AutomaticCreateFactoryzhuce;import java.lang.reflect.Method;/*** @BelongsProject: DesignPattern* @BelongsPackage: AutomaticCreateFactoryzhuce* @Author: Wuzilong* @Description: 委托类* @CreateTime: 2023-03-29 08:48* @Version: 1.0*/public class Delegate {private Object obj;private String methodName;private Object[] methodParameter;private Class<?>[] methodType;public Delegate(Object obj, String methodName, Object... methodParameter) {this.obj = obj;this.methodName = methodName;this.methodParameter = methodParameter;int len = methodParameter.length;this.methodType = new Class[len];for (int i = 0; i < len; i++) {methodType[i] = methodParameter[i].getClass();}}public void eventHandler() throws Exception {Method method = obj.getClass().getDeclaredMethod(methodName, methodType);method.invoke(obj, methodParameter);}
}
事件类
package AutomaticCreateFactoryzhuce;import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;/*** @BelongsProject: DesignPattern* @BelongsPackage: AutomaticCreateFactoryzhuce* @Author: Wuzilong* @Description: 事件类* @CreateTime: 2023-03-27 09:40* @Version: 1.0*/public class Event {private List<Delegate> objects=new ArrayList<>();public void addDelegate(Delegate source) {objects.add(source);}public void addClass() throws Exception {if (objects.size()!=0){for (Delegate object:objects){object.eventHandler();}}}
}
两个线程类,一个只负责监听有没有新类的加入,一个只负责让用户输入运算
监听线程
package AutomaticCreateFactoryzhuce;import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;/*** @BelongsProject: DesignPattern* @BelongsPackage: AutomaticCreateFactory* @Author: Wuzilong* @Description: 触发监听的线程* @CreateTime: 2023-03-21 08:31* @Version: 1.0*/public class RegularService implements Runnable{public void run() {CreateClass createClass=new CreateClass();Listener listener = new Listener();// 需要定时执行的任务Runnable runnable = () -> {try {createClass.createClass();listener.run();} catch (Exception e) {throw new RuntimeException(e);}};ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();//立即执行,并且每5秒执行一次ses.scheduleAtFixedRate(runnable, 0, 10000, TimeUnit.MILLISECONDS);}
}
用户输入运算线程
package AutomaticCreateFactoryzhuce;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;/*** @BelongsProject: DesignPattern* @BelongsPackage: AutomaticCreateFactoryzhuce* @Author: Wuzilong* @Description: 定时触发用户想要的运算* @CreateTime: 2023-03-27 21:14* @Version: 1.0*/public class RegularClient {public void run() {// 需要定时执行的任务Runnable runnable = () -> {try {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));System.out.println("请输入要执行的算法工厂");String operation = br.readLine();Class aClass = Class.forName("AutomaticCreateFactoryzhuce.OperationFactory." + operation + "Client");Object object = aClass.newInstance();Method mainMethod = aClass.getMethod("createMethod");mainMethod.invoke(object);} catch (Exception e) {System.out.println("暂不支持该运算");}};ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();//立即执行,并且每5秒执行一次ses.scheduleAtFixedRate(runnable, 0, 8000, TimeUnit.MILLISECONDS);}
}
客户端
package AutomaticCreateFactoryzhuce;/*** @BelongsProject: DesignPattern* @BelongsPackage: AutomaticCreateFactoryV2* @Author: Wuzilong* @Description: 客户端* @CreateTime: 2023-03-21 08:36* @Version: 1.0*/public class Client {public static void main(String[] args) {RegularService regularService=new RegularService();RegularClient regularClient = new RegularClient();regularService.run();regularClient.run();}
}
运行结果
三、总结提升
只要我们把最基础的内容学会了其他的内容就是我们通过基础的内容组合而成的。实现这个例子的时候一开始觉得实现起来比较困难。但是把整个过程拆分一下,都是之前学习过的内容:反射、事件与委托、工厂方法等。对于一个比较大的任务颗粒化就十分的重要。把每个小的颗粒逐个击破大问题也就没有了。