设计模式-工厂方法模式

简介: 设计模式-工厂方法模式

文章目录

发展:

简单实现:

命名不规范:

可读性差

可维护性差

可扩展性差

团队合作问题

除数不能为0问题:

开闭原则问题:

想象力创造力:

首先是发现力:

接下来是想象力:

总结


大话设计模式这本书反反复复学过好多遍了,每一次学都会有不同的认识,接下来谈谈我最近学习工厂的一次感受;

发展:

一个计算器的例子从不使用工厂到分离出前端、后端,到使用简单工厂再到使用工厂方法,每一步的变化都是巨大的;


简单实现:

简单实现的版本中存在着大量的问题,命名不规范啊,除数不能为0,前后端没有进行分离导致无法复用后端;违反开闭原则,新增运算的业务需要修改代码才可以;


命名不规范:

我们写代码是为了给别人看的,不是能运行就可以,一个好的程序员写出来的代码要能让被人看一眼就能知道你这里写的是什么,如果我们随便对变量进行命名,任谁来也不能马上知道你写的是什么意思,所以命名不规范就导致了你写的这段程序一个人开发的,维护的时候,需要一百个人来维护,浪费人力、物力、财力,千万不要小看命名的问题;


可读性差

不规范的命名会使代码难以理解和阅读,增加了其他开发人员理解代码的难度。当代码命名不清晰时,读者需要花费更多的时间和精力来推断变量、函数或类的用途和含义。


可维护性差

命名不规范会给代码维护带来困难。当代码需要修改或调试时,不规范的命名可能会让开发人员困惑,导致错误的修改或调试行为。同时,不规范的命名还会影响代码的重构,增加了重构的难度和风险。


可扩展性差

命名不规范会限制代码的可扩展性。当新功能需要添加或现有功能需要扩展时,不规范的命名可能会导致冲突、歧义或混乱,使得代码的扩展变得困难。良好的命名规范可以提高代码的可扩展性,使得新功能的添加和现有功能的扩展更加容易和可靠。


团队合作问题

不规范的命名会给团队协作带来问题。在团队开发中,成员之间需要相互理解和协作。如果命名不规范,代码的含义和用途可能会被误解,导致沟通困难和合作效率降低。


除数不能为0问题:

这里问题就更严重了,只有没有把用户当猪的开发者才能写出这种代码,没有把用户当猪,总想着用户能知道除法运算中除数不能为0,把这种生死权交在了用户的手中,只有用户在使用软件的过程中按照正确的方式输入才可以使用,但是如果用户没有按照正确的方式输入的,那你的系统岂不是直接挂了,在用户看来就是这什么软件啊,我输入个0都不行,导致用户骂你,骂你的软件,用户是你最大的收益,用户不用了,你也就失业了。


开闭原则问题:

我们说写代码不按照6大设计原则写的写出来的代码都是垃圾,我们写代码是为了让别人复用的;写了一段程序,别人想用的话你这还得改来改去,想想,这样别人会用吗?


想象力创造力:

创造力是基于想象力的,没有想象力,创造力根本无法实施,航天工程固然伟大,相比来说嫦娥奔月这个想法更加伟大,没有嫦娥奔月的想象力是不可能造出航天飞行器的;


cdeee3c6a63746bf9c1b686b479d5579.png


这是一个工厂方法模式的类图, 接下来代码实现:

public abstract class Operation {
    private double numberA = 0;
    private double numberB = 0;
    public abstract double GetResult() throws Exception;
    public double getNumberA() {
        return numberA;
    }
    public void setNumberA(double numberA) {
        this.numberA = numberA;
    }
    public double getNumberB() {
        return numberB;
    }
    public void setNumberB(double numberB) {
        this.numberB = numberB;
    }
}
public interface OperationFactory {
    Operation createOperate();
}
public class OperationAdd extends Operation {
    @Override
    public double GetResult() {
        return getNumberA()+getNumberB();
    }
}
public class OperationFactoryAdd implements OperationFactory {
    @Override
    public Operation createOperate() {
        return new OperationAdd();
    }
}
public static void main(String[] args) throws Exception {
        OperationFactory operationFactory = new OperationFactoryAdd();
        Operation operate = operationFactory.createOperate();
        operate.setNumberA(11);
        operate.setNumberB(22);
        double result = operate.GetResult();
        System.out.println(result);
    }


首先是发现力:

以此我们发现运算类工厂中的代码基本都是一致的,只有涉及到创建出不用运算类对象的名字部分是不一样的;


接下来是想象力:

我们就想,既然代码基本都是一致的,我可不可以写一个模板,让程序来帮我写工厂的这段代码,这样每当我有一个写的运算类添加的时候,这样重复性的东西就不用手写了呀;


有了这样的想象力之后是创造力:

工厂模板,用于让程序帮我们实现自动写代码

public class FactoryTemplate {
    public String createFactory(String operationName) throws Exception{
        String srcFactoryCode = "package com.mengjie.saomiao.operationFactory;\n" +
                "import com.mengjie.saomiao.Operation;\n" +
                "import com.mengjie.saomiao.OperationFactory;\n" +
                "import com.mengjie.saomiao.operation."+operationName+";\n" +
                "public class" + " " + operationName+"Factory" + " " + "implements OperationFactory {\n" +
                "    @Override\n" +
                "    public Operation createOperate() {\n" +
                "        return new" + " " + operationName + "();\n" +
                "    }\n" +
                "}";
        String srcFilePath = "E:\\study\\Practice\\auto\\src\\main\\java\\com\\mengjie\\saomiao\\operationFactory\\" + operationName+"Factory" + ".java";
        FileWriter fileWriter = null;
        File file = new File(srcFilePath);
        if (!file.exists()) {
            file.createNewFile();
        }
        fileWriter = new FileWriter(srcFilePath);
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        bufferedWriter.write(srcFactoryCode);
        bufferedWriter.close();
        return srcFilePath;
    }
}

编译工具类,用于我们让程序帮我们写出来代码时候,新增的工厂类没有编译成字节码文件的话我们的程序是没有办法帮我们执行的;

public class Compiler {
    private String classPath;
    private String filePath;
    public Compiler(String classPath, String filePath) {
        this.classPath = classPath;
        this.filePath = filePath;
    }
    public void compiler() {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        int status = compiler.run(null, null, null, "-d",classPath,filePath);
        if(status!=0){
            System.out.println("没有编译成功!");
        }
    }
}

自动扫描,每次都获取一个文件夹中的所有的运算类,将类名最终截取出来,传入创建工程类的模板中让程序来帮我们写代码;

public class Scan {
    public void scan() throws Exception {
        String packagePath = "E:\\study\\Practice\\auto\\src\\main\\java\\com\\mengjie\\saomiao\\operation";
        File file = new File(packagePath);
        if (file.isDirectory()){
            File[] files = file.listFiles();
            Map<Object, Method> map = new HashMap<>();
            for (File f : files){
                String fileName = f.getAbsolutePath();
                if (fileName.endsWith(".java")){
                    String className = fileName.substring(fileName.indexOf("com"), fileName.indexOf(".java"));
                    String replacedName = className.replace("com\\mengjie\\saomiao\\operation\\", "");
                    FactoryTemplate factoryTemplate = new FactoryTemplate();
                    String factoryClassPath = factoryTemplate.createFactory(replacedName);
                    //调用一个编译源码的方法,将创建出的.java文件编译成.class文件
                    Compiler compilerOperation = new Compiler(System.getProperty("user.dir")+"\\auto\\target\\classes",fileName);
                    compilerOperation.compiler();
                    //调用一个编译源码的方法,将创建出的.java文件编译成.class文件
                    Compiler compilerFactory = new Compiler(System.getProperty("user.dir")+"\\auto\\target\\classes",factoryClassPath);
                    compilerFactory.compiler();
                    ClientTemplate clientTemplate = new ClientTemplate();
                    String clientClassPath = clientTemplate.createClient(replacedName);
                    //调用一个编译源码的方法,将创建出的.java文件编译成.class文件
                    Compiler compilerClient = new Compiler(System.getProperty("user.dir")+"\\auto\\target\\classes",clientClassPath);
                    compilerClient.compiler();
                    String compileClassName = "com.mengjie.saomiao.client."+replacedName+"Client";
                    Class<?> classLoaderClass = Class.forName(compileClassName);
                    Object instance = classLoaderClass.getConstructor().newInstance();
                    Method method = classLoaderClass.getMethod("main",String[].class);
                    map.put(instance,method);
                    method.invoke(null,  new String[]{""});
                }
            }
        }
    }
}


总结

工厂方法模式提供了一种将对象的创建与使用分离的方式,通过定义一个创建对象的工厂接口,让子类决定实例化哪个具体类。工厂方法模式可以在不知道具体对象类型的情况下创建对象,使代码更加灵活和可扩展。

目录
相关文章
|
19天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
22天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
15天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
36 1
|
1月前
|
设计模式 Java Kotlin
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin语法,推荐查看“简洁”系列教程。本文重点介绍了构建者模式在Kotlin中的应用与改良,包括如何使用具名可选参数简化复杂对象的创建过程,以及如何在初始化代码块中对参数进行约束和校验。
22 3
|
2月前
|
设计模式 算法 安全
设计模式——模板模式
模板方法模式、钩子方法、Spring源码AbstractApplicationContext类用到的模板方法
设计模式——模板模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。
|
2月前
|
设计模式 Java Spring
spring源码设计模式分析-代理设计模式(二)
spring源码设计模式分析-代理设计模式(二)
|
2月前
|
设计模式
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
这篇文章详细解释了工厂模式,包括简单工厂、工厂方法和抽象工厂三种类型。每种模式都通过代码示例展示了其应用场景和实现方法,并比较了它们之间的差异。简单工厂模式通过一个工厂类来创建各种产品;工厂方法模式通过定义一个创建对象的接口,由子类决定实例化哪个类;抽象工厂模式提供一个创建相关或依赖对象家族的接口,而不需要明确指定具体类。
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
36 0

热门文章

最新文章

  • 1
    C++一分钟之-设计模式:工厂模式与抽象工厂
    43
  • 2
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    50
  • 3
    C++一分钟之-C++中的设计模式:单例模式
    58
  • 4
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    38
  • 5
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    63
  • 6
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    58
  • 7
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    42
  • 8
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    50
  • 9
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    110
  • 10
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    78
  • 下一篇
    无影云桌面