一, 什么是简单工厂模式
设计模式的核心是 "分工", 通过分工将对象与职责划分的更细化, 进而提升系统设计的可扩展性, 使其更容易维护.
开闭原则: 对扩展开放, 对修改关闭; 要增加一个新的处理逻辑, 可以开一个新的类, 不要在老的上面修改
依赖倒转原则: 依赖关系从具体转向抽象, 也就是说: A 调用 B, 不是直接调用 B 的实现, 而是依赖 B 的接口
迪米特法则: 类尽量少的与其他类发生关系, 或者产生依赖, 以此来使扩展可以更容易
工厂模式中的三种: 简单工厂模式, 工厂方法模式, 抽象工厂模式; 实现了创建者和调用者的分离, 调用者不需要知道具体的创建者是什么类, 只需要知道工厂的接口以及自己想要的产品名称, 就可以进行调用得到想要的产品
简单工厂模式: 简单工厂模式也称为静态工厂模式, 工厂类一般采用静态方法, 根据接收的参数不同来确定返回对象实例, 但简单工厂模式违反了开闭原则, 要增加一个新的类别必须要修改代码
注意, 简单工厂模式就是: 针对一个项目或者一个独立模块只有一个工厂类, 而工厂方法模式是有一组实现了相同接口的工厂类 (虽然符合开闭原则, 但是会增加新的类来扩展, 看情况而定, 实际上在项目开发中通常还是用简单工厂比较多)
二, 依据 Spring 中的 BeanFactory 自己实现简版
首先是, 先写一个接口类, BeanFactory 的接口类如下:
- public interfaceBeanFactory {
- Object getBean(String beanName);
- }
下面是 xml 配置文件 springtest.xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans>
- <bean id="usertest" class="beanfactory.demo.User">
- <property name="username" value="lxlx" />
- <property name="passWord" value="111" />
- <property name="age" value="11"/>
- </bean>
- </beans>
下面是 bean 定义的 class 文件 User 类:
- public class User {
- private String username;
- private String passWord;
- private int age;
- public void setUsername(String username) {
- this.username = username;
- }
- public void setPassWord(String passWord) {
- this.passWord = passWord;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getUsername() {
- return username;
- }
- public String getPassWord() {
- return passWord;
- }
- public int getAge() {
- return age;
- }
- }
接下来是实现类 ConcreteBeanFactory:
- package beanfactory.demo;
- import org.dom4j.io.SAXReader;
- import org.dom4j.*;
- import java.io.File;
- import java.lang.reflect.Type;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Iterator;
- import java.lang.reflect.Method;
- /**
- * Created by xiami on 2019/5/26.
- */
- public class ConcreteBeanFactory implements BeanFactory{
- private Map<String, Object> beanDefinitionMap = new HashMap<String, Object>();
- // 简单工厂模式的特征是: 一个工厂中可以生产多种不同的产品, 这里的 Bean 其实是没有区分不同的 bean, 是可以通过 get 返回不同的 bean
- @Override
- public Object getBean(String beanName) {
- return beanDefinitionMap.get(beanName);
- }
- // 增加一个 init 的操作方法
- // 从 xml 配置文件中进行解析读取
- public void init(String xmlPath){
- SAXReader saxReader = new SAXReader();
- File file = new File(xmlPath);
- try {
- Document document = saxReader.read(file);
- Element root = document.getRootElement();
- Element foo;
- // 遍历 bean
- for (Iterator i = root.elementIterator("bean"); i.hasNext();) {
- foo = (Element) i.next();
- // 获取 bean 的属性 id 和 class
- Attribute id = foo.attribute("id");
- Attribute cls = foo.attribute("class");
- // 利用 Java 反射机制, 通过 class 的名称获取 Class 对象
- Class<?> bean = Class.forName(cls.getText());
- // 获取对应 class 的信息
- java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);
- // 获取其属性描述
- java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();
- // 设置值的方法
- Method mSet = null;
- // 创建一个对象
- Object obj = bean.newInstance();
- // 遍历该 bean 的 property 属性
- for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {
- Element foo2 = (Element) ite.next();
- // 获取该 property 的 name 属性
- Attribute name = foo2.attribute("name");
- String value = null;
- Object typeValue = null;
- // 获取 value 值
- value = foo2.attributeValue("value");
- for (int k = 0; k < pd.length; k++) {
- if (pd[k].getName().equalsIgnoreCase(name.getText())) {
- mSet = pd[k].getWriteMethod();
- // 设置值这里, 需要根据类型给 value 做类型转换
- //properties 中包含了 properType 的项, 因为当前程序中就只有 String 和 Int, 先处理这样的类型
- Type mType = pd[k].getPropertyType();
- if (mType.getTypeName().equals("java.lang.String")){
- typeValue = String.valueOf(value);
- }
- else if(mType.getTypeName().equals("int")){
- typeValue = Integer.parseInt(value);
- }
- mSet.invoke(obj, typeValue);
- }
- }
- }
- // 将对象放入 beanMap 中, 其中 key 为 id 值, value 为对象
- beanDefinitionMap.put(id.getText(), obj);
- }
- }catch (Exception e){
- System.out.println(e.toString());
- }
- }
- }
下面是测试类:
- public class Client {
- public static void main(String[] args){
- AbstractBeanFactory absbf = new AbstractBeanFactory();
- absbf.init("E:\\java-demo\\src\\beanfactory\\demo\\springtest.xml");
- User user = (User)absbf.getBean("usertest");
- System.out.println("User 类的 bean 有没有创建成功:" + user);
- System.out.println("属性值:" + user.getUsername() + "," + user.getPassWord() + "," + user.getAge());
- }
- }
测试结果是:
要理解的是: 简单工厂模式是一种思想, 就是: 不针对特定的产品进行工厂的划分, 也就是说没有多个批次或者类别的工厂, 而是所有的内容都在一个工厂里面生产, 你需要什么我给你什么即可
参考文章: https://blog.csdn.net/mlc1218559742/article/details/52776160/
来源: https://www.cnblogs.com/keke-xiaoxiami/p/10934406.html