简单工厂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月前
|
运维 Linux Apache
Puppet 作为一款强大的自动化运维工具,被广泛应用于配置管理领域。通过定义资源的状态和关系,Puppet 能够确保系统始终处于期望的配置状态。
Puppet 作为一款强大的自动化运维工具,被广泛应用于配置管理领域。通过定义资源的状态和关系,Puppet 能够确保系统始终处于期望的配置状态。
66 3
|
15天前
|
人工智能 自然语言处理 JavaScript
Agent-E:基于 AutoGen 代理框架构建的 AI 浏览器自动化系统
Agent-E 是一个基于 AutoGen 代理框架构建的智能自动化系统,专注于浏览器内的自动化操作。它能够执行多种复杂任务,如填写表单、搜索和排序电商产品、定位网页内容等,从而提高在线效率,减少重复劳动。本文将详细介绍 Agent-E 的功能、技术原理以及如何运行该系统。
59 5
Agent-E:基于 AutoGen 代理框架构建的 AI 浏览器自动化系统
|
2月前
|
机器学习/深度学习 人工智能 机器人
智能废物管理系统:城市垃圾的自动化处理
【10月更文挑战第24天】智能废物管理系统利用物联网、大数据、人工智能和自动化机器人等技术,实现城市垃圾从分类、收集到处理的全过程自动化,提高处理效率,优化资源配置,提升居民参与度,降低运营成本,推动城市可持续发展。
|
1月前
|
运维 监控 网络协议
自动化运维的魔法——打造高效、可靠的系统
【10月更文挑战第32天】在数字化时代的浪潮下,运维不再是简单的硬件维护和故障排除。它已经演变成一场关乎效率、稳定性和创新的技术革命。自动化运维,作为这场革命的核心,正引领着企业走向更加智能和高效的未来。本文将带你探索自动化运维的世界,揭示其背后的原理和实践,让你领略到自动化带来的无限可能。
28 0
|
2月前
|
测试技术 Python
自动化测试项目学习笔记(二):学习各种setup、tearDown、断言方法
本文主要介绍了自动化测试中setup、teardown、断言方法的使用,以及unittest框架中setUp、tearDown、setUpClass和tearDownClass的区别和应用。
76 0
自动化测试项目学习笔记(二):学习各种setup、tearDown、断言方法
|
2月前
|
运维 监控 安全
构建高效运维体系:从监控到自动化的全面指南在当今数字化时代,运维作为保障系统稳定性和效率的重要环节,其重要性不言而喻。本文将深入探讨如何构建一个高效的运维体系,从监控系统的搭建到自动化运维的实施,旨在为读者提供一套完整的解决方案。
本文详细介绍了高效运维体系的构建过程,包括监控系统的选择与部署、日志分析的方法、性能优化的策略以及自动化运维工具的应用。通过对这些关键环节的深入剖析,帮助运维人员提升系统的可靠性和响应速度,降低人工干预成本,实现业务的快速发展和稳定运行。
|
2月前
|
机器学习/深度学习 供应链 搜索推荐
机器学习驱动的工厂自动化
机器学习驱动的工厂自动化是一种利用先进的机器学习技术来提升生产效率、降低成本和提高产品质量的智能制造方法。
41 2
|
2月前
|
运维 Prometheus 监控
运维中的自动化实践每月一次的系统维护曾经是许多企业的噩梦。不仅因为停机时间长,更因为手动操作容易出错。然而,随着自动化工具的引入,这一切正在悄然改变。本文将探讨自动化在IT运维中的重要性及其具体应用。
在当今信息技术飞速发展的时代,企业对系统的稳定性和效率要求越来越高。传统的手动运维方式已经无法满足现代企业的需求。自动化技术的引入不仅提高了运维效率,还显著降低了出错风险。本文通过几个实际案例,展示了自动化在IT运维中的具体应用,包括自动化部署、监控告警和故障排除等方面,旨在为读者提供一些实用的参考。
|
3月前
使用装饰器实现自动化日志系统
使用装饰器实现自动化日志系统
24 0
|
3月前
|
运维 监控 负载均衡
高效运维管理:如何通过自动化提升系统可靠性
本文探讨了如何通过自动化提升系统可靠性,包括自动化监控、自动化部署、自动化测试和自动化故障恢复四个方面。通过实际案例展示了自动化在运维中的应用效果,强调了团队建设与培训的重要性以及持续改进与优化的策略。
43 0