1.工厂方法与2.抽象工厂详解

下面是一个典型的工厂方法模式:

package com;

import java.util.Properties;

/**
* 动物接口,所有的具体动物类均需要继承此接口
* @author abing
*
*/
interface Animal {
void eat();

void sleep();

}
/**
* 动物子类老虎
* @author abing
*
*/
class Tiger implements Animal {

@Override
public void eat() {
System.out.println("老虎要吃饭...");

}

@Override
public void sleep() {
System.out.println("老虎要睡觉...");

}

}
/**
* 动物子类狼
* @author abing
*
*/
class Walf implements Animal {

@Override
public void eat() {
System.out.println("狼要吃饭...");

}

@Override
public void sleep() {
System.out.println("狼要睡觉...");

}

}

/**
* 工厂方法类
* @author abing
*
*/
class AnimalFactory {
/**
* 根具传入参数创建相应的子类
* @param type
* @return
* @throws Exception
*/
public Animal createAnimal(String type) throws Exception {
Animal animal = (Animal) Class.forName(type).newInstance();//创建动物子类,用反射的方式避免此处代码的修改
return animal;
}

}

/**
* 测试类
* @author abing
*
*/
public class FactoryMethod {
static Properties properties = new Properties();
/**
* 这部分可以写在配置文件里面,每当新扩展一个子类,只用修改配置文件即可
*/
static {
properties.setProperty("t", "com.Tiger");
properties.setProperty("w", "com.Walf");
}

public static void main(String[] args) throws Exception {
String type = "w";
AnimalFactory animalFactory = new AnimalFactory();
Animal animal = animalFactory.createAnimal(properties.getProperty(type));
animal.eat();
animal.sleep();
}

}



在此基础上,假如系统中又要创建植物系列对象,则实现抽象工厂模式如下:

package com.koubei.demo2;

import java.util.Properties;

/**
* 动物接口,所有的具体动物类均需要继承此接口
* @author abing
*
*/
interface Animal {
void eat();

void sleep();

}
/**
* 动物子类老虎
* @author abing
*
*/
class Tiger implements Animal {

@Override
public void eat() {
System.out.println("老虎要吃饭...");

}

@Override
public void sleep() {
System.out.println("老虎要睡觉...");

}

}
/**
* 动物子类狼
* @author abing
*
*/
class Walf implements Animal {

@Override
public void eat() {
System.out.println("狼要吃饭...");

}

@Override
public void sleep() {
System.out.println("狼要睡觉...");

}

}

/**
* 植物接口,所有的具体植物类均需要继承此接口
* @author abing
*
*/
interface Plant {
/**
* 植物生长
*/
void grow();
/**
* 植物开花
*/
void flower();

}

class SunFlower implements Plant{

@Override
public void flower() {
System.out.println("向日葵要开花...");

}

@Override
public void grow() {
System.out.println("向日葵要生长...");

}


}
class Pumpkin implements Plant{

@Override
public void flower() {
System.out.println("南瓜要开花...");

}

@Override
public void grow() {
System.out.println("南瓜要生长...");

}


}


/**
* 动物工厂方法类
* @author abing
*
*/
class AnimalFactory extends AbstractFactory{
/**
* 根具传入参数创建相应的动物子类
* @param type
* @return
* @throws Exception
*/
public Animal createAnimal(String type) throws Exception {
Animal animal = (Animal) Class.forName(type).newInstance();//创建动物子类,用反射的方式避免此处代码的修改
return animal;
}

@Override
Plant createPlant(String type) throws Exception {
// TODO Auto-generated method stub
return null;
}

}

/**
* 植物工厂方法类
* @author abing
*
*/
class PlantFactory extends AbstractFactory {
/**
* 根具传入参数创建相应的植物子类
* @param type
* @return
* @throws Exception
*/
public Plant createPlant(String type) throws Exception {
Plant plant = (Plant) Class.forName(type).newInstance();//创建动物子类,用反射的方式避免此处代码的修改
return plant;
}

@Override
Animal createAnimal(String type) throws Exception {
// TODO Auto-generated method stub
return null;
}

}

abstract class AbstractFactory {

/**
* 生成相应的实体工厂
* @param factorytype
* @return
* @throws Exception
*/
public static AbstractFactory getConcreteFactory(String factorytype) throws Exception
{
AbstractFactory factory=(AbstractFactory)Class.forName(factorytype).newInstance();
return factory;
}


/**
* 根具传入参数创建相应的动物子类
* @param type
* @return
* @throws Exception
*/
abstract Animal createAnimal(String type)throws Exception;
/**
* 根具传入参数创建相应的植物子类
* @param type
* @return
* @throws Exception
*/
abstract Plant createPlant(String type)throws Exception;

}

/**
* 测试类
* @author abing
*
*/
public class AbstractFactoryTest{
static Properties properties = new Properties();
/**
* 这部分可以写在配置文件里面,每当新扩展一个子类,只用修改配置文件即可
*/
static {
//------------加入植物动物相关子类到配置中-----------
properties.setProperty("t", "com.Tiger");
properties.setProperty("w", "com.Walf");
//------------加入植物相关子类到配置中-----------
properties.setProperty("s", "com.SunFlower");
properties.setProperty("p", "com.Pumpkin");
}
public static void main(String[] args) throws Exception {
String factorytype = "com.PlantFactory";//具体工厂代号,这个也应该放在配置中
String concretetype="s";//具体子类代号
AbstractFactory factory=AbstractFactory.getConcreteFactory(factorytype);//获得具体工厂-PlantFactory
Plant plant= factory.createPlant(properties.getProperty(concretetype));//通过工厂生产实际产品-Sum
plant.grow();
plant.flower();
}
}


JDK中体现:Collection.iterator方法

但是上面这种情况下,植物系列与动物系列的行为不是一样的,到底适合用抽象工厂模式吗?
----------------------------------------------------------
而下面一种方式,应该是最适合于使用抽象工厂模式的。
解决跨数据库的功能,用到抽象工厂模式.用于创建多系列化的对象(如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





JDK中体现:
(1)java.sql包
(2)UIManager(swing外观)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值