java 抽象工厂模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 抽象工厂模式相关的知识,希望对你有一定的参考价值。

请哪位高手帮我写个简单的抽象工厂模式!最好还有详细一点的注释,感激不尽!

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

以开发项目的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
参考技术A /*
* GUIFactory 示例
* 根据不同的操作系统环境来生成不同的用户界面(GUI)
*/
abstract class GUIFactory
public static GUIFactory getFactory()
int sys = readFromConfigFile("OS_TYPE"); //从配置文件中读取操作系统类型
if (sys == 0)
return new WinFactory(); // Windows
else
return new OSXFactory(); // OS X



public abstract Button createButton();


class WinFactory extends GUIFactory //生成Windows界面的工厂
public Button createButton()
return new WinButton();



class OSXFactory extends GUIFactory //生成OS X界面的工厂
public Button createButton()
return new OSXButton();



abstract class Button
public abstract void paint();


class WinButton extends Button
public void paint()
System.out.println("I'm a WinButton"); //在windows下按钮的表现



class OSXButton extends Button
public void paint()
System.out.println("I'm an OSXButton"); //在OS X下按钮的表现



public class Application
public static void main(String[] args)
GUIFactory factory = GUIFactory.getFactory();
Button button = factory.createButton();
button.paint();

// 输出为:
// "I'm a WinButton"
// 或:
// "I'm an OSXButton"

参考资料:http://en.wikipedia.org/wiki/Abstract_factory_pattern

Java设计模式学习记录-抽象工厂模式

前言

上篇博客介绍了简单工厂模式和工厂方法模式,这次介绍抽象工厂模式,抽象工厂模式和工厂方法模式的区别在于需要创建对象的复杂程度上。

抽象工厂模式

抽象工厂模式是围绕着一个超级工厂创建其他工厂。这个超级工厂被称为其他工厂的工厂,主要是为了解决接口选择问题。

举例说明:

还是继续上篇用户使用手的例子,现在生产手机的工厂发现,不同的手机使用的配件也不相同,需要单独的生产配件。例如iphonX使用的原深感摄像头,以及OLED显示屏,而iphone8使用的全新感光元件组成的摄像头,以及视网膜高清显示屏。这样就需要通过每个配件的配件工厂来提供相应的配件。为了在写代码实例时取名称简单,暂且定义iphoneX使用的是A摄像头和A显示器,而iphone8使用的是B摄像头和B感应器。

代码实例如下:

显示器

/**
 * 显示屏接口
 */
public interface Display {
}
/**
 * iphoneX显示器
 */
public class ADisplay implements Display {

    public ADisplay(){
        System.out.println("##### 制造OLED显示屏 #####");
    }
}
/**
 * iphone8显示器
 */
public class BDisplay implements Display {

    public BDisplay(){
        System.out.println("##### 制造高清视网膜显示器 #####");
    }
}

摄像头

/**
 * 摄像头接口
 */
public interface Camera {
}
/**
 * iphoneX摄像头
 */
public class ACamera implements Camera {

    public ACamera(){
        System.out.println("##### 制造原深感摄像头 #####");
    }
}
/**
 * iphone8摄像头
 */
public class BCamera implements Camera{
    public BCamera(){
        System.out.println("#####  制造搭配全新感光组件的摄像头 #####");
    }
}

工厂类

/**
 * 抽象工厂类
 */
public abstract class AbstractFactory {
    /**
     * 获得显示屏
     * @return
     */
    public abstract Display getDisplay();

    /**
     * 获得摄像头
     * @return
     */
    public abstract Camera getCamera();

}
/**
 * iphoneX配件工厂类
 */
public class IphoneXPartsFactory extends AbstractFactory{
    /**
     * 获得显示屏
     *
     * @return
     */
    @Override
    public Display getDisplay() {
        return new ADisplay();
    }

    /**
     * 获得摄像头
     *
     * @return
     */
    @Override
    public Camera getCamera() {
        return new ACamera();
    }
}
/**
 * iphone8配件工厂类
 */
public class Iphone8PartsFactory extends AbstractFactory{
    /**
     * 获得显示屏
     *
     * @return
     */
    @Override
    public Display getDisplay() {
        return new BDisplay();
    }

    /**
     * 获得摄像头
     *
     * @return
     */
    @Override
    public Camera getCamera() {
        return new BCamera();
    }
}

用户类

/**
 * 用户类
 */
public class Customer {
    
    /**
     * 制造配件
     * @param af
     */
    public static void madeIphone(AbstractFactory af){
        //制造iphone的配件
        af.getDisplay();
        af.getCamera();
    }

    public static void main(String[] args) {

        AbstractFactory  iphonePartsFactory = new IphoneXPartsFactory();
        //制造iPhoneX 的配件
        madeIphone(iphonePartsFactory);

        iphonePartsFactory = new Iphone8PartsFactory();
        //制造iPhone8 的配件
        madeIphone(iphonePartsFactory);

    }
}

运行结果:

##### 制造OLED显示屏 #####
##### 制造原深感摄像头 #####
##### 制造高清视网膜显示器 #####
#####  制造搭配全新感光组件的摄像头 #####

工厂模式也是属于创建模式,它是工厂方法模式的进一步推广。在当一个子系统需要一些产品对象,而这些产品又属于一个以上的产品等级结构,那么为了将消费这些产品对象的责任和创建这些产品对象的责任分割开来,这个时候就可以使用抽象工厂模式了。这样在使用产品的一方不要直接参与产品的创建工作,而只需要向一个公用的工厂接口请求所需要的产品。

工厂模式的关系类图如下:

 

抽象工厂模式中的角色和工厂方法模式中的角色是一样的,这里就不介绍了,可以看上一篇工厂方法模式的角色介绍。

抽象工厂模式的优点和缺点

优点:

分离接口和实现

客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦出来了。

使切换产品族变得容易

因为一个具体的工厂实现代表的是一个产品族,比如上面例子的从iphoneX的配件到iphone8的配件只需要切换一下具体工厂。

缺点:

抽象工厂模式的缺点是不太容易扩展新的产品。如果需要给整个产品族添加一个新的产品,那么久需要修改抽象工厂,这样就会导致修改所有的工厂实现类。

 

 

 

 

以上是关于java 抽象工厂模式的主要内容,如果未能解决你的问题,请参考以下文章

Java设计模式-工厂方法模式和抽象工厂模式

Java描述设计模式(04):抽象工厂模式

Java设计模式学习记录-抽象工厂模式

java设计模式 -------- 创建模式 之 抽象工厂模式

JAVA常用设计模式(抽象工厂模式)

java/android 设计模式学习笔记---抽象工厂模式