java动态创建子类实例,动态实例化一个类以及一个类的子类(C++/JAVA)

整理一下理解的几种模式的类的实例化:

Singleton:单态,这个类只能被实例化一次

Factory Method:在Factory子类里,进行,product类的子类的实例化(Simple Factory看为Factory Method模式的一种特例)

Abstract Factory:在Factory子类里,进行,多个“product类的子类”的实例化,一个是product1类的子类,一个是product2类的子类......而且这两个子类是存在关系的

(他们的区别参考:Factory Method模式与Abstract Factory模式区别1,2)

Simple Factory动态实例化一个类,Factory Method和Abstract Factory动态实例化一个类的子类,log4**系列代码有这样的例子,也许他们考虑到还要做完全不同类型的工厂类的管理

1.     log4cplus中Simple Factory和Factory Method的实现方式

product类:

class  Logger----

class Appender----

class ConsoleAppender : public Appender

class FileAppender : public Appender

class RollingFileAppender : publicFileAppender

Factory类:

class  LoggerFactory----

classAppenderFactory : public BaseFactory----

class ConsoleAppenderFactory : publicAppenderFactory

class FileAppenderFactory : publicAppenderFactory

class RollingFileAppenderFactory : publicAppenderFactory

(

class LayoutFactory: public BaseFactory----

class SimpleLayoutFactory : publicLayoutFactory

class TTCCLayoutFactory : publicLayoutFactory

class PatternLayoutFactory : publicLayoutFactory

)

(1)Logger是通过Simple Factory来实现的,LoggerFactory工厂就是实例化一个Logger类

(2)Appender和Layout是通过Factory Method来实现的,这里AppenderFactory和LayoutFactory就是工厂方法的基工厂类(撇开BaseFactory不谈,对工厂方法而言),ConsoleAppenderFactory子工厂类中做的工作就实例化ConsoleAppender类

(3)Logger是巧妙的通过

typedef std::mapLoggerMap;

来管理logger_name和Logger实例的

(4)Appender类和Layout类很巧妙的新建了一个类AppenderFactoryRegistry和LayoutFactoryRegistry来实现的,主要是考虑到和AppenderFactory平行的LayoutFactory还可以扩展其他的工厂类

AppenderFactoryRegistry和LayoutFactoryRegistry作用也是利用std::map来管理appender_name和Appender实例

不管是LoggerFactory还是AppenderFactory,都是通过Factory去维护一个对象名称到对象实例的一个映射关系

2.     log4j中采用的JAVA反射机制

在log4j中上面两种模式JAVA很简单的采用反射机制就可以实现,JAVA反射机制如下:

在运行时,判断任意一个对象所属的类

在运行时,调用任意一个对象的方法

在运行时,判断任意一个类所具有的成员变量和方法

在运行时,构造任意一个类的对象(Class.forName(), newInstance())

instantiateByClassName是在通过反射实例化对象的时候调用,而findAndSubst是在解析配置文件时,判断是否存在指定键值的。

//

已经存在category_factory,可以直接用instantiateByClassName

protected void configureCategoryFactory(Properties props) {

String factoryClassName = OptionConverter.findAndSubst(CATEGORY_FACTORY_KEY,

props);

if(factoryClassName != null) {

LogLog.debug("Setting category factory to ["+factoryClassName+"].");

categoryFactory = (CategoryFactory)

OptionConverter.instantiateByClassName(factoryClassName,

CategoryFactory.class,

categoryFactory);

PropertySetter.setProperties(categoryFactory, props, FACTORY_PREFIX + ".");

}

}

///

public

static

Object instantiateByClassName(String className, Class superClass,

Object defaultValue) {

if(className != null) {

try {

Class classObj = Class.forName(className);

if(!superClass.isAssignableFrom(classObj)) {

LogLog.error("A \""+className+"\" object is not assignable to a \""+

superClass.getName() + "\" variable.");

return defaultValue;

}

return classObj.newInstance();

}

catch (Exception e) {

LogLog.error("Could not instantiate class [" + className + "].", e);

}

}

return defaultValue;

}

//

相当于appender_factory的功能

Appender parseAppender(Properties props, String appenderName) {

Appender appender = registryGet(appenderName);

if((appender != null)) {

LogLog.debug("Appender \"" + appenderName + "\" was already parsed.");

return appender;

}

// Appender was not previously initialized.

String prefix = APPENDER_PREFIX + appenderName;

String layoutPrefix = prefix + ".layout";

appender = (Appender) OptionConverter.instantiateByKey(props, prefix,

org.apache.log4j.Appender.class,

null);

......

Layout layout = (Layout) OptionConverter.instantiateByKey(props,

layoutPrefix,

Layout.class,

null);

///

public

static

Object instantiateByKey(Properties props, String key, Class superClass,

Object defaultValue) {

// Get the value of the property in string form

String className = findAndSubst(key, props);

if(className == null) {

LogLog.error("Could not find value for key " + key);

return defaultValue;

}

// Trim className to avoid trailing spaces that cause problems.

return OptionConverter.instantiateByClassName(className.trim(), superClass,

defaultValue);

}

//

下面google到的两个个例子(1,2)是一种完全不同的处理方式,也是一个写C++的同学推荐的方法

简单工厂类维护一个对象名称到对象实例的映射

工厂方法基类里面有个静态createInstance函数,然后每个子类继承这个createInstance函数,每个子类的createInstance自己实例化自己一个实例,在外面函数调用基类的createInstance,非常简单就实例化一个子类

3.     简单工厂维护name到实例的映射

{

// store instances of pools

private static Mappools =

new HashMap();

// empty constructor

protected SockIOPool() { }

/**

* Factory to create/retrieve new pools given a unique poolName.

*

* @param poolName unique name of the pool

* @return instance of SockIOPool

*/

public static synchronized SockIOPool getInstance( String poolName ) {

if ( pools.containsKey( poolName ) )

return pools.get( poolName );

SockIOPool pool = new SockIOPool();

pools.put( poolName, pool );

return pool;

}

/**

* Single argument version of factory used for back compat.

* Simply creates a pool named "default".

*

* @return instance of SockIOPool

*/

public static SockIOPool getInstance() {

return getInstance( "default" );

}

}

4.     工厂方法模式的智能化实现

#include

#include

#include

class Shape;

typedef Shape*(*FactoryFunction)();

class ShapeFactory

{

public:

static void Register(std::string name,FactoryFunction instanceFunction)

{m_FactoryFunctions[name] =instanceFunction;};

static Shape * getInstance(std::stringname)

{ if(m_FactoryFunctions.count(name))                     returnm_FactoryFunctions[name]();

else       return NULL; }

private:

staticstd::mapm_FactoryFunctions;

};

std::mapShapeFactory::m_FactoryFunctions;

class Shape

{

public:

virtual void  Draw() = 0;

};

class Circle :public Shape

{

public:

void Draw()  { std::cout << "Drawing aCircle......Done" << std::endl; }

static Shape *createInstance() {returnnew Circle;}

};

class Triangle :public Shape

{

public:

void Draw()  { std::cout << "Drawing aTriagnle......Done" << std::endl; }

static Shape *createInstance() {returnnew Triangle;}

};

int main()

{

ShapeFactory::Register("circle",   &  Circle::createInstance);

ShapeFactory::Register("Triangle", &Triangle::createInstance);

Shape * pShape = NULL;

pShape =ShapeFactory::getInstance("circle");

if (NULL == pShape)

{

std::cout << "can'tfind the product in the factory" << std::endl;

delete pShape;

}

else

{

pShape->Draw();

delete pShape;

}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值