A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
优缺点分析
优点:
(1)最大的好处是易于交换产品系列,由于具体工厂类在一个应用中只需要初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。如Access->SQL   Server
(2)第二大好处是:它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。如客户端只知道使用IUser和IDepartment,至于它是用SQL Server还是Access来实现就不知道了。
缺点:
当需要增加功能时,就需要增加很多类


这讲的理论。。。。真不好理解!有实例的可以交流一下~!

评分

参与人数 1技术分 +1 收起 理由
赵志勇 + 1 赞一个!

查看全部评分

5 个回复

倒序浏览
工厂模式在项目中是常常用到的,有人说只有大项目才会用到,小项目是体会不出来.其实使用设计模式与项目的大小没有实质性的联系.设计模式是经验的总结而不是衡量项目大小的标准.

以开发项目的DAO层为例,在项目中客户的需求是常常变动的,临时更换数据库的需求也是常常发生的,那我们要如何解决跨数据库的功能,这里就要使用到抽象工厂模式了.工厂模式常常用于创建多系列化的对象(如Orale系列,MySql系列)

1.首先定义相关接口(与平常的做法没什么区别)

Java代码
// 角色表DAO接口   
interface IroleDao {   
    void insert();   
  
    void update();   
}   
// 用户表DAO接口   
interface IuserDao {   
    void find();   
  
    void delete();   
}  

// 角色表DAO接口
interface IroleDao {
void insert();

void update();
}
// 用户表DAO接口
interface IuserDao {
void find();

void delete();
} 2.不同的数据库有不同的SQL语句所以实现时必须分数据库来实现

Java代码
// 用户表Oralce数据库DAO   
class OracleuserDao implements IuserDao {   
    public void delete() {   
        System.out.println("Oralce 删除用户表数据");   
    }   
  
    public void find() {   
        System.out.println("Oralce 查询用户表数据");   
    }   
}   
  
// 用户表MySql数据库DAO   
class MySqluserDao implements IuserDao {   
    public void delete() {   
        System.out.println("MySql 删除用户数据");   
    }   
  
    public void find() {   
        System.out.println("MySql 查询用户数据");   
    }   
}   
// 角色表Oracle数据库DAO   
class OracleroleDao implements IroleDao {   
    public void insert() {   
        System.out.println("Oralce 对角色表插入数据");   
    }   
  
    public void update() {   
        System.out.println("Oracle 对角色表更新数据");   
    }   
}   
  
// 角色表MySql数据库DAO   
class MySqlroleDAO implements IroleDao {   
    public void insert() {   
        System.out.println("MySql 对角色表插入数据");   
    }   
  
    public void update() {   
        System.out.println("Mysql 对角色表更新数据");   
    }   
}  

// 用户表Oralce数据库DAO
class OracleuserDao implements IuserDao {
public void delete() {
  System.out.println("Oralce 删除用户表数据");
}

public void find() {
  System.out.println("Oralce 查询用户表数据");
}
}

// 用户表MySql数据库DAO
class MySqluserDao implements IuserDao {
public void delete() {
  System.out.println("MySql 删除用户数据");
}

public void find() {
  System.out.println("MySql 查询用户数据");
}
}
// 角色表Oracle数据库DAO
class OracleroleDao implements IroleDao {
public void insert() {
  System.out.println("Oralce 对角色表插入数据");
}

public void update() {
  System.out.println("Oracle 对角色表更新数据");
}
}

// 角色表MySql数据库DAO
class MySqlroleDAO implements IroleDao {
public void insert() {
  System.out.println("MySql 对角色表插入数据");
}

public void update() {
  System.out.println("Mysql 对角色表更新数据");
}
}
这里增加了一套DAO的实现 (与平时有所不同,如果有10个数据库就要加上10种不同的实现,比较麻烦呀)

3.定义DAO工厂接口与实现(利用java反射机制生产出你需要的DAO如:userDAO,roleDao)

Java代码
// DAO工厂   
abstract class DaoFactory {   
    public static DaoFactory getInstance(String classname) {   
        DaoFactory dao = null;   
        try {   
            dao = (DaoFactory) Class.forName(classname).newInstance();   
        } catch (Exception e) {   
            e.printStackTrace();   
        }   
        return dao;   
    }   
  
    abstract IuserDao getuserdao();   
  
    abstract IroleDao getroledao();   
}   
  
// Oralce工厂   
class OracleFactory extends DaoFactory {   
    public IroleDao getroledao() {   
        return new OracleroleDao();   
    }   
    public IuserDao getuserdao() {   
        return new OracleuserDao();   
    }   
}   
  
// MySql工厂   
class MysqlFactory extends DaoFactory {   
    public IroleDao getroledao() {   
        return new MySqlroleDAO();   
    }   
    public IuserDao getuserdao() {   
        return new MySqluserDao();   
    }   
}  

// DAO工厂
abstract class DaoFactory {
public static DaoFactory getInstance(String classname) {
  DaoFactory dao = null;
  try {
   dao = (DaoFactory) Class.forName(classname).newInstance();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return dao;
}

abstract IuserDao getuserdao();

abstract IroleDao getroledao();
}

// Oralce工厂
class OracleFactory extends DaoFactory {
public IroleDao getroledao() {
  return new OracleroleDao();
}
public IuserDao getuserdao() {
  return new OracleuserDao();
}
}

// MySql工厂
class MysqlFactory extends DaoFactory {
public IroleDao getroledao() {
  return new MySqlroleDAO();
}
public IuserDao getuserdao() {
  return new MySqluserDao();
}
}  

4. 定义配置文件

Java代码
class Config {   
    // Oralce   
    static final String ORALCE = "org.abc.OracleFactory";   
  
    static final String MYSQL = "org.abc.MysqlFactory";   
}  

class Config {
// Oralce
static final String ORALCE = "org.abc.OracleFactory";

static final String MYSQL = "org.abc.MysqlFactory";
}

配置文件可以定义到XML中去(好处:修改配置项之后不需要对JAVA文件进行编译.)

5.测试你的输出的DAO

Java代码
public class Dao {   
    public static void main(String[] args) {   
        DaoFactory.getInstance(Config.ORALCE).getroledao().insert();   
        DaoFactory.getInstance(Config.MYSQL).getroledao().insert();   
    }   
  
}  

public class Dao {
public static void main(String[] args) {
  DaoFactory.getInstance(Config.ORALCE).getroledao().insert();
  DaoFactory.getInstance(Config.MYSQL).getroledao().insert();
}

}  

总结

使用条件:一系列接口有一系列的实现
如上IuserDao、IroleDao等一系列的接口,他们可以有一系列的实现(Oracle方式、MySql方式)

OracleuserDao、OracleroleDao、MySqluserDao、MySqlroleDAO
组成元素(以上面例子)
一系列接口:IuserDao、IroleDao
一系列实现:Oracle系列、MySql系列
系列工厂类:Oracle系列工厂类、MySql系列工厂类(必须继承抽象工厂类)
抽象工厂类:DaoFactory


百度上边的 = =  说实在的抽象工厂模式没认真了解过,应该类似MVC模式吧
回复 使用道具 举报
以前看视屏的时候写过这样一个例子,不知道对你有没有帮助:

这是一个交通工具工厂抽象类:
package Factory;
public abstract class VehicleFactory {
abstract Moveable create();
}

这是一个接口,表示run的方式:
public interface Moveable {
void run();
}

这是一个汽车工厂类,专门生产汽车,实现了交通工具工厂类:
package Factory;
public class CarFactory extends VehicleFactory{
public Moveable create() {
  return new Car();
}
}

这是一个飞机工厂类,专门生产飞机,也实现了交通工具工厂类:
package Factory;
public class PlaneFactory extends VehicleFactory{
public Moveable create() {
  return new Plane();
}
}

这是一个汽车类:
package Factory;
public class Car implements Moveable{
public void run() {
  System.out.println("工厂为您造的汽车,正在行驶中....");
}
}

这是一个飞机类:
package Factory;
public class Plane implements Moveable {
public void run() {
  System.out.println("工厂帮您创造了一架飞机,正在航行中....");
}
}

这是测试类:
package Factory;
public class Test {
public static void main(String[] args) {
  VehicleFactory factory = new CarFactory();
  Moveable m = factory.create();
  m.run();
}
}
当我们使用飞机的工厂初始化交通工具工厂时,就会创建一个飞机对象,就会按照飞机的方式来执行run()方法,
否则就按照汽车的方式来执行run()方法!!







评分

参与人数 1技术分 +1 收起 理由
赵志勇 + 1 赞一个!

查看全部评分

回复 使用道具 举报
宋浩 发表于 2012-6-15 21:03
以前看视屏的时候写过这样一个例子,不知道对你有没有帮助:

这是一个交通工具工厂抽象类:

就是说它省去了创建的过程?。。有没有这个意思?。。。。我觉得这对代码的简洁度也同样有很大作用。。。
回复 使用道具 举报
胡大强 发表于 2012-6-15 21:26
就是说它省去了创建的过程?。。有没有这个意思?。。。。我觉得这对代码的简洁度也同样有很大作用。。。 ...

有一点这个意思,工厂可以帮你创建,但是感觉运用更多的是多态,你传什么工厂就能帮你创建什么工具!!这个代码还是写的简单了一点!!
回复 使用道具 举报
interface AbstractFactory {
public Draw CreateLine();
public Draw CreateDot();
}
//抽象工厂1
class ConcreteFactory1  implements AbstractFactory {
public Draw CreateLine() {
return new Line1();
}
public Draw CreateDot() {
return new Dot1();
}
}
//抽象工厂2
class ConcreteFactory2  implements AbstractFactory {
public Draw CreateLine() {
return new Line2();
}
public Draw CreateDot() {
return new Dot2();
}
}
//产品A抽象类
public abstract class Line implements Draw {
public abstract void drawing();
}
//产品B抽象类
public abstract class Dot implements Draw {
public abstract void drawing();
}
//产品接口
interface Draw {
public void drawing();
}
//产品A1类继承产品A抽象类
public class Line1 extends Line{
public void drawing() {
//画线1
System.out.println("画线1");
}
}
//产品A2类继承产品A抽象类
public class Line2 extends Line{
public void drawing() {
//画线2
System.out.println("画线2");
}
}
//产品B1类继承产品B抽象类
public class Dot1 extends Dot {
public void drawing() {
//画点1
System.out.println("画点1");
}
}
//产品B2类继承产品B抽象类
public class Dot2 extends Dot{
public void drawing() {
//画点2
System.out.println("画点2");
}
}

//客户端测试类
public class test {
public static void main(String args[]) {
AbstractFactory a = new ConcreteFactory1 ();
Draw Line1 = a.CreateLine();
Line1.drawing();
Draw Dot1 = a.CreateDot();
Dot1.drawing();
AbstractFactory aa = new ConcreteFactory2 ();
Draw Line2 = aa.CreateLine();
Line2.drawing();
Draw Dot2 = aa.CreateDot();
Dot2.drawing();
}
}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马