Java设计模式之工厂模式

Java设计模式之工厂模式
首先,学习模式,一定不能生搬硬套,一定要明天它的好处,为什么要用这个模式,以及这个模式的特点是什么。
对于工厂模式,我们最熟悉的就是spring里面的bean对象了。它起到解耦的作用。如果我们每次用到对象都new一个,那么当我们需要修改的时候
就会很麻烦,得一个一个的修改,这样不利于程序的解耦。这是它的主要作用,那么它的特点呢?
在代码里我们应该怎么写呢?工厂模式有很多种。
有简单工厂模式:用一个类去创建其他类的实例,父类是相同的,子类是具体的,那么这局限创造的范围
工厂方法模式:它的特点是一个抽象工厂可以派生出多个具体的工厂,而每个具体的工厂又可以对一个具体的对象进行创建
抽象工厂模式:它的特点是一个抽象工厂可以派生出多个具体的工厂,而每个具体的工厂可以对某一类对象进行创建
从上面三个模式可以看出,其实工厂模式的核心就是对类进行管理,那么我们抓住这个核心,就可以任意创建我们需要的模式

spring里面的工厂模式就是一个很好的例子-----程序启动时自动扫描需要创建的对象,把他们保存到一个map里面,当我们其他的类依赖它们的时,
就通过注解的value值反射出它们的实例并注入。

学习语言,无外乎多写多看多思多想,下面我自己写一下一个简单的实现,用来做自己的知识的积累:

首先:看看这个工厂类:

package testfactory;
import java.util.Map;
import testfactory.bean.Student;
public class BeanFactory {
public static  Object getBean(String beanName) throws Exception{
	 Map<String,String> clazzs= ClassScanUtil.getClassFormPackage("testfactory.bean");
    String clazz= clazzs.get(beanName);
	 Object object=Class.forName(clazz).newInstance();
	 return object;
}
public static void main(String[] args) throws Exception {
Student student=(Student) getBean("student");
student.study();
}
}
只需要得到类的名字就能得到这个类的具体的实例,其实这有些像spring的工厂模式,只不过spring的工厂模式面对的是接口,是得到这个接口下面的某个实现类,这

里只是一个简化版,下面看看ClassScanUtil如何实现:

package testfactory;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ClassScanUtil {
public static Map<String,String> getClassFormPackage(String packagePath) throws IOException, ClassNotFoundException{
	Map<String,String> clazzs = new HashMap<String,String>();
	String path=packagePath.replace(".", "/"); 
	 File directory =new File("");//设定为当前文件夹
     //定义一个枚举的集合 并进行循环来处理这个目录下的文件 
     Enumeration<URL> dirs;
     //得到资源路径
     dirs=Thread.currentThread().getContextClassLoader().getResources(path);
     if(dirs.hasMoreElements()){
    	URL url=dirs.nextElement();
    	//System.out.println(url.getFile());
    	File file=new File(url.getFile()); 
    	String[] strs=file.list();
    	for(String str:strs){
    	//得到这个路径下的所有class文件。这里只是 一个简版,默认是路径下只有class文件不存在文件包,
    	//如果想做的复杂可以看看file.list()一个需要过滤器的重载方法
    	  Class clazz=Class.forName(packagePath+"."+str.split("\\.")[0]);
    	  //这里是个自定义的注解,只有注解的类才能用于工厂生产
    	  FactoryMap factoryMap=(FactoryMap) clazz.getAnnotation(FactoryMap.class);
    	  if(factoryMap!=null){
    		  String s=isEmpty(factoryMap.value())?str.split("\\.")[0].toLowerCase():factoryMap.value();
    		  clazzs.put(isEmpty(factoryMap.value())?str.split("\\.")[0].toLowerCase():factoryMap.value(), packagePath+"."+str.split("\\.")[0]);
    	  }
    	}
     }
	return clazzs;
}
public static boolean isEmpty(String str){
	if(str==null||str.equals("")||"null".equals(str)){
		return true;
	}else{
		return false;
	}
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
	getClassFormPackage("testfactory.bean");
}
}
下面看看注解的实现:
package testfactory;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)//用于描述类、接口(包括注解类型) 或enum声明
@Retention(RetentionPolicy.RUNTIME)//运行时保留
@Documented
public @interface FactoryMap {
	 String value() default "";
}



只要在指定的包下的类加入这个注解,就能用BeanFactory的geBean方法得到这个类的具体事例:


package testfactory.bean;

import testfactory.FactoryMap;

@FactoryMap()
public class Student {
public void study(){
	System.out.println("学生爱学习");
}
}
这是今天对工厂的学习,每天进步一点点




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值