抽象工厂模式

来源:互联网 发布:剑桥战争史 知乎 编辑:程序博客网 时间:2024/05/17 08:43

一、 抽象工厂(Abstract Factory)模式

抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。

为了方便引进抽象工厂模式,引进一个新概念:产品族(Product Family)。所谓产品族,是指位于不同产品等级结构,功能相关联的产品组成的家族。如图:

 

图中一共有四个产品族,分布于三个不同的产品等级结构中。只要指明一个产品所处的产品族以及它所属的等级结构,就可以唯一的确定这个产品。

引进抽象工厂模式

所谓的抽象工厂是指一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象。如果用图来描述的话,简而言之,就是一个工厂可以创建出一个产品族中的所有对象, 如下图:

 

二、 Abstract Factory模式的结构:

 

图中描述的东西用产品族描述如下:

 

三、举例

在本例子中有3个具体工厂AKetchen, BKetchen, CKetchen,分别生产牛奶和汤匙、面包和刀、肉和叉子。牛奶、面包和肉都实现了食物接口。汤匙、刀和叉子都实现了餐具接口。
//抽象工厂的接口定义如下所示;package abstractFactory;public interface KetchenFactory{    public Food getFood();    public TableWare getTableWare();}//抽象餐具的接口定义如下所示:package abstractFactory;public interface TableWare{  public String getTool();}//抽象食物的接口定义如下所示:package abstractFactory;public interface Food{    public String getEatable();}//具体工厂AKetchen的定义如下所示;package abstractFactory;public class AKetchen implements KetchenFactory{    public Food getFood(){       return new Milk();    }    public TableWare getTableWare(){       return new Spoon();    }} //具体餐具(spoon)的定义如下所示:package abstractFactory;public class Spoon implements TableWare{     public String getTool() {       return "spoon";    }}//具体食物(milk)的定义如下所示:package abstractFactory;public class Milk implements Food{    public String getEatable(){       return "milk";    }}//客户端的定义如下:package abstractFactory;public class Client{    public void eat(KetchenFactory k){       System.out.println("A person eat "+k.getFood().getEatable()              +" with "+k.getTableWare().getTool()+"!");    }    public static void main(String[] args){       Client client= new Client();       KetchenFactory kf = new AKetchen();       client.eat(kf);       kf=new BKetchen();       client.eat(kf);       kf= new CKetchen();       client.eat(kf);    }}
例2,,抽象工厂模式与单例模式结合,一般工厂只需要一个实例
//用户表dao接口public interface UserDao {public void find();public void delete();}//用户表mysql数据库daopublic class MysqlUserDao implements UserDao {@Overridepublic void find() {// TODO Auto-generated method stubSystem.out.println("mysql查找用户表数据");}@Overridepublic void delete() {// TODO Auto-generated method stubSystem.out.println("mysql删除用户表数据");}}//用户表oracle数据库daopublic class OracleUserDao implements UserDao {@Overridepublic void find() {// TODO Auto-generated method stubSystem.out.println("oracle查找用户表数据");}@Overridepublic void delete() {// TODO Auto-generated method stubSystem.out.println("oracle删除用户表数据");}}
//角色表DAO接口public interface RoleDao {public void insert();public void update();}//角色表msyql数据库daopublic class MysqlRoleDao implements RoleDao {@Overridepublic void insert() {// TODO Auto-generated method stubSystem.out.println("mysql对角色表插入数据");}@Overridepublic void update() {// TODO Auto-generated method stubSystem.out.println("mysql对角色表更新数据");}}//角色表oracle数据库daopublic class OracleRoleDao implements RoleDao {@Overridepublic void insert() {// TODO Auto-generated method stubSystem.out.println("oracle对角色表插入数据");}@Overridepublic void update() {// TODO Auto-generated method stubSystem.out.println("oracle对角色表更新数据");}}
//Dao工厂public abstract class DaoFactory {private static DaoFactory dao;public synchronized static DaoFactory getInstance(String className){try {if(dao == null){dao = (DaoFactory) Class.forName(className).newInstance();}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return dao;}public abstract UserDao getUserDao();public abstract RoleDao getRoleDao();}//MysqlDao工厂public class MysqlDaoFactory extends DaoFactory {@Overridepublic UserDao getUserDao() {// TODO Auto-generated method stubreturn new MysqlUserDao();}@Overridepublic RoleDao getRoleDao() {// TODO Auto-generated method stubreturn new MysqlRoleDao();}}//OracleDao工厂public class OracleDaoFactory extends DaoFactory {@Overridepublic UserDao getUserDao() {// TODO Auto-generated method stubreturn new OracleUserDao();}@Overridepublic RoleDao getRoleDao() {// TODO Auto-generated method stubreturn new OracleRoleDao();}}
//测试类public class Client {public static void main(String[] args) {Properties config = new Properties();try {config.load(Client.class.getClassLoader().getResourceAsStream("config.properties"));System.out.println(config.getProperty("oracle"));DaoFactory dao1 = DaoFactory.getInstance(config.getProperty("mysql"));dao1.getRoleDao().insert();DaoFactory dao2 = DaoFactory.getInstance(config.getProperty("mysql"));dao2.getUserDao().find();System.out.println(dao1);System.out.println(dao2);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
运行结果如下

四、 "开放-封闭"原则

"开放-封闭"原则要求系统对扩展开放,对修改封闭。通过扩展达到增强其功能的目的。对于涉及到多个产品族与多个产品等级结构的系统,其功能增强包括两方面:

增加产品族:Abstract Factory很好的支持了"开放-封闭"原则。

增加新产品的等级结构:需要修改所有的工厂角色,没有很好支持"开放-封闭"原则。

综合起来,抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,而不能为新的产品等级结构的增加提供这样的方便。


      

0 0