AbstractFactory模式和可扩展性 假如要实现较好的可扩展性,AbstractFactory模式确实是一件利器。如上面所说,假如要创建的Forum接口的不同实现,而又不想更改代码的话,就需要用到抽象工厂了。再Jive中,AuthorizationFactory类是一个抽象类,用来创建Authorization对象。这是一个抽象工厂,可以通过不同的子类来创建不同的Authorization对象。这个工厂的实现方法是: 在AuthorizationFactory中使用一个private static变量factory,用来引用具体的抽象工厂的实例: private static AuthorizationFactory factory = null; 用一个private static的String,来指明具体的抽象工厂的子类类名: private static String className ="com.coolservlets.forum.database.DbAuthorizationFactory"; 然后是用一个private static的loadAuthorizationFactory方法来给这个factory变量赋值,生成具体的抽象工厂类: private static void loadAuthorizationFactory() { if (factory == null) { synchronized(className) { if (factory == null) { String classNameProp = PropertyManager.getProperty( "AuthorizationFactory.className" ); if (classNameProp != null) { className = classNameProp; } try { Class c = Class.forName(className); factory = (AuthorizationFactory)c.newInstance(); } catch (Exception e) { System.err.println("Exception loading class: " + e); e.printStackTrace(); } } } } } 在static的getAuthorization方法返回一个Authorization的过程中,先初始化工厂类factory变量,然后用factory的createAuthorization方法来创建: public static Authorization getAuthorization(String username, String passWord) throws UnauthorizedException { loadAuthorizationFactory(); return factory.createAuthorization(username, password); } 不同的子类有不同的createAuthorization方法的实现。比如在DbAuthorizationFactory这个AuthorizationFactory的数据库实现子类中,createAuthorization方法是这样实现的: public Authorization createAuthorization(String username, String password) throws UnauthorizedException { if (username == null password == null) { throw new UnauthorizedException(); } password = StringUtils.hash(password); int userID = 0; Connection con = null; PreparedStatement pstmt = null; try { con = DbConnectionManager.getConnection(); pstmt = con.prepareStatement(AUTHORIZE); pstmt.setString(1, username); pstmt.setString(2, password); ResultSet rs = pstmt.executeQuery(); if (!rs.next()) { throw new UnauthorizedException(); } userID = rs.getInt(1); } catch( SQLException sqle ) { System.err.println("Exception in DbAuthorizationFactory:" + sqle); sqle.printStackTrace(); throw new UnauthorizedException(); } finally { try { pstmt.close(); } catch (Exception e) { e.printStackTrace(); } try { con.close(); } catch (Exception e) { e.printStackTrace(); } } return new DbAuthorization(userID); } 在这个类中,可以看到抽象类和具体的子类之间的关系,它们是如何协作的,又是如何划分抽象方法和非抽象方法的,这都是值得注重的地方。一般的,抽象方法需要子类来实现,而抽象类中的非抽象方法应该所有子类所能够共享的,或者可是说,是定义在抽象方法之上的较高层的方法。这确实是一个抽象工厂的好例子!虽然实现的方法已经和GOF中给出的实现相差较远了,但思想没变,这儿的实现,也确实是要巧妙的些。 还有就是静态方法的使用,使得这个类看起来有些Singleton的意味。这使得对于AbstractFactory的创建变得简单。 在AuthorizationFactory中定义的其它方法,涉及到具体的如何创建Authorization,都是作为abstract方法出现,具体实现留给子类来完成。 这样,在需要生成一个Authorization的时候,只需要调用AuthorizationFactory的静态方法getAuthorization就可以了,由子类实现了具体的细节。 其它的,如同上面讲到的,在创建Forum的时候用的ForumFactory,具有同上面一样的实现,这就是模式之所以称为模式的所在了。
|