学习笔记-轻量级Java EE:模式--简单工厂

来源:互联网 发布:淘宝店 源珍果醋 编辑:程序博客网 时间:2024/06/13 11:02

1.假如有多种产品,使用一个工厂来生产,使用者只与工厂联系在一起,该种方式称之为简单工厂模式。

2.下面摘抄一个简单的例子:(来源李刚的javaee实战)

    例子比较简单,一个工厂类管理了俩个打印机(实际会更多);而使用者Computer只与工厂类耦合;

   优势:让对象的调用者和对象创建过程分离,当对象调用者需要对象时,直接像工厂请求。从而避免了对象的调用者与对象的实现类以硬编码方式耦合,以提高系统的可维护性、可扩展性。

    缺陷:当产品修改时,工厂类也要做相应修改;当产品非常多,一个工厂类显然管理会混乱。

public class Computer{    private Output out;    private String name;    public Computer(){}    //out属性的setter和getter方法    public void setOut(Output out)    {        this.out = out;    }    //name属性的setter和getter方法    public void setName(String name)    {        this.name = name;    }    //定义一个模拟获取字符串输入的方法    public void keyIn(String msg)    {        out.getData(msg);    }    //定义一个模拟打印的方法    public void print()    {        System.out.println(name + "开始打印...");         out.out();    }}
public interface Output{//接口里定义的属性只能是常量int MAX_CACHE_LINE = 50;//接口里定义的只能是public的抽象实例方法void out();void getData(String msg);}
public class OutputFactory{public Output getOutput(String type){//下面两行代码用于控制系统到底使用Output的哪个实现类。if(type.equalsIgnoreCase("printer") {                    return new Printer();                } else {                    return new BetterPrinter();                }        }}
public class Printer implements Output{private String[] printData = new String[MAX_CACHE_LINE];//用以记录当前需打印的作业数private int dataNum = 0;public void out(){//只要还有作业,继续打印while(dataNum > 0){System.out.println("打印机打印:" + printData[0]);//把作业队列整体前移一位,并将剩下的作业数减1System.arraycopy(printData , 1, printData, 0, --dataNum);}}public void getData(String msg){if (dataNum >= MAX_CACHE_LINE){System.out.println("输出队列已满,添加失败");}else{//把打印数据添加到队列里,已保存数据的数量加1。printData[dataNum++] = msg;}}}
public class BetterPrinter implements Output{private String[] printData = new String[MAX_CACHE_LINE * 2];//用以记录当前需打印的作业数private int dataNum = 0;public void out(){//只要还有作业,继续打印while(dataNum > 0){System.out.println("高速打印机正在打印:" + printData[0]);//把作业队列整体前移一位,并将剩下的作业数减1System.arraycopy(printData , 1, printData, 0, --dataNum);}}public void getData(String msg){if (dataNum >= MAX_CACHE_LINE * 2){System.out.println("输出队列已满,添加失败");}else{//把打印数据添加到队列里,已保存数据的数量加1。printData[dataNum++] = msg;}}}

3.下面是简单的模拟Spring IoC的容器的方式来生成对象:(来源李刚的javaee实战)

    该容器仅仅实现了简单的IoC功能,可以创建并管理容器中所有的Bean实例。

<?xml version="1.0" encoding="GBK"?><beans><bean id="computer" class="Computer"><!-- 为name属性注入普通属性值 --><property name="name" value="李刚的电脑"/><!-- 为out属性注入普通属性值 --><property name="out" ref="betterPrinter"/></bean><!-- 配置两个Bean实例 --><bean id="printer" class="Printer"/> <bean id="betterPrinter" class="BetterPrinter"/><!-- 配置一个prototype行为的Bean实例 --><bean id="now" class="java.util.Date" scope="prototype"/> <!--①--></beans>
public interface ApplicationContext{//获取指定Bean实例的方法Object getBean(String name)throws Exception;}
public class YeekuXmlApplicationContextimplements ApplicationContext{//保存容器中所有单例模式的Bean实例private Map<String , Object> objPool= Collections.synchronizedMap(new HashMap<String , Object>()); //保存配置文件对应的Document对象private Document doc;//保存配置文件里的根元素private Element root;public YeekuXmlApplicationContext(String filePath)throws Exception{SAXReader reader = new SAXReader();doc = reader.read(new File(filePath));root = doc.getRootElement();initPool();initProp();}public Object getBean(String name)throws Exception{Object target = objPool.get(name);//对于singleton Bean,容器已经初始化了所有Bean实例if (target.getClass() != String.class){return target;}else{String clazz = (String)target;//对于prototype并未注入属性值return Class.forName(clazz).newInstance();}}//初始化容器中所有singleton Beanprivate void initPool()throws Exception{//遍历配置文件里的每个<bean.../>元素for (Object obj : root.elements()){Element beanEle = (Element)obj;//取得<bean.../>元素的id属性String beanId = beanEle.attributeValue("id");//取得<bean.../>元素的class属性String beanClazz = beanEle.attributeValue("class");//取得<bean.../>元素的scope属性String beanScope = beanEle.attributeValue("scope");//如果<bean.../>元素的scope属性不存在,或为singletonif (beanScope == null ||beanScope.equals("singleton")){//以默认构造器创建Bean实例,并将其放入objPool中objPool.put(beanId , Class.forName(beanClazz).newInstance());}else{//对于非singlton Bean,存放该Bean实现类的类名。objPool.put(beanId , beanClazz);}}}//初始化容器中singleton Bean的属性private void initProp()throws Exception{//遍历配置文件里的每个<bean.../>元素for (Object obj : root.elements()){Element beanEle = (Element)obj;//取得<bean.../>元素的id属性String beanId = beanEle.attributeValue("id");//取得<bean.../>元素的scope属性String beanScope = beanEle.attributeValue("scope");//如果<bean.../>元素的scope属性不存在,或为singletonif (beanScope == null ||beanScope.equals("singleton")){//取出objPool的指定的Bean实例Object bean = objPool.get(beanId);//遍历<bean.../>元素的每个<property.../>子元素for (Object prop : beanEle.elements()){Element propEle = (Element)prop;//取得<property.../>元素的name属性String propName = propEle.attributeValue("name");//取得<property.../>元素的value属性String propValue = propEle.attributeValue("value");//取得<property.../>元素的ref属性String propRef = propEle.attributeValue("ref");//将属性名的首字母大写String propNameCamelize = propName.substring(0 , 1).toUpperCase()+ propName.substring(1 , propName.length());//如果<property.../>元素的value属性值存在if (propValue != null && propValue.length() > 0){//获取设值注入所需的setter方法Method setter = bean.getClass().getMethod("set" + propNameCamelize , String.class);//执行setter注入setter.invoke(bean , propValue);}if (propRef != null && propRef.length() > 0){//取得需要被依赖注入的Bean实例Object target = objPool.get(propRef);//objPool池中不存在指定Bean实例if (target == null){//此处还应处理Singleton Bean依赖prototype Bean的情形}//定义设值注入所需的setter方法Method setter = null;//遍历target对象所所实现的所有接口for (Class superInterface : target.getClass().getInterfaces()){try{//获取设值注入所需的setter方法setter = bean.getClass().getMethod("set" + propNameCamelize , superInterface);//如果成功取得该接口对应的方法,直接跳出循环break;}catch (NoSuchMethodException ex){//如果没有找到对应的setter方法,继续下次循环continue;}}//如果setter方法依然为null,//则直接取得target实现类对应的setter方法if (setter == null){setter = bean.getClass().getMethod("set" + propNameCamelize , target.getClass());}//执行setter注入setter.invoke(bean , target);}}}}}}

0 0
原创粉丝点击