首页 > 其他分享 >简单工厂VS工厂方法&手写自动化工厂——系统学习六

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

时间:2022-12-05 17:03:42浏览次数:44  
标签:java 子类 class 工厂 VS import 手写 public


一、背景介绍

工厂方法仅仅为了解决简单工厂判断不符合开闭原则的问题?
工厂方法仅仅为了解决业务子类实例化的问题?
然而我的观点是工厂方法是为了解决自动化创建对象的问题;如何理解这句话?请读者朋友继续往下看。

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

二、学习思路

1.绘制模式的UML图
2.根据UML图编写代码
3.寻找模式的例子进行UML图的绘制
4.根据例子的UML图编写代码
5.对比两个模式的区别,以及分别的作用与意义
6.请教高人

三、学习过程

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

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


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


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工厂的过程中了解到注解扫描类默认为单例,为什么?

五、升华

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


标签:java,子类,class,工厂,VS,import,手写,public
From: https://blog.51cto.com/u_14471711/5913073

相关文章

  • Qt+vs读取文件(文件对话框问题)
    QtCreator文件定位正确,VS2010+QT定位失败://选择数据库名称voiddbSettingDlg::on_selectBtn_clicked(){QStringdataBaseName=QFileDialog::getOpenFileName(thi......
  • 精选、前端开发N个必备的 VSCode 插件
    目录​​一、汉化vscode​​​​二、vue2代码提示​​​​三、格式化高亮vue代码​​​​四、实时预览网页效果​​​​五、html标签​​​​六、格式化代码​​​​七、规......
  • VS工具箱没有控件解决办法
    https://jingyan.baidu.com/article/148a1921d4acdf4d71c3b1ec.html首先确认自己不是在如下图所示的代码编写界面,因为在该界面下右边的工具箱窗口中没有控件,这是由于不......
  • 数据中心服务器大战:思科vs惠普vsIBMvs戴尔
    思科去过一直被视为一家纯粹的网络公司。在企业和服务提供商网络中,以及在路由器和交换机市场上,思科都占据着统治地位,拥有举足轻重的影响力。惠普曾经是思科的长期合作伙伴......
  • 图像处理技术OpencvSharp入门
    目录第一部分初识Opencv1.C#下Opencv库2.安装OpenCvSharp第二部分OpencvSharp入门1.加载图像文件2.显示图像第三部分基础应用1.颜色转换2.尺寸调整3.二值化......
  • vs 使用第三方库配置jsoncpp
    https://blog.csdn.net/hml111666/article/details/127227992?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendF......
  • 在VS2008中打开VS2010项目解决办法
    在VS08版打开VS10版时可能会出现问题:1.无法识别工具版本4.0;此时的解决方案如下:————————————————————————————————请把以下代码复制到一......
  • VC6.0和VS2005:C++和C#编写调用COM组件
    这篇文章就是关于COM组件的编写和调用的,主要包含了使用VC6.0编写和调用COM组件,VS2005中使用C#编写和调用COM组件,以及在VC6.0和VS2005之间互相调用COM组件。前一阵在......
  • structs里Dispatchaction VS LookupDispathAction
    Struts里这两个玩意还是十分有用的,近来学习到,故总结之首先,DispatchAction的作用简单地说就是把原来我们写在多个acton里的操作放在同一个actio......
  • opencv460在win10+vs2017上的编译
    近期有网友提问,正好把最新的460编译情况简单整理一下。1、下载并解压2、cmake打开,一般选择最新版本cmake3、如果需要编译64位的,这里一定要选64.默认是32位。此外,openc......