JDK设计模式之——工厂模式

1.首先来看最普通的工厂模式

1.1 定义一个需要工厂生产的java类

package javaee.net.cn.factory;

class Person{
    private int age;
    private String name;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Person [age=" + age + ", name=" + name + "]";
    }
    
}

1.2 写一个最普通的工厂

package javaee.net.cn.factory;

import org.junit.Test;
public class BeanFactory {
    
    @Test
    public void test() throws Exception{
        Person  person = createPerson();
        System.out.println(person.toString());
    }
    public static  Person createPerson(){
        return new Person();
    }
}

上面的是最普通的工厂模式,不过使用new关键字来创建的对象,如果代码中出现很多这种new的代码(POJO除外)

那么 这种非常不容易维护和扩展。

2.对工厂模式优化 -->反射工厂

package javaee.net.cn.factory;

import org.junit.Test;
public class BeanFactory {
    @SuppressWarnings("unchecked")
    public static  <T> T getBean(String className,Class<T> Type) throws Exception{
        Class<T> clz = (Class<T>) Class.forName(className);
        Object obj = clz.newInstance();//进行实例化操作,要求类中必须存在无参的构造方法
        if(!Type.isInstance(obj)){
            throw new Exception("对象和内容不兼容");
        }
        return (T)obj;
    }
    
    @Test
    public void test() throws Exception{
        Person person = getBean("javaee.net.cn.factory.Person",Person.class);
        System.out.println(person.toString());
    }
}
Tip:getBean是一个泛型方法,可以在编译期间检查所要传入的对象和想要获取的对象是否一致
反射工厂虽然没有了虽然对普通工厂有一些改善(避免了new关键字)但是还是出现了硬编码
"javaee.net.cn.factory.Person"
3.利用Annotation改善反射工厂
3.1先定义一个注解@FactoryFlag

package javaee.net.cn.factory.strategy;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface FactoryFlag { // 定义一个Annotation
    public String className();//定义一个className()属性
}
3.2把注解应用到BeanFactory 
package javaee.net.cn.factory;

import javaee.net.cn.factory.strategy.FactoryFlag;

import org.junit.Test;
@FactoryFlag(className="javaee.net.cn.factory.Person")
public class BeanFactory {
    @SuppressWarnings("unchecked")
    public static  <T> T getBean(String className,Class<T> Type) throws Exception{
        Class<T> clz = (Class<T>) Class.forName(className);
        Object obj = clz.newInstance();//进行实例化操作,要求类中必须存在无参的构造方法
        if(!Type.isInstance(obj)){
            throw new Exception("对象和内容不兼容");
        }
        return (T)obj;
    }
    
    @Test
    public void test() throws Exception{
        Class<?> cls = BeanFactory.class;
        FactoryFlag factoryFlag = cls.getAnnotation(FactoryFlag.class);
        String className = factoryFlag.className();
        Person person = BeanFactory.getBean(className,Person.class);
        System.out.println(person.toString());
    }
}

这样 我们的代码里面就没有硬编码了 而是写在了注解上,@FactoryFlag(className="javaee.net.cn.factory.Person")

当然 也可以写在配置文件里,然后读进来,我们在这里是写在注解上 然后去读取注解

里面用到的一些放射方法(获取注解、创建对象) 大家可以去参考JDK的API

上面的Demo Bean工厂只生产了一个对象,其实:工厂可以生产一系列对象(这才叫工厂吗)

这样 我们替换工厂的时候 可以直接替换掉那一系列对象,工厂也可以利用多态 写成抽象工厂

原文地址:https://www.cnblogs.com/ssskkk/p/9185308.html