public class test02 {
private static final String CLASS_001 = "com.className1";
private static final String CLASS_002 = "com.className1";
private static final String CLASS_003 = "com.className1";
private static HashMap hm = new HashMap();
/**
* 根据Class Name创建实例
* @param className
* @return
* @throws Exception
* @author
*/
private static Object getObjectByClassName(String className) throws Exception
{
try
{
return Class.forName(className).newInstance();
}
catch (Exception e)
{
throw e;
}
}
/**
* 为web service接口提供实现
* @return
* @throws Exception
* @author
*/
public static className1Interface getExtInterface() throws Exception
{
if (hm.get(CLASS_001) != null)
{
return (className1Interface) hm.get(CLASS_001);
}
else
{
Object object = getObjectByClassName(CLASS_001);
hm.put(CLASS_001, object);
return (className1Interface) object;
}
}
}
解决方案 »
- 拜求大神解惑,帮我加下注释好吗??看看题目中的疑问...
- 一起讨论软件项目开发过程中。业务与技术的关系。。
- Swing源码中的<code>是什么意思,还有<i>什么的
- 继承构造函数为private的父类时,一旦为内隐类就不出错了,弄不清楚原因。
- 请教PrinterJob中的未知异常
- JTable里一列设置为JCheckBox出现的郁闷问题
- 类QQ的文本功能
- ###那么多控制台窗口怎么办?###
- Spring事务配置和程序代码结构都正确,为什么事务就是不起作用。实在想不出哪里有问题。
- 关于ArrayList和LinkedList
- 关于java socket编程中文件传输问题
- javaSE之有才人士帮帮我吧?
板桥里人 http://www.jdon.com 2002/10/07定义:提供创建对象的接口.为何使用?
工厂模式是我们最常用的模式了,著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑实用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。我们以类Sample为例, 如果我们要创建Sample的实例对象:Sample sample=new Sample();可是,实际情况是,通常我们都要在创建sample实例时做点初始化的工作,比如赋值 查询数据库等。首先,我们想到的是,可以使用Sample的构造函数,这样生成实例就写成:Sample sample=new Sample(参数);但是,如果创建sample实例时所做的初始化工作不是象赋值这样简单的事,可能是很长一段代码,如果也写入构造函数中,那你的代码很难看了(就需要Refactor重整)。为什么说代码很难看,初学者可能没有这种感觉,我们分析如下,初始化工作如果是很长一段代码,说明要做的工作很多,将很多工作装入一个方法中,相当于将很多鸡蛋放在一个篮子里,是很危险的,这也是有背于Java面向对象的原则,面向对象的封装(Encapsulation)和分派(Delegation)告诉我们,尽量将长的代码分派“切割”成每段,将每段再“封装”起来(减少段和段之间偶合联系性),这样,就会将风险分散,以后如果需要修改,只要更改每段,不会再发生牵一动百的事情。在本例中,首先,我们需要将创建实例的工作与使用实例的工作分开, 也就是说,让创建实例所需要的大量初始化工作从Sample的构造函数中分离出去。这时我们就需要Factory工厂模式来生成对象了,不能再用上面简单new Sample(参数)。还有,如果Sample有个继承如MySample, 按照面向接口编程,我们需要将Sample抽象成一个接口.现在Sample是接口,有两个子类MySample 和HisSample .我们要实例化他们时,如下:Sample mysample=new MySample();
Sample hissample=new HisSample();随着项目的深入,Sample可能还会"生出很多儿子出来", 那么我们要对这些儿子一个个实例化,更糟糕的是,可能还要对以前的代码进行修改:加入后来生出儿子的实例.这在传统程序中是无法避免的.但如果你一开始就有意识使用了工厂模式,这些麻烦就没有了.工厂方法
你会建立一个专门生产Sample实例的工厂:public class Factory{ public static Sample creator(int which){ //getClass 产生Sample 一般可使用动态类装载装入类。
if (which==1)
return new SampleA();
else if (which==2)
return new SampleB(); }}
那么在你的程序中,如果要实例化Sample时.就使用Sample sampleA=Factory.creator(1);这样,在整个就不涉及到Sample的具体子类,达到封装效果,也就减少错误修改的机会,这个原理可以用很通俗的话来比喻:就是具体事情做得越多,越容易范错误.这每个做过具体工作的人都深有体会,相反,官做得越高,说出的话越抽象越笼统,范错误可能性就越少.好象我们从编程序中也能悟出人生道理?呵呵.使用工厂方法 要注意几个角色,首先你要定义产品接口,如上面的Sample,产品接口下有Sample接口的实现类,如SampleA,其次要有一个factory类,用来生成产品Sample,如下图,最右边是生产的对象Sample:进一步稍微复杂一点,就是在工厂类上进行拓展,工厂类也有继承它的实现类concreteFactory了。抽象工厂
工厂模式中有: 工厂方法(Factory Method) 抽象工厂(Abstract Factory).这两个模式区别在于需要创建对象的复杂程度上。如果我们创建对象的方法变得复杂了,如上面工厂方法中是创建一个对象Sample,如果我们还有新的产品接口Sample2.这里假设:Sample有两个concrete类SampleA和SamleB,而Sample2也有两个concrete类Sample2A和SampleB2那么,我们就将上例中Factory变成抽象类,将共同部分封装在抽象类中,不同部分使用子类实现,下面就是将上例中的Factory拓展成抽象工厂:public abstract class Factory{ public abstract Sample creator(); public abstract Sample2 creator(String name); }public class SimpleFactory extends Factory{ public Sample creator(){
.........
return new SampleA
} public Sample2 creator(String name){
.........
return new Sample2A
}}public class BombFactory extends Factory{ public Sample creator(){
......
return new SampleB
} public Sample2 creator(String name){
......
return new Sample2B
}}
从上面看到两个工厂各自生产出一套Sample和Sample2,也许你会疑问,为什么我不可以使用两个工厂方法来分别生产Sample和Sample2? 抽象工厂还有另外一个关键要点,是因为 SimpleFactory内,生产Sample和生产Sample2的方法之间有一定联系,所以才要将这两个方法捆绑在一个类中,这个工厂类有其本身特征,也许制造过程是统一的,比如:制造工艺比较简单,所以名称叫SimpleFactory。在实际应用中,工厂方法用得比较多一些,而且是和动态类装入器组合在一起应用,举例我们以Jive的ForumFactory为例,这个例子在前面的Singleton模式中我们讨论过,现在再讨论其工厂模式:public abstract class ForumFactory { private static Object initLock = new Object();
private static String className = "com.jivesoftware.forum.database.DbForumFactory";
private static ForumFactory factory = null; public static ForumFactory getInstance(Authorization authorization) {
//If no valid authorization passed in, return null.
if (authorization == null) {
return null;
}
//以下使用了Singleton 单态模式
if (factory == null) {
synchronized(initLock) {
if (factory == null) {
...... try {
//动态转载类
Class c = Class.forName(className);
factory = (ForumFactory)c.newInstance();
}
catch (Exception e) {
return null;
}
}
}
} //Now, 返回 proxy.用来限制授权对forum的访问
return new ForumFactoryProxy(authorization, factory,
factory.getPermissions(authorization));
} //真正创建forum的方法由继承forumfactory的子类去完成.
public abstract Forum createForum(String name, String description)
throws UnauthorizedException, ForumAlreadyExistsException; ....}
因为现在的Jive是通过数据库系统存放论坛帖子等内容数据,如果希望更改为通过文件系统实现,这个工厂方法ForumFactory就提供了提供动态接口:private static String className = "com.jivesoftware.forum.database.DbForumFactory";你可以使用自己开发的创建forum的方法代替com.jivesoftware.forum.database.DbForumFactory就可以.在上面的一段代码中一共用了三种模式,除了工厂模式外,还有Singleton单态模式,以及proxy模式,proxy模式主要用来授权用户对forum的访问,因为访问forum有两种人:一个是注册用户 一个是游客guest,那么那么相应的权限就不一样,而且这个权限是贯穿整个系统的,因此建立一个proxy,类似网关的概念,可以很好的达到这个效果. 看看Java宠物店中的CatalogDAOFactory:public class CatalogDAOFactory { /** * 本方法制定一个特别的子类来实现DAO模式。
* 具体子类定义是在J2EE的部署描述器中。
*/ public static CatalogDAO getDAO() throws CatalogDAOSysException { CatalogDAO catDao = null; try { InitialContext ic = new InitialContext();
//动态装入CATALOG_DAO_CLASS
//可以定义自己的CATALOG_DAO_CLASS,从而在无需变更太多代码
//的前提下,完成系统的巨大变更。 String className =(String) ic.lookup(JNDINames.CATALOG_DAO_CLASS); catDao = (CatalogDAO) Class.forName(className).newInstance(); } catch (NamingException ne) { throw new CatalogDAOSysException("
CatalogDAOFactory.getDAO: NamingException while
getting DAO type : \n" + ne.getMessage()); } catch (Exception se) { throw new CatalogDAOSysException("
CatalogDAOFactory.getDAO: Exception while getting
DAO type : \n" + se.getMessage()); } return catDao; }}
CatalogDAOFactory是典型的工厂方法,catDao是通过动态类装入器className获得CatalogDAOFactory具体实现子类,这个实现子类在Java宠物店是用来操作catalog数据库,用户可以根据数据库的类型不同,定制自己的具体实现子类,将自己的子类名给与CATALOG_DAO_CLASS变量就可以。由此可见,工厂方法确实为系统结构提供了非常灵活强大的动态扩展机制,只要我们更换一下具体的工厂方法,系统其他地方无需一点变换,就有可能将系统功能进行改头换面的变化。
板桥里人 http://www.jdon.com 2002/05/07定义:
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。如何使用?
因为Java中的提供clone()方法来实现对象的克隆(具体了解clone()按这里),所以Prototype模式实现一下子变得很简单.以勺子为例:public abstract class AbstractSpoon implements Cloneable
{
String spoonName; public void setSpoonName(String spoonName) {this.spoonName = spoonName;}
public String getSpoonName() {return this.spoonName;} public Object clone()
{
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException exception) {
System.err.println("AbstractSpoon is not Cloneable");
}
return object;
}
}
有两个具体实现(ConcretePrototype):public class SoupSpoon extends AbstractSpoon
{
public SoupSpoon()
{
setSpoonName("Soup Spoon");
}
}public class SaladSpoon extends AbstractSpoon
{
public SaladSpoon()
{
setSpoonName("Salad Spoon");
}
}
调用Prototype模式很简单:AbstractSpoon spoon = new SoupSpoon();
AbstractSpoon spoon = new SaladSpoon(); 当然也可以结合工厂模式来创建AbstractSpoon实例。在Java中Prototype模式变成clone()方法的使用,由于Java的纯洁的面向对象特性,使得在Java中使用设计模式变得很自然,两者已经几乎是浑然一体了。这反映在很多模式上,如Interator遍历模式。
设计模式之Builder
板桥里人 http://www.jdon.com 2002/05/07Builder模式定义:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们.用户不知道内部的具体构建细节.Builder模式是非常类似抽象工厂模式,细微的区别大概只有在反复使用中才能体会到.为何使用?
是为了将构建复杂对象的过程和它的部件解耦.注意: 是解耦过程和部件.因为一个复杂的对象,不但有很多大量组成部分,如汽车,有很多部件:车轮 方向盘 发动机还有各种小零件等等,部件很多,但远不止这些,如何将这些部件装配成一辆汽车,这个装配过程也很复杂(需要很好的组装技术),Builder模式就是为了将部件和组装过程分开.如何使用?
首先假设一个复杂对象是由多个部件组成的,Builder模式是把复杂对象的创建和部件的创建分别开来,分别用Builder类和Director类来表示.首先,需要一个接口,它定义如何创建复杂对象的各个部件:public interface Builder { //创建部件A 比如创建汽车车轮
void buildPartA();
//创建部件B 比如创建汽车方向盘
void buildPartB();
//创建部件C 比如创建汽车发动机
void buildPartC(); //返回最后组装成品结果 (返回最后装配好的汽车)
//成品的组装过程不在这里进行,而是转移到下面的Director类中进行.
//从而实现了解耦过程和部件
Product getResult(); }
用Director构建最后的复杂对象,而在上面Builder接口中封装的是如何创建一个个部件(复杂对象是由这些部件组成的),也就是说Director的内容是如何将部件最后组装成成品:public class Director { private Builder builder; public Director( Builder builder ) {
this.builder = builder;
}
// 将部件partA partB partC最后组成复杂对象
//这里是将车轮 方向盘和发动机组装成汽车的过程
public void construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC(); } }
Builder的具体实现ConcreteBuilder:
通过具体完成接口Builder来构建或装配产品的部件;
定义并明确它所要创建的是什么具体东西;
提供一个可以重新获取产品的接口:public class ConcreteBuilder implements Builder { Part partA, partB, partC;
public void buildPartA() {
//这里是具体如何构建partA的代码 };
public void buildPartB() {
//这里是具体如何构建partB的代码
};
public void buildPartC() {
//这里是具体如何构建partB的代码
};
public Product getResult() {
//返回最后组装成品结果
}; }
复杂对象:产品Product:public interface Product { }
复杂对象的部件:public interface Part { }
我们看看如何调用Builder模式:
ConcreteBuilder builder = new ConcreteBuilder();
Director director = new Director( builder ); director.construct();
Product product = builder.getResult(); Builder模式的应用
在Java实际使用中,我们经常用到"池"(Pool)的概念,当资源提供者无法提供足够的资源,并且这些资源需要被很多用户反复共享时,就需要使用池."池"实际是一段内存,当池中有一些复杂的资源的"断肢"(比如数据库的连接池,也许有时一个连接会中断),如果循环再利用这些"断肢",将提高内存使用效率,提高池的性能.修改Builder模式中Director类使之能诊断"断肢"断在哪个部件上,再修复这个部件.
设计模式之Proxy(代理)
板桥里人banq http://www.jdon.com 2002/04/21/理解并使用设计模式,能够培养我们良好的面向对象编程习惯,同时在实际应用中,可以如鱼得水,享受游刃有余的乐趣.Proxy是比较有用途的一种模式,而且变种较多,应用场合覆盖从小结构到整个系统的大结构,Proxy是代理的意思,我们也许有代理服务器等概念,代理概念可以解释为:在出发点到目的地之间有一道中间层,意为代理.设计模式中定义: 为其他对象提供一种代理以控制对这个对象的访问.为什么要使用Proxy?
1.授权机制 不同级别的用户对同一对象拥有不同的访问权利,如Jive论坛系统中,就使用Proxy进行授权机制控制,访问论坛有两种人:注册用户和游客(未注册用户),Jive中就通过类似ForumProxy这样的代理来控制这两种用户对论坛的访问权限.
2.某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动.
举例两个具体情况:
(1)如果那个对象是一个是很大的图片,需要花费很长时间才能显示出来,那么当这个图片包含在文档中时,使用编辑器或浏览器打开这个文档,打开文档必须很迅速,不能等待大图片处理完成,这时需要做个图片Proxy来代替真正的图片.
(2)如果那个对象在Internet的某个远端服务器上,直接操作这个对象因为网络速度原因可能比较慢,那我们可以先用Proxy来代替那个对象.总之原则是,对于开销很大的对象,只有在使用它时才创建,这个原则可以为我们节省很多宝贵的Java内存. 所以,有些人认为Java耗费资源内存,我以为这和程序编制思路也有一定的关系.如何使用Proxy?
以Jive论坛系统为例,访问论坛系统的用户有多种类型:注册普通用户 论坛管理者 系统管理者 游客,注册普通用户才能发言;论坛管理者可以管理他被授权的论坛;系统管理者可以管理所有事务等,这些权限划分和管理是使用Proxy完成的.Forum是Jive的核心接口,在Forum中陈列了有关论坛操作的主要行为,如论坛名称 论坛描述的获取和修改,帖子发表删除编辑等.在ForumPermissions中定义了各种级别权限的用户:public class ForumPermissions implements Cacheable { /**
* Permission to read object.
*/
public static final int READ = 0;/**
* Permission to administer the entire sytem.
*/
public static final int SYSTEM_ADMIN = 1;/**
* Permission to administer a particular forum.
*/
public static final int FORUM_ADMIN = 2;/**
* Permission to administer a particular user.
*/
public static final int USER_ADMIN = 3;/**
* Permission to administer a particular group.
*/
public static final int GROUP_ADMIN = 4;/**
* Permission to moderate threads.
*/
public static final int MODERATE_THREADS = 5;/**
* Permission to create a new thread.
*/
public static final int CREATE_THREAD = 6;/**
* Permission to create a new message.
*/
public static final int CREATE_MESSAGE = 7;/**
* Permission to moderate messages.
*/
public static final int MODERATE_MESSAGES = 8;.....public boolean isSystemOrForumAdmin() {
return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]);
}.....}
因此,Forum中各种操作权限是和ForumPermissions定义的用户级别有关系的,作为接口Forum的实现:ForumProxy正是将这种对应关系联系起来.比如,修改Forum的名称,只有论坛管理者或系统管理者可以修改,代码如下:public class ForumProxy implements Forum {private ForumPermissions permissions;
private Forum forum;
this.authorization = authorization; public ForumProxy(Forum forum, Authorization authorization,
ForumPermissions permissions)
{
this.forum = forum;
this.authorization = authorization;
this.permissions = permissions;
}
public void setName(String name) throws UnauthorizedException,
ForumAlreadyExistsException
{
//只有是系统或论坛管理者才可以修改名称
if (permissions.isSystemOrForumAdmin()) {
forum.setName(name);
}
else {
throw new UnauthorizedException();
}
}而DbForum才是接口Forum的真正实现,以修改论坛名称为例:public class DbForum implements Forum, Cacheable {
public void setName(String name) throws ForumAlreadyExistsException { .... this.name = name;
//这里真正将新名称保存到数据库中
saveToDb();}凡是涉及到对论坛名称修改这一事件,其他程序都首先得和ForumProxy打交道,由ForumProxy决定是否有权限做某一样事情,ForumProxy是个名副其实的"网关","安全代理系统".在平时应用中,无可避免总要涉及到系统的授权或安全体系,不管你有无意识的使用Proxy,实际你已经在使用Proxy了.我们继续结合Jive谈入深一点,下面要涉及到工厂模式了,如果你不了解工厂模式,请看我的另外一篇文章:设计模式之Factory我们已经知道,使用Forum需要通过ForumProxy,Jive中创建一个Forum是使用Factory模式,有一个总的抽象类ForumFactory,在这个抽象类中,调用ForumFactory是通过getInstance()方法实现,这里使用了Singleton(也是设计模式之一,由于介绍文章很多,我就不写了,看这里),getInstance()返回的是ForumFactoryProxy.为什么不返回ForumFactory,而返回ForumFactory的实现ForumFactoryProxy?
原因是明显的,需要通过代理确定是否有权限创建forum.在ForumFactoryProxy中我们看到代码如下:public class ForumFactoryProxy extends ForumFactory { protected ForumFactory factory;
protected Authorization authorization;
protected ForumPermissions permissions; public ForumFactoryProxy(Authorization authorization, ForumFactory factory,
ForumPermissions permissions)
{
this.factory = factory;
this.authorization = authorization;
this.permissions = permissions;
} public Forum createForum(String name, String description)
throws UnauthorizedException, ForumAlreadyExistsException
{
//只有系统管理者才可以创建forum
if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) {
Forum newForum = factory.createForum(name, description);
return new ForumProxy(newForum, authorization, permissions);
}
else {
throw new UnauthorizedException();
}
}
方法createForum返回的也是ForumProxy, Proxy就象一道墙,其他程序只能和Proxy交互操作.注意到这里有两个Proxy:ForumProxy和ForumFactoryProxy. 代表两个不同的职责:使用Forum和创建Forum;
至于为什么将使用对象和创建对象分开,这也是为什么使用Factory模式的原因所在:是为了"封装" "分派";换句话说,尽可能功能单一化,方便维护修改.Jive论坛系统中其他如帖子的创建和使用,都是按照Forum这个思路而来的.以上我们讨论了如何使用Proxy进行授权机制的访问,Proxy还可以对用户隐藏另外一种称为copy-on-write的优化方式.拷贝一个庞大而复杂的对象是一个开销很大的操作,如果拷贝过程中,没有对原来的对象有所修改,那么这样的拷贝开销就没有必要.用代理延迟这一拷贝过程.比如:我们有一个很大的Collection,具体如hashtable,有很多客户端会并发同时访问它.其中一个特别的客户端要进行连续的数据获取,此时要求其他客户端不能再向hashtable中增加或删除 东东.最直接的解决方案是:使用collection的lock,让这特别的客户端获得这个lock,进行连续的数据获取,然后再释放lock.
public void foFetches(Hashtable ht){
synchronized(ht){
//具体的连续数据获取动作..
} }
但是这一办法可能锁住Collection会很长时间,这段时间,其他客户端就不能访问该Collection了.
第二个解决方案是clone这个Collection,然后让连续的数据获取针对clone出来的那个Collection操作.这个方案前提是,这个Collection是可clone的,而且必须有提供深度clone的方法.Hashtable就提供了对自己的clone方法,但不是Key和value对象的clone,关于Clone含义可以参考专门文章.
public void foFetches(Hashtable ht){
Hashttable newht=(Hashtable)ht.clone();
}问题又来了,由于是针对clone出来的对象操作,如果原来的母体被其他客户端操作修改了, 那么对clone出来的对象操作就没有意义了.最后解决方案:我们可以等其他客户端修改完成后再进行clone,也就是说,这个特别的客户端先通过调用一个叫clone的方法来进行一系列数据获取操作.但实际上没有真正的进行对象拷贝,直至有其他客户端修改了这个对象Collection.使用Proxy实现这个方案.这就是copy-on-write操作.Proxy应用范围很广,现在流行的分布计算方式RMI和Corba等都是Proxy模式的应用.
import java.io.* ;
import java.util.* ;
interface Fruit
{
// 生长
public void grow() ;
// 采摘
public void pick() ;
}
class Apple implements Fruit
{
public void grow()
{
System.out.println("苹果在生长 ") ;
}
public void pick()
{
System.out.println("摘苹果") ;
}
};
class Orange implements Fruit
{
public void grow()
{
System.out.println("橘子在生长 ") ;
}
public void pick()
{
System.out.println("摘橘子") ;
}
};
class Cherry implements Fruit
{
public void grow()
{
System.out.println("樱桃在生长 ") ;
}
public void pick()
{
System.out.println("摘樱桃") ;
}
};class WaterMelon implements Fruit
{
public void grow()
{
System.out.println("西瓜在生长") ;
}
public void pick()
{
System.out.println("摘西瓜") ;
}
};class Banana implements Fruit
{
public void grow()
{
System.out.println("香蕉在生长 ") ;
}
public void pick()
{
System.out.println("摘香蕉") ;
}
};class DD implements Fruit
{
public void grow()
{
System.out.println("DD ") ;
}
public void pick()
{
System.out.println("摘DD") ;
}
};class Factory
{
public static Fruit getFruitInstance(String type)
{
Fruit f = null ;
// 通过Class类完成
try
{
f = (Fruit)Class.forName(type).newInstance() ;
}
catch (Exception e)
{
System.out.println(e) ;
}
return f ;
}
};// 定义一个新类,此类可以从键盘输入数据
class InputData
{
BufferedReader buf = null ;
public InputData()
{
buf = new BufferedReader(new InputStreamReader(System.in)) ;
}
public String getString()
{
String str = null ;
try
{
str = buf.readLine() ;
}
catch (Exception e)
{
}
return str ;
}
};class Init
{
public static Properties getPropertiesInit()
{
Properties p = new Properties() ;
try
{
p.loadFromXML(new FileInputStream("lxh.xml")) ;
}
catch (Exception e)
{
}
return p ;
}
};public class FactoryDemo06
{
public static void main(String args[])
{
Properties p = new Properties() ;
p = Init.getPropertiesInit() ;
System.out.println(p) ;
// 加入一个可以从键盘输入数据的类
System.out.print("输入要使用的子类代码:") ;
String code = new InputData().getString() ;
System.out.println(p.getProperty(code)) ;
Fruit f = Factory.getFruitInstance(p.getProperty(code)) ;
if(f!=null)
{
f.grow() ;
f.pick() ;
}
else
{
System.out.println("没有发现这个类型。") ;
}
}
};
package com.haojia.factory;public interface Factory {
Animal produceAnimal(); Color produceColor();
}class RedDogFactory implements Factory { @Override
public Color produceColor() {
return new Red();
} @Override
public Animal produceAnimal() {
return new Dog();
}}class GreenDogFactory implements Factory { @Override
public Animal produceAnimal() {
return new Dog();
} @Override
public Color produceColor() {
return new Green();
}}class RedCatFactory implements Factory { @Override
public Animal produceAnimal() {
return new Cat();
} @Override
public Color produceColor() {
return new Red();
}}class GreenCatFactory implements Factory { @Override
public Animal produceAnimal() {
return new Cat();
} @Override
public Color produceColor() {
return new Green();
}}
package com.haojia.factory;public abstract class Animal {}class Dog extends Animal {
public Dog() {
System.out.println("dog");
}}class Cat extends Animal {
public Cat() {
System.out.println("cat");
}
}
package com.haojia.factory;public abstract class Color {}class Red extends Color { public Red() {
System.out.println("red");
}
}class Green extends Color { public Green() {
System.out.println("green");
}}
package com.haojia.factory;import java.io.IOException;
import java.util.Properties;public class Client {
private static Properties props = new Properties(); static {
try {
props.load(Thread.currentThread().getContextClassLoader()
.getResourceAsStream(
"com/haojia/factory/factory.properties"));
} catch (IOException e) {
e.printStackTrace();
}
} public static String getFactoryName() {
return "com.haojia.factory." + props.getProperty("Color")
+ props.getProperty("Animal") + "Factory";
} public static void main(String[] args) throws Exception {
Factory factory = (Factory) Class.forName(Client.getFactoryName())
.newInstance();
factory.produceColor();
factory.produceAnimal();
}
}factory.properties文件里的内容:
Color=Green
Animal=Cat