简单工厂VS工厂方法&手写自动化工厂——系统学习六

简介: 然而我的观点是工厂方法是为了解决自动化创建对象的问题;如何理解这句话?请读者朋友继续往下看。

一、背景介绍


工厂方法仅仅为了解决简单工厂判断不符合开闭原则的问题?

工厂方法仅仅为了解决业务子类实例化的问题?

然而我的观点是工厂方法是为了解决自动化创建对象的问题;如何理解这句话?请读者朋友继续往下看。


阅读这篇文章您会了解到小编在进行设计模式学习过程中的思路、总结以及产生的问题,希望能够和读者碰撞出更多的"车祸"。


二、学习思路


1.绘制模式的UML图

2.根据UML图编写代码

3.寻找模式的例子进行UML图的绘制

4.根据例子的UML图编写代码

5.对比两个模式的区别,以及分别的作用与意义

6.请教高人


三、学习过程


1.实现绘制UML以及实现代码下面是对于工厂方法的UML图


20210611230941775.png

20210611231000504.png


2.开始解答以上的问题

2.1.工厂方法仅仅为了解决简单工厂判断不符合开闭原则的问题?

答:如果不用工厂方法,简单工厂对应的实现在客户端直接实例化不同的子类即可;依然能解决开闭原则的问题


2.2.工厂方法仅仅为了解决业务子类实例化的问题?

答:业务子类实例化,交由客户端通过反射直接获取子类即可


2.3.然而我的观点是工厂方法是为了解决自动化的问题

答:有了工厂方法这个理念我就可以自动将业务子类一一对应进行实例化,如果我的子类成千上万的话;并且我的子类需要动态的扩充的话如何通过自动化来实现?

下面我会介绍如何自动实现业务子类的实例化


3.自动实现业务子类的实例化内容


package com.mark.b01Operation.service.impl;
import com.mark.b01Operation.service.CreateClassService;
import com.mark.b01Operation.service.operation.AbstractOperation;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.*;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.tools.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.Arrays;
@Service
public class CreateClassServiceImpl implements CreateClassService {
    @Resource
    private ConfigurableListableBeanFactory configurableListableBeanFactory;
    @Resource
    private AbstractBeanFactory abstractBeanFactory;
    @Override
    public void CreateClass(String str,String name) throws Exception {
        //1.获取java编程语言编译器
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        //2.获取文件管理器
        StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null);
        //3.获取class文件管理器
        ClassJavaFileManager classJavaFileManager = new ClassJavaFileManager(standardFileManager);
        //4.获取要加载的.java文件内容
        StringObject stringObject = new StringObject(new URI(name+".java"), JavaFileObject.Kind.SOURCE, str);
        //5.调用编译器,传入参数获取要执行的编译任务
        JavaCompiler.CompilationTask task = compiler.getTask(null, classJavaFileManager,
                null, null, null, Arrays.asList(stringObject));
        //6.执行编译任务
        if (task.call()) {
            //7.获取类文件获取.class文件
            ClassJavaFileObject javaFileObject = classJavaFileManager.getClassJavaFileObject();
            //8.创建类加载器,并将.class文件传入
            ClassLoader classLoader = new MyClassLoader(javaFileObject);
            //9.获得该类的实例
            Object AddFactory = classLoader.loadClass(name).newInstance();
            //10.调用spring管理bean的集合,将实例化的类交给spring管理
            configurableListableBeanFactory.registerSingleton(name,AddFactory);
            //11.通过spring的BeanFactory获取bean验证是否可以获取到
            AbstractOperation abstractOperation =  (AbstractOperation) abstractBeanFactory.getBean(name);
            System.out.println(AddFactory);
        }
    }
    /**
     *自定义fileManager 继承ForwardingJavaFileManager文件管理器
     */
    static class ClassJavaFileManager extends ForwardingJavaFileManager {
        private ClassJavaFileObject classJavaFileObject;
        public ClassJavaFileManager(JavaFileManager fileManager) {
            super(fileManager);
        }
        public ClassJavaFileObject getClassJavaFileObject() {
            return classJavaFileObject;
        }
        //这个方法一定要自定义
        //获取输出的文件对象,它表示给定位置处指定类型的制定类
        @Override
        public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
            return (classJavaFileObject = new ClassJavaFileObject(className,kind));
        }
    }
    /**
     * 存储源文件   SimpleJavaFileObject:简单的java文件对象
     */
    static class StringObject extends SimpleJavaFileObject {
        private String content;
        public StringObject(URI uri, Kind kind, String content) {
            super(uri, kind);
            this.content = content;
        }
        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
            return this.content;
        }
    }
    /**
     * class文件(不需要存到文件中)
     */
    static class ClassJavaFileObject extends SimpleJavaFileObject{
        ByteArrayOutputStream outputStream;
        public ClassJavaFileObject(String className, Kind kind) {
            super(URI.create(className + kind.extension), kind);
            this.outputStream = new ByteArrayOutputStream();
        }
        //这个也要实现
        @Override
        public OutputStream openOutputStream() throws IOException {
            return this.outputStream;
        }
        public byte[] getBytes(){
            return this.outputStream.toByteArray();
        }
    }
    //自定义classloader
    static class MyClassLoader extends ClassLoader{
        private ClassJavaFileObject classJavaFileObject;
        public MyClassLoader(ClassJavaFileObject classJavaFileObject){
            this.classJavaFileObject = classJavaFileObject;
        }
        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            byte[] bytes = this.classJavaFileObject.getBytes();
            return defineClass(name,bytes,0,bytes.length);
        }
    }
}


扩展:spring中最核心的BeanFactory就是通过工厂方法+注解来实现的对于业务类实例化操作


四、学习总结


收获:

对于工厂方法的认识有了质的变化,对于后续其它模式的学习指明了方向。

提出的问题:

在研究spring工厂的过程中了解到注解扫描类默认为单例,为什么?


五、升华


高人指路之后要多问一句,高人为什么能够想到这些?

相关文章
|
2月前
|
机器学习/深度学习 人工智能 测试技术
EdgeMark:嵌入式人工智能工具的自动化与基准测试系统——论文阅读
EdgeMark是一个面向嵌入式AI的自动化部署与基准测试系统,支持TensorFlow Lite Micro、Edge Impulse等主流工具,通过模块化架构实现模型生成、优化、转换与部署全流程自动化,并提供跨平台性能对比,助力开发者在资源受限设备上高效选择与部署AI模型。
350 9
EdgeMark:嵌入式人工智能工具的自动化与基准测试系统——论文阅读
|
1月前
|
存储 人工智能 自然语言处理
拔俗AI自动化评价分析系统:让数据说话,让决策更智能
在用户体验为核心的时代,传统评价分析面临效率低、洞察浅等痛点。本文基于阿里云AI与大数据技术,构建“数据-算法-应用”三层智能分析体系,实现多源数据实时接入、情感与主题精准识别、跨模态融合分析及实时预警,助力企业提升运营效率、加速产品迭代、优化服务质量,并已在头部电商平台成功落地,显著提升用户满意度与商业转化。
|
4月前
|
运维 Prometheus 监控
系统崩了怪运维?别闹了,你该问问有没有自动化!
系统崩了怪运维?别闹了,你该问问有没有自动化!
170 9
|
7月前
|
jenkins 测试技术 Shell
利用Apipost轻松实现用户充值系统的API自动化测试
API在现代软件开发中扮演着连接不同系统与模块的关键角色,其测试的重要性日益凸显。传统API测试面临效率低、覆盖率不足及难以融入自动化工作流等问题。Apipost提供了一站式API自动化测试解决方案,支持零代码拖拽编排、全场景覆盖,并可无缝集成CI/CD流程。通过可视化界面,研发与测试人员可基于同一数据源协作,大幅提升效率。同时,Apipost支持动态数据提取、性能压测等功能,满足复杂测试需求。文档还以用户充值系统为例,详细介绍了从创建测试用例到生成报告的全流程,帮助用户快速上手并提升测试质量。
|
7月前
|
人工智能 算法 物联网
5G赋能工业自动化:构建未来工厂的新引擎
5G赋能工业自动化:构建未来工厂的新引擎
285 10
|
8月前
|
存储 人工智能 API
OWL:告别繁琐任务!开源多智能体系统实现自动化协作,效率提升10倍
OWL 是基于 CAMEL-AI 框架开发的多智能体协作系统,通过智能体之间的动态交互实现高效的任务自动化,支持角色分配、任务分解和记忆功能,适用于代码生成、文档撰写、数据分析等多种场景。
1733 13
OWL:告别繁琐任务!开源多智能体系统实现自动化协作,效率提升10倍
|
10月前
|
监控 运维
HTTPS 证书自动化运维:https证书管理系统- 自动化监控
本文介绍如何设置和查看域名或证书监控。步骤1:根据证书状态选择新增域名或证书监控,线上部署推荐域名监控,未部署选择证书监控。步骤2:查询监控记录详情。步骤3:在详情页查看每日定时检测结果或手动测试。
HTTPS 证书自动化运维:https证书管理系统- 自动化监控
|
10月前
|
Linux 持续交付 调度
HTTPS 证书自动化运维:https证书管理系统-自动化部署
本指南介绍如何部署Linux服务器节点。首先复制生成的Linux脚本命令,然后将其粘贴到目标服务器上运行。接着刷新页面查看节点记录,并点击“配置证书”选择证书以自动部署。最后,节点部署完成,后续将自动调度,无需人工干预。
HTTPS 证书自动化运维:https证书管理系统-自动化部署
|
10月前
|
运维
HTTPS 证书自动化运维:https证书管理系统之自动化签发
通过访问【https://www.lingyanspace.com】注册账户,进入证书服务菜单并新增证书。填写域名(单域名、多域名或泛域名),创建订单后添加云解析DNS记录进行质检。确认完成后可下载证书,并支持后续查看、更新和定时更新功能。证书过期前15天自动更新,需配置邮箱接收通知。
HTTPS 证书自动化运维:https证书管理系统之自动化签发
|
10月前
|
运维 监控 数据安全/隐私保护
HTTPS 证书自动化运维:HTTPS 证书管理系统之使用指南
本文详细介绍【灵燕空间HTTPS证书管理系统】(https://www.lingyanspace.com)的配置与使用,涵盖注册账户、邮箱配置及证书自动签发、监控和部署的一体化指南。通过页面顶部菜单的【视频教程】和【图文教程】,帮助用户从注册到实际应用全面掌握系统操作。最新迭代后,泛域名证书已包含根域名,无需额外申请多域名证书。

热门文章

最新文章