设计模式-对于工厂方法的想象力和创造力

简介: 对于工厂方法的想象力和创造力

一、背景介绍

       对于简单工厂、工厂方法和抽象工厂都听说过,也知道怎么用。但是从没有工厂到添加了工厂到工厂方法再到抽象工厂每一次的巨大的变化和给我们以及用户带来了哪些好处是我们不清楚的,下面我们来一起分析每一次变换的重大意义以及到工厂方法之后如何体现我们的想象力和创造力。

二、阶段分析

注:Px 代表设计模式书上的页码

没有使用工厂:P1、P2

需求

       实现一个简单的计算器例子

实现

客户端

public class Client {
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        System.out.println("请输入要计算的第一个数字");
        String A = br.readLine();
        System.out.println("请选择运算符号(+、-、*、/)");
        String strOperate = br.readLine();
        System.out.println("请输入要计算的第二个数字");
        String B = br.readLine();
        String NumberSum="";
        if (strOperate.equals("+")){
            NumberSum=String.valueOf(Double.valueOf(A) +Double.valueOf(B));
        }
        if (strOperate.equals("-")){
            NumberSum=String.valueOf(Double.valueOf(A) -Double.valueOf(B));
        }
        if (strOperate.equals("*")){
            NumberSum=String.valueOf(Double.valueOf(A) *Double.valueOf(B));
        }
        if (strOperate.equals("/")){
            NumberSum=String.valueOf(Double.valueOf(A) /Double.valueOf(B));
        }
        System.out.println("没使用工厂第一版的结果:"+NumberSum);
    }
}

运行结果

cca6a1a5017748fbbec343f73ca25dfe.png

总结

       单纯的实现了一个加减乘除的计算机小例子,通过控制台输入数据和运算符的方式进行运算。没有应用开发规范和一些设计的思想。把功能的样式(控制台的提示和输入的内容)和功能的业务逻辑写在了一起。

从没有使用工厂到进行了前后端分离P1、2-P3

需求

       编写一个不同端的系统,代码如何复用。比如已经在pc端写好了一个计算器例子,再写一个手机端的是不是可以复用代码。

实现

客户端

public class Client {
    public static void main(String[] args) {
        try{
            BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
            System.out.println("请输入要计算的第一个数字");
            String strNumberA = br.readLine();
            System.out.println("请选择运算符号(+、-、*、/)");
            String strOperate = br.readLine();
            System.out.println("请输入要计算的第二个数字");
            String strNumberB = br.readLine();
            Double strResult= Operation.getResult(Double.valueOf(strNumberA), Double.valueOf(strNumberB),strOperate);
            System.out.println("结果是:"+strResult);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运算类

public class Operation {
    public static double getResult(double numberA,double numberB,String operate){
        double result=0d;
        switch (operate){
            case "+":
                result=numberA+numberB;
                break;
            case "-":
                result=numberA-numberB;
                break;
            case "*":
                result=numberA*numberB;
                break;
            case "/":
                if (numberB==0){
                    System.out.println("除数不能为0");
                }else{
                    result=numberA/numberB;
                }
                break;
        }
        return  result;
    }
}

运行结果

afaf5ca535334fd0bf0d4bb212634032.png

总结      0738909ad6474fbab03128a2252040e5.png

85613c378fbc4a9b935b3d2412e0b937.png

       1、调整了命名规范:没有命名格式到驼峰命名格式。

       2、进行了前后端分离:把功能样式和功能具体逻辑写到一起到把功能具体逻辑封装到一个类中(Operation)。达到了前后端分离,后端的业务逻辑可以进行复用。多个前端都可以调用同一个后端。降低了功能样式和功能业务逻辑的耦合。

       3、考虑了报错的情况:在除法中没有对除数进行判断到判断是否0,增加了程序的健壮性。  

       4、把四个并列的if换成了switch case:减少了资源的浪费,从四个运算中选择一个运算只需要判断一次就可以不需要每种情况进行判断,如果判断的类型非常多的话会造成cpu飙升的问题。

       5、减少了报错的情况增强了用户的体验感。 前后端分离减少了开发成本代码直接复用即可。  命名规范提高了开发的效率不用去猜这个变量是干什么的

从前后端分离到简单工厂P3-P9、P10

需求

       添加一个新的运算类不会影响其他的运算类

实现

结构

304dcc99464842dfbb69ef8a6028b9ad.png

客户端

public class Client {
    public static void main(String[] args) throws Exception {
        Operation operation;
        operation=OperationFactory.createOperate("+");
        operation.setNumberA(1);
        operation.setNumberB(2);
        double result=operation.getResult();
        System.out.println("简单工厂的运行结果:"+result);
    }
}

运算工厂

public class OperationFactory {
    public static Operation createOperate(String operate) {
        Operation operation=null;
        switch (operate){
            case"+":
                operation=new OperationAdd();
                break;
            case"-":
                operation=new OperationSub();
                break;
            case"*":
                operation=new OperationMul();
                break;
            case"/":
                operation=new OperationDiv();
                break;
        }
        return operation;
    }
}

运算父类

@Data
public class Operation {
    private double numberA=0;
    private  double numberB=0;
    public  double getResult() throws Exception {
        double result=0;
        return result;
    }
}

运算加法

public class OperationAdd extends Operation{
    @Override
    public  double getResult() {
        double result=0;
        result=getNumberA()+getNumberB();
        return result;
    }
}

运算减法、乘法都是一样的

运算除法

public class OperationDiv extends Operation{
    @Override
    public  double getResult() throws Exception {
        double result=0;
        if(getNumberB()==0){
            throw new Exception("除数不能为0");
        }
        result=getNumberA()/getNumberB();
        return result;
    }
}

运行结果

09ca9d7d275c4f58a3f75cf07a305a39.png

总结

       1、将四种运算方式进行了封装:把直接在Operation进行计算到四种运算都写成了类,抽象了运算父类,以后添加其他业务直接继承运算父类即可达到扩充的效果。

       2、把要调用的运算类写死在了客户端中,缺少了和用户之间的交互。可以通过让用户输入的方式去实例化对应的运算类。完成对应的运算结果。

       3、把四种运算进行封装,避免了开发人员因添加一个运算修改了其他运算的情况,增加了代码的安全性。对于运算类的扩充直接继承父类

从简单工厂到工厂方法P10、11-P69、70

需求

       在添加新的运算类的时候符合开闭原则,不需要在OperationFactory中修改代码。

实现

结构

42df64ac6ee14ab2b7b458224ae830a5.png

客户端

public class Client {
    public static void main(String[] args) throws Exception {
        IFactory operFactory=new AddFactory();
        Operation operation = operFactory.createOperation();
        operation.setNumberA(1);
        operation.setNumberB(2);
        double result=operation.getResult();
        System.out.println("工厂方法的运行结果:"+result);
    }
}

运算父类

@Data
public class Operation {
    private double numberA=0;
    private  double numberB=0;
    public  double getResult() throws Exception {
        double result=0;
        return result;
    }
}

运算子类

public class OperationAdd extends Operation {
    @Override
    public  double getResult() {
        double result=0;
        result=getNumberA()+getNumberB();
        return result;
    }
}

工厂接口

public interface IFactory {
    Operation createOperation();
}

工厂实现类

public class AddFactory implements IFactory {
    @Override
    public Operation createOperation(){
        return  new OperationAdd();
    }
}

运行结果

f877660c399540bcb627aeb291397fc4.png

总结

        1、将工厂进行了拆分:从一个工厂管理四个运算子类到每个运算子类都有一个工厂进行管理。添加一个运算类在添加一个相对应的工厂达到扩充的效果,不需要修改工厂中的代码相较于简单工厂更符合开闭原则。一个工厂只负责一件事情。

       2、把实例化对象的过程交给了工厂去完成。      

从工厂方法到工厂类由程序来创建

需求

       把重复性有规律性的内容交给程序去完成,提高了开发人员的工作效率。 减少了人为操作出错的情况。

实现

扫描版本

结构

23536c54d63c4401879595672bf22dad.png

客户端

package AutomaticCreateFactory;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: AutomaticCreateFactory
 * @Author: Wuzilong
 * @Description: 生成工厂类
 * @CreateTime: 2023-03-15 16:57
 * @Version: 1.0
 */
public class CreateClass {
        public static void main(String[] args) throws IOException, ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {
            // 工厂文件模板
            String factoryTemplate = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactory//FactoryTemplate";
            //客户端文件模板
            String clientTemplate ="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactory//ClientTemplate";
            //运算子类的抽象类名
            String className = "FactoryTemplate";
            //运算子类中要实例化的类的抽象类名
            String reClass="OperationClass";
            //客户端的抽象类名
            String clientName="Client";
            //客户端中要实例化的类的抽象类名
            String newName="OperationFactory";
            //创建工厂的方法
            createClass(factoryTemplate,className,reClass);
            //创建客户端的方法
            createClass(clientTemplate,clientName,newName);
        }
        private static void createClass(String filePath,String className,String reClass) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException, IOException {
            String packagePath="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactory//OperClass//";
            //反射的类路径
            String[] classPath=new String[4];
            //要创建的java类的名字
            String[] target =new String[4];
            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("OperClass"), fileNamePath.indexOf(".java"));
                        String createClassName = operClassPath.replace("OperClass\\", "");
                        target[i]=createClassName;
                        classPath[i]="AutomaticCreateFactory.OperClass."+createClassName;
                    }
                }
            }
            // 创建java类的存放路径
            String targetURL = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactory//OperFactory//";
            //存放class文件的路径
            String classURL="D://项目//设计模式//Java//DesignPattern//target//classes//";
            int isClient=0;
            for (int i = 0; i < target.length; i++) {
                try {
                    BufferedReader bufReader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));//数据流读取文件
                    //StringBuffer动态的字符串数组
                    StringBuffer strBuffer = new StringBuffer();
                    //截取计算类的后三位
                    String substring = target[i].substring(target[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 = Class.forName(classPath[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 = new Compiler();
                    compiler.compiler(classURL,createClassName);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (isClient==4){
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("请输入要执行的算法类");
                String operation = br.readLine();
                Class aClass = Class.forName("AutomaticCreateFactory.OperFactory." + operation + "Client");
                Object object = aClass.newInstance();
                Method mainMethod = aClass.getMethod("main");
                mainMethod.invoke(object);
            }
        }
}

编译文件类:将java文件编译成class文件

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("没有编译成功!");
        }
    }
}

 生成工厂类的模板

68b76fc569bc4cb687f6de66aa657417.png

其他的类和工厂方法中的内容是一致的。

运行结果

386f9a4dc7ff48928f74621ac7ec5eb4.png

注册版本

结构

15053ae17e504ee4a1e6b65cc9738e5d.png

客户端

package AutomaticCreateFactoryV3;
import java.io.*;
import java.lang.reflect.Method;
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: AutomaticCreateFactory
 * @Author: Wuzilong
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-03-15 16:57
 * @Version: 1.0
 */
public class CreateClass {
    public static void main(String[] args) throws IOException {
        //公共路径
        String commonPath="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryV3//Template//";
        // 工厂文件模板
        String factoryTemplate = commonPath+"FactoryTemplate";
        //客户端文件模板
        String clientTemplate = commonPath+"ClientTemplate";
        //运算子类的模板
        String operationTemplate = commonPath+"OperationTemplate";
        //运算类的名称
        String operClassName="OperationName";
        //运算类的符号
        String operClassSign="?";
        //工厂中运算子类的抽象类名
        String className = "FactoryTemplate";
        //工厂中运算子类中要实例化的类的抽象类名
        String reClass = "OperationClass";
        //客户端的抽象类名
        String clientName = "Client";
        //客户端中要实例化的类的抽象类名
        String newName = "OperFactory";
        //创建运算子类的方法
        createFile(operationTemplate,operClassName,operClassSign);
        //创建工厂的方法
        createFile(factoryTemplate, className, reClass);
        //创建客户端的方法
        createFile(clientTemplate, clientName, newName);
    }
    private static void createFile(String filePath, String className, String reClass) throws IOException {
        // 创建java类的存放路径
        String javaURL = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryV3//OperationFactory//";
        String operationClassURL = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryV3//OperationSubclass//";
        String classURL="D://项目//设计模式//Java//DesignPattern//target//classes//";
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        Boolean isShow=false;
        System.out.println("请输入要创建的类名");
        String createClassName = br.readLine();
        try {
            BufferedReader bufReader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));//数据流读取文件
            //StringBuffer动态的字符串数组
            StringBuffer strBuffer = new StringBuffer();
            for (String temp = null; (temp = bufReader.readLine()) != null; temp = null) {
                //判断当前行是否存在想要替换掉的字符
                if (temp.contains(className)) {
                    //替换类名
                    temp = temp.replace(className, createClassName);
                } else if (temp.contains(reClass)) {
                    if (reClass.contains("Factory")) {
                        String classNameStr  = createClassName.substring(0, 10);
                        //替换返回需要实例化的类名
                        temp = temp.replace(reClass, classNameStr);
                    }else if(createClassName.contains("Operation")){
                        isShow=true;
                        if (createClassName.contains("OperationAdd")){
                            temp=temp.replace(reClass, "+");
                        }else if(createClassName.contains("OperationSub")){
                            temp=temp.replace(reClass, "-");
                        }else if(createClassName.contains("OperationMul")){
                            temp=temp.replace(reClass, "*");
                        }else{
                            temp=temp.replace(reClass, "/");
                        }
                    }else {
                        //反射获取计算类的名称
                        String classStr  = createClassName.substring(0, 3);
                        Class classObject = Class.forName("AutomaticCreateFactoryV3.OperationSubclass.Operation"+classStr);
                        //替换返回需要实例化的类名
                        temp = temp.replace(reClass, classObject.getSimpleName());
                    }
                }
                //把读取的每一行添加到数组中
                strBuffer.append(temp);
                //换行符
                strBuffer.append(System.getProperty("line.separator"));
            }
            bufReader.close();
            //创建java对象并存放在对应的路径当中
            PrintWriter printWriter = null;
            String classFilePath="";
            String compileClassName="";
            if (isShow){
                printWriter=new PrintWriter(operationClassURL+createClassName+".java");
                classFilePath=classURL+"AutomaticCreateFactoryV3//OperationSubclass//"+createClassName+".class";
                compileClassName="AutomaticCreateFactoryV3.OperationSubclass."+createClassName;
            }else{
                printWriter=new PrintWriter(javaURL + createClassName + ".java");
                classFilePath=classURL+"AutomaticCreateFactoryV3//OperationFactory//"+createClassName+".class";
                compileClassName="AutomaticCreateFactoryV3.OperationFactory."+createClassName;
            }
            //将获取数据的数组写入到创建的java对象中
            printWriter.write(strBuffer.toString().toCharArray());
            printWriter.flush();
            printWriter.close();
            //调用一个编译源码的方法,将创建出的.java文件编译成.class文件
            Compiler compiler = new Compiler();
            String srcFilePath =javaURL+createClassName+".java";
            if (isShow){
                compiler.compiler(classURL,operationClassURL+createClassName+".java");
            }else{
                compiler.compiler(classURL,srcFilePath);
            }
            Class<?> aClass = compiler.findClass(compileClassName, classFilePath);
            Object instance = aClass.getConstructor().newInstance();
            if (createClassName.contains("Client")){
                Method createMethod = aClass.getMethod("createMethod");
                createMethod.invoke(instance);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运算类模板

5a7f4a17a31a48bf8897ef15533fe299.png

工厂类模板

cca784ad04934751b2fe678f8b35ddd5.png

运行结果

ed05bb9e17e444548075b04ce1e01e49.png

总结

       完成的事情系统也能完成。将重复性的代码让系统替我们来完成,我们来完成具有想象力和创造力的事情。这样提高了我们的开发效率,也减少了出错的情况。随着业务越来越多我们自动生成的也就越来越多。从一开的只写一个变成了后来的无数多个。

从自动创建类到热加载创建的类

需求

       程序运行的过程中添加一个类也同样可以执行运算结果,不需要把程序重启

实现

结构

9f2034c93e8f4fe59d1823b177a969cc.png

客户端

public class Logon {
    public static void main(String[] args) {
        Regular regular=new Regular();
        regular.run();
    }
}

定时扫描器

public class Regular implements Runnable{
    public void run() {
        CreateClass createClass=new CreateClass();
        // 需要定时执行的任务
        Runnable runnable = () -> {
            try {
                createClass.createClass();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        };
        ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
        //立即执行,并且每5秒执行一次
        ses.scheduleAtFixedRate(runnable, 0, 15000, TimeUnit.MILLISECONDS);
    }
}
package AutomaticCreateFactoryV4;
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 IOException, ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {
            // 工厂文件模板
            String factoryTemplate = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryV4//FactoryTemplate";
            //客户端文件模板
            String clientTemplate ="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryV4//ClientTemplate";
            //运算子类的抽象类名
            String className = "FactoryTemplate";
            //运算子类中要实例化的类的抽象类名
            String reClass="OperationClass";
            //客户端的抽象类名
            String clientName="Client";
            //客户端中要实例化的类的抽象类名
            String newName="OperationFactory";
            //创建工厂的方法
            createFlie(factoryTemplate,className,reClass);
            //创建客户端的方法
            createFlie(clientTemplate,clientName,newName);
        }
        private static void createFlie(String filePath,String className,String reClass) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException, IOException {
            String packagePath="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryV4//OperClass//";
            //反射的类路径
            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("OperClass"), fileNamePath.indexOf(".java"));
                        String createClassName = operClassPath.replace("OperClass\\", "");
                        target.add(createClassName);
                        classPath.add("AutomaticCreateFactoryV4.OperClass."+createClassName);
                    }
                }
            }
            // 创建java类的存放路径
            String targetURL = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryV4//OperFactory//";
            //存放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();
                }
            }
            if (isClient==target.size()){
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("请输入要执行的算法类");
                String operation = br.readLine();
                Class aClass = Class.forName("AutomaticCreateFactoryV4.OperFactory." + operation + "Client");
                Object object = aClass.newInstance();
                Method mainMethod = aClass.getMethod("main");
                mainMethod.invoke(object);
            }
        }
}

其他类和没有使用热加载的一致

执行结果

3a4263cb7fd8481ea44c3e7cba9112a3.png

总结

       在程序运行的过程中把用户的需求添加到项目中,不会影响用户的时候。用户想要使用什么功能直接使用就可以了。


相关文章
|
7月前
|
设计模式 开发者
探讨常见设计模式 - 工厂方法模式的最佳实践和潜在的实施问题
【4月更文挑战第7天】工厂方法模式是创建型设计模式,提供了一种在不指定具体类情况下创建对象的方式。它定义创建对象的接口,允许子类决定实例化哪个类,从而解耦对象的创建和使用。最佳实践包括明确接口、封装创建逻辑、提供扩展点和避免过度使用。然而,过度工程、违反开闭原则、性能影响和依赖管理是可能的问题。通过权衡利弊并遵循最佳实践,工厂方法模式能在适当场景下提升代码灵活性和可扩展性。
65 1
|
1月前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
3月前
|
设计模式
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
这篇文章详细解释了工厂模式,包括简单工厂、工厂方法和抽象工厂三种类型。每种模式都通过代码示例展示了其应用场景和实现方法,并比较了它们之间的差异。简单工厂模式通过一个工厂类来创建各种产品;工厂方法模式通过定义一个创建对象的接口,由子类决定实例化哪个类;抽象工厂模式提供一个创建相关或依赖对象家族的接口,而不需要明确指定具体类。
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
|
3月前
|
设计模式 Java
Java设计模式-工厂方法模式(4)
Java设计模式-工厂方法模式(4)
|
4月前
|
设计模式 XML 存储
【二】设计模式~~~创建型模式~~~工厂方法模式(Java)
文章详细介绍了工厂方法模式(Factory Method Pattern),这是一种创建型设计模式,用于将对象的创建过程委托给多个工厂子类中的某一个,以实现对象创建的封装和扩展性。文章通过日志记录器的实例,展示了工厂方法模式的结构、角色、时序图、代码实现、优点、缺点以及适用环境,并探讨了如何通过配置文件和Java反射机制实现工厂的动态创建。
【二】设计模式~~~创建型模式~~~工厂方法模式(Java)
|
4月前
|
设计模式 uml
设计模式-------------工厂模式之工厂方法模式(创建型)
工厂方法模式是一种创建型设计模式,它通过定义一个用于创建对象的接口,让子类决定实例化哪一个类,从而实现类的实例化推迟到子类中进行,提高了系统的灵活性和可扩展性。
|
6月前
|
设计模式 Java
Java设计模式:工厂模式之简单工厂、工厂方法、抽象工厂(三)
Java设计模式:工厂模式之简单工厂、工厂方法、抽象工厂(三)
|
6月前
|
设计模式 搜索推荐
工厂方法模式-大话设计模式
工厂方法模式-大话设计模式
|
6月前
|
设计模式 新零售 Java
设计模式最佳套路5 —— 愉快地使用工厂方法模式
工厂模式一般配合策略模式一起使用,当系统中有多种产品(策略),且每种产品有多个实例时,此时适合使用工厂模式:每种产品对应的工厂提供该产品不同实例的创建功能,从而避免调用方和产品创建逻辑的耦合,完美符合迪米特法则(最少知道原则)。
90 6
|
6月前
|
设计模式 XML Java
【设计模式】第三篇:一篇搞定工厂模式【简单工厂、工厂方法模式、抽象工厂模式】
三 结尾 如果文章中有什么不足,欢迎大家留言交流,感谢朋友们的支持! 如果能帮到你的话,那就来关注我吧!如果您更喜欢微信文章的阅读方式,可以关注我的公众号
63 5