工厂设计模式
1. 简单工厂设计模式
定义:定义了一个创建对象的类,由这个类来封装实例化对象的行为。
缺点:类的创建依赖工厂类,如果想要拓展程序,必须对工厂类进行修改,这违背了开闭原则
代码示例
/**
* 数据库接口
*/
public interface DataBase {
//数据更新方法
void update();
//数据删除方法
void delete();
}
// MySQL数据库对数据库接口的实现
public class MySQL implements DataBase{
@Override
public void update() {
System.out.println("MySQL数据库正在更新数据");
}
@Override
public void delete() {
System.out.println("MySQL数据库正在删除数据");
}
}
// Oracle数据库对数据库接口的实现
public class Oracle implements DataBase{
@Override
public void update() {
System.out.println("Oracle数据库正在更新数据");
}
@Override
public void delete() {
System.out.println("Oracle数据库正在删除数据");
}
}
/**
* 此类用于实现对数据库类的动态创建
*/
public class EasyFactory {
// 此方法通过输入字符串从而动态的创建类
public static DataBase createDataBase(String database){
if (database.equals("mysql")){
return new MySQL();
} else if (database.equals("oracle")){
return new Oracle();
} else {
System.out.println("不好意思您输入有误");
return null;
}
}
}
// 测试类
public class EasyTest {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str = input.next();
DataBase dataBase = EasyFactory.createDataBase(str);
dataBase.delete();
dataBase.update();
}
}
2. 工厂方法设计模式
定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法是一个类的实例化延迟到其子类。
问题: 用户创建对应的实例就需要寻找对应的工厂,对用户的操作性增大了,这样的话还不如用户直接new一个对象出来,何必需要这样大费周章。
代码实例
//数据库接口
public interface DataBase {
void update();
void delete();
}
//MySQL数据库实现类
public class MySQL implements DataBase {
@Override
public void update() {
System.out.println("MySQL数据库正在更新数据");
}
@Override
public void delete() {
System.out.println("MySQL数据库正在删除数据");
}
}
//Oracle数据库的实现类
public class Oracle implements DataBase {
@Override
public void update() {
System.out.println("Oracle数据库正在更新数据");
}
@Override
public void delete() {
System.out.println("Oracle数据库正在删除数据");
}
}
// 工厂方法接口
public interface DataBaseFactory {
DataBase creatDataBase();
}
// 生产MySQL数据库的实现类
public class MySQLFactory implements DataBaseFactory{
@Override
public DataBase creatDataBase() {
return new MySQL();
}
}
// 生产Oracle数据库的实现类
public class OracleFactory implements DataBaseFactory{
@Override
public DataBase creatDataBase() {
return new Oracle();
}
}
// 测试类
public class FactoryMethodTest {
public static void main(String[] args) {
MySQL mySQL = (MySQL) new MySQLFactory().creatDataBase();
mySQL.delete();
mySQL.update();
Oracle oracle = (Oracle) new OracleFactory().creatDataBase();
oracle.delete();
oracle.update();
}
}
3. 抽象工厂设计模式
定义: 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。
抽象工厂模式的主要角色。
- 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
- 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
代码实例
// 抽象类的测试
public class AbstractFactoryTest {
public static void main(String[] args) {
DatabaseFactory databaseFactory = DatabaseFactory.chooseDatabaseFactory("mysql");
databaseFactory.createDelete().databaseDelete();
databaseFactory.createUpdate().databaseUpdate();
}
}
// 抽象产品(更新数据)
interface Update{
void databaseUpdate();
}
// 抽象产品(删除数据)
interface Delete{
void databaseDelete();
}
// 具体产品(MySQL工厂中的代表更新的具体产品)
class MySQLUpdate implements Update{
@Override
public void databaseUpdate() {
System.out.println("MySQL数据库更新数据");
}
}
// 具体产品(MySQL工厂中的代表删除的具体产品)
class MySQLDelete implements Delete{
@Override
public void databaseDelete() {
System.out.println("MySQL数据库删除数据");
}
}
// 具体产品(Oracle工厂中的代表更新的具体产品)
class OracleUpdate implements Update{
@Override
public void databaseUpdate() {
System.out.println("Oracle数据库更新数据");
}
}
// 具体产品(Oracle工厂中的代表删除的具体产品)
class OracleDelete implements Delete{
@Override
public void databaseDelete() {
System.out.println("Oracle数据库删除数据");
}
}
// 抽象工厂
abstract class DatabaseFactory{
public abstract Update createUpdate();
public abstract Delete createDelete();
public static DatabaseFactory chooseDatabaseFactory(String database){
DatabaseFactory databaseFactory = null;
if (database.equals("mysql")){
databaseFactory = new MySQLFactory();
} else if (database.equals("Oracle")){
databaseFactory = new OracleFactory();
}
return databaseFactory;
}
}
// MySQL工厂
class MySQLFactory extends DatabaseFactory{
@Override
public Update createUpdate() {
return new MySQLUpdate();
}
@Override
public Delete createDelete() {
return new MySQLDelete();
}
}
// Oracle工厂
class OracleFactory extends DatabaseFactory{
@Override
public Update createUpdate() {
return new OracleUpdate();
}
@Override
public Delete createDelete() {
return new OracleDelete();
}
}
修改一些抽象工厂中可以优化的点
细节:在抽象工厂中可以发现想要创建具体的工厂,使用具体的产品都得对源码进行修改,所以通过配置文件和反射的方式结合起来解决问题。同时在拓展具体产品的时候不需要对之前代码进行修改。
package fun.mengfan.design.factory.intact;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
// 测试
public class AbstractFactoryTest {
public static void main(String[] args) {
DatabaseFactory databaseFactory = DatabaseFactory.chooseDatabaseFactory();
// 通过抽象工厂创建一个具体的工厂然后在具体工厂的基础上去创建基于抽象产品的具体产品
databaseFactory.creatMethod(MethodType.UPDATE).mission();
databaseFactory.creatMethod(MethodType.DELETE).mission();
}
}
// 此接口的作用是为了对抽象产品的拓展
interface Method{
void mission();
}
// 抽象产品
interface Update extends Method{
// void databaseUpdate();
}
// 抽象产品
interface Delete extends Method{
// void databaseDelete();
}
// 具体产品
class MySQLUpdate implements Update{
@Override
public void mission() {
System.out.println("MySQL数据库更新数据");
}
}
// 具体产品
class MySQLDelete implements Delete{
@Override
public void mission() {
System.out.println("MySQL数据库删除数据");
}
}
// 具体产品
class OracleUpdate implements Update{
@Override
public void mission() {
System.out.println("Oracle数据库更新数据");
}
}
// 具体产品
class OracleDelete implements Delete{
@Override
public void mission() {
System.out.println("Oracle数据库删除数据");
}
}
// 抽象工厂
abstract class DatabaseFactory{
// 配置文件
private static Properties prop=new Properties();
public abstract Method creatMethod(MethodType mission);
//读取配置文件的内容
static{
try {
InputStream is = DatabaseFactory.class.getClassLoader().getResourceAsStream("factory.properties");
prop.load(is);
System.out.println(prop.getProperty("factoryName"));
} catch (IOException e) {
e.printStackTrace();
}
}
// 通过反射的方式创建具体工厂
public static DatabaseFactory chooseDatabaseFactory(){
try {
return (DatabaseFactory) Class.forName("fun.mengfan.design.factory.intact." + prop.getProperty("factoryName")).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
// 将产品中的细节提取出来
enum MethodType{
UPDATE,DELETE;
}
// 具体工厂
class MySQLFactory extends DatabaseFactory{
// 通过反射的方式创建具体产品
@Override
public Method creatMethod(MethodType mission) {
String newMission = "MySQL" + mission.toString().substring(0,1) + mission.toString().substring(1).toLowerCase();
try {
return (Method) Class.forName("fun.mengfan.design.factory.intact." + newMission).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
// 具体工厂
class OracleFactory extends DatabaseFactory{
// 通过反射的方式创建具体产品
@Override
public Method creatMethod(MethodType mission) {
String newMission = "Oracle" + mission.toString().substring(0,1) + mission.toString().substring(1).toLowerCase();
try {
return (Method) Class.forName("fun.mengfan.design.factory.intact." + newMission).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}