Java基础之工厂模式的思考
2015-07-08 12:01
567 查看
工厂设计
首先,我们拿水果作为本次案例的一个讲解:interface Fruits{ public void eat(); }; class Apple implements Fruits{ public void eat(){ System.out.println("I want to eat Apple....."); } }; class Oranger implements Fruits{ public void eat(){ System.out.println("I want to eat Oranger"); } };
And then ,我们编写一下客户端的代码:
public class Demo5Factory { public static void mian(String[] args){ Fruits f=new Apple(); f.eat(); Fruit f2 =new Oranger(); f2.eat(); } }
这样写,我们觉的合理吗?Why ?and How to do?
Why?
Analyse;
首先,我们应该保证,客户端或者调用端的代码应该足够简洁,并且他的修改代价是最少的。客户端的代码修改起来是简单的灵活的。
假设:如果我们的是分布式的应用,我们的客户端与程序是分割2地的,如果我们要修改后面的代码,我们也必须要修改客户端的代码。但为了避免客户端的代码改写,我们可以在后面做一些改写;
How?
resolution:
/** * 定义 工厂 方法; * @author R * */ class Factory{ public static Fruits getInstance(String className){ Fruits f=null; //注意这种写法是不可取的,应该采用这种写法 ” “。equals(className);这样可以避免抛出空指针,可悲我大3才发现并纠正这个不良的习惯啊; // if(className.equals("apple")){ // f=new Apple(); // }if(className.equals("Oranger")){ // f=new Oranger(); // } if("apple".equals(className)){ f=new Apple(); }if("Oranger".equals(className)){ f=new Oranger(); } return f; } };
这样我们的客户端就可以这样写:
public static void main(String[] args){ Fruits f1= Factory.getInstance("apple"); f1= Factory.getInstance(null); }这样写的好处,就是完全对Apple 进行了解耦,后端与前端代码完全隔离,如果要维护,我们也只需维护后端的代码即可。
用反射改进工厂模式
如果我们要添加一个新的类如 Watermelon 西瓜类 如我们就必须修改Factory 为了避免这样的事情发生,我们用反射对工厂进行以下修改:class Factory{ public static Fruit getInstance(String className){ Fruit f=null;; try { f=(Fruit) Class.forName(className).newInstance(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { e.printStackTrace(); } return f; } }我们调用是就如下实现:直接包路径+类名称
public static void main(String[] args){ Fruit f=Factory.getInstance("demoFactory001.Oranger"); f.eat(); }综上:我们这样是得到了改进,单在使用类的时候,我们必须要知道并且输入一段很长的 字符路径 使用起来就非常不方便,因此,有人提出了一个这样的设计思路;
通过配置文件+Factory来实现这种设计 ,于是呼,Spring 的 IOC 就诞生了。
模仿Spring的IOC
添加配置文件:E:\\fruit.propertiesapple=demoFactory002.Apple orange=demoFactory002.Orange
class Init{ public static Properties getPro(){ Properties pro = new Properties() ; File f = new File("E:\\fruit.properties") ; // 找到属性文件 try{ if(f.exists()){ // 文件存在 pro.load(new FileInputStream(f)) ; // 读取属性 } // else{ // pro.setProperty("apple","demoFactory002.Apple") ; // pro.setProperty("orange","demoFactory002.Orange") ; // pro.store(new FileOutputStream(f),"FRUIT CLASS") ; // } }catch(Exception e){} return pro ; } };实现如下:
public static void main(String args[]){ Properties pro = Init.getPro() ; Fruit f = Factory.getInstance(pro.getProperty("apple")) ; if(f!=null){ f.eat() ; } }
相关文章推荐
- Eclipse版本及概述
- java安装及配置
- Java 多线程 并发编程
- Java 实现 SSH 协议的客户端登录认证方式
- Spring3.2 中 Bean 定义之基于 XML 配置方式的源码解析
- 分析java对象内存占用
- Minimum Depth of Binary Tree Java
- JavaSE实战——API(中) 集合框架
- Maximum Depth of Binary Tree Java
- 在 Java 中使用启发式搜索更快地解决问题
- Java IO最详解
- 深入探索 Java 热部署
- 使用 Cobertura 和反射机制提高 Java 单元测试中的代码覆盖率
- Java中到底有没有指针;同时注意引用和指针的区别
- 如何关闭Java线程
- springMVC的HandlerInterceptor拦截器
- Mybatis整合Spring
- Java为何大行其道
- 总结了Struts1与Struts2的12点区别
- Struts2的国际化实现