一:什么是工厂方法模式
定义一个创建对象的接口,具体实例的产生由这个接口的子类去决定,也就是所谓的一个类的实例化延迟到子类。
二:工厂方法模式的优点(共性)
1 屏蔽了产品类,客户端不用去关注产品类的实现的变化,他只需要关注产品的接口。因为产品的实例化是由工厂类负责的。比如使用JDBC连接数据库,数据库从DB2切换到Oracle,你只需要关注我要使用哪一个数据库,至于后面的东西,你不会去关注的。
2 良好的扩展性
3 典型的解耦
4 更加符合设计原则:依赖抽象而不是实现(依赖倒置原则),父类能出现的地方,子类就可以出现(里氏替换原则),系统高层模块只需要和抽象联系,而不会和实现联系(迪米特法则)
三:三种工厂方法的比较
1) 简单工厂模式:选择实现类,但是不会延迟到子类来实现,简而言之,就是一个类搞定对象的创建,不会用到抽象
结构图:
示例代码:
package FactoryTemplate.SimpleFactory;
/**
* 产品抽象类
* @author Administrator
*/
public interface Product {
public void getProductMessage();
}
package FactoryTemplate.SimpleFactory;
/**
* 具体的产产品类
* @author Administrator
*/
public class GuitarProduct implements Product {
@Override
public void getProductMessage() {
System.out.println("---Guitars");
}
}
package FactoryTemplate.SimpleFactory;
public class BassProduct implements Product {
@Override
public void getProductMessage() {
System.out.println("---Bass");
}
}
package FactoryTemplate.SimpleFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.logging.Logger;
public class MusicProductFactory {
private static final String GUITAR_TYPE = "guitar";
private static final String BASS_TYPE = "bass";
//Determined to what condition/type
/**
public static Product createMusicProdcuProduct(String type){
Product product = null;
//这种方式写的太死了,我们可以通过配置文件配置来实现扩展
if(GUITAR_TYPE.equals(type)){
product = new GuitarProduct();
}else if(BASS_TYPE.equals(BASS_TYPE)){
product=new BassProduct();
}
return (product != null) ? product : null ;
}*/
public static Product createMusicProdcuProduct(){
//直接读取配置文件来获取需要创建实例的类
Properties properties = new Properties();
InputStream in = null;
try {
in = Product.class.getResourceAsStream("musicProduct.properties");
properties.load(in);
} catch (Exception e) {
Logger.getLogger("配置文件出错");
}finally{
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Product product = null;
try {
product = (Product)Class.forName(properties.getProperty("musicProduct")).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return product;
}
}
package FactoryTemplate.SimpleFactory;
public class Client {
public static void main(String[] args) {
Product product = MusicProductFactory.createMusicProdcuProduct();
product.getProductMessage();
}
}
2) 工厂方法 : 也是选择实现,但是和简单工厂相比较,它是把对象的创建延迟到子类,即实现一个工厂接口。
结构图:
示例代码:
package FactoryTemolate;
/**
* 抽象产品类
* @author Administrator
*
*/
public abstract class Product {
//产品类的公共方法
public void method1(){
//business logic
}
//抽象方法
public abstract void method2();
}
package FactoryTemolate;
/**
* 具体的产品
* @author Administrator
*
*/
public class ConcreateProduct1 extends Product {
@Override
public void method2() {
//business logic
}
}
package FactoryTemolate;
public class ConcreateProduct2 extends Product {
@Override
public void method2() {
//business logic
}
}
package FactoryTemolate;
/**
* 我定义的用于创建对象的接口:即所谓的抽象工厂
* @author Administrator
*/
public interface Creator {
public abstract <T extends Product> T createProduct(Class<T> c);
}
package FactoryTemolate;
/**
* 产品的实例化延迟到创建者子类中实现
* @author Administrator
*
*/
public class ConcreateCreator implements Creator {
@Override
public <T extends Product> T createProduct(Class<T> c) {
Product product = null;
try {
product = (Product)Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return (T)product;
}
}
package FactoryTemolate;
public class Client {
public static void main(String[] args) {
Creator creator = new ConcreateCreator();
creator.createProduct(ConcreateProduct1.class);
creator.createProduct(ConcreateProduct2.class);
}
}
3) 抽象工厂 : 提供一个创建一系列的相关的或者相互依赖的对象的接口。什么意思呢?就是我可以对不同的对象进行组装,然后返回,和 简单工厂和工厂方法相比较而言,后两者只是针对单个产品对象的创建。
抽象工厂更加容易切换产品簇。
结构图:
示例代码:
package FactoryTemolate.AbstractFactory;
/**
* 抽象产品A的接口
* @author Administrator
*
*/
public interface AbstractProductA {
//定义抽象产品A的接口
public void getProductA();
}
package FactoryTemolate.AbstractFactory;
/**
* 抽象产品B的接口
* @author Administrator
*
*/
public interface AbstractProductB {
//定义抽象产品B的接口
public void getProductB();
}
package FactoryTemolate.AbstractFactory;
public class ProductA1 implements AbstractProductA {
@Override
public void getProductA() {
System.out.println("我是具体的产品A1");
}
}
package FactoryTemolate.AbstractFactory;
public class ProductA2 implements AbstractProductA {
@Override
public void getProductA() {
System.out.println("我是具体的产品A2");
}
}
package FactoryTemolate.AbstractFactory;
public class ProductB1 implements AbstractProductB {
@Override
public void getProductB() {
System.out.println("我是具体的产品B1");
}
}
package FactoryTemolate.AbstractFactory;
public class ProductB2 implements AbstractProductB {
@Override
public void getProductB() {
System.out.println("我是具体的产品B2");
}
}
package FactoryTemolate.AbstractFactory;
/**
* 抽象工厂的接口,生命一些创建抽象产品的方法
* @author Administrator
*
*/
public interface AbstractFactory {
/**
* 创建抽象产品A
*/
public AbstractProductA createProductA();
/**
* 创建抽象产品B
*/
public AbstractProductB createProductB();
}
package FactoryTemolate.AbstractFactory;
public class ConcreateFactory1 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
// TODO Auto-generated method stub
return new ProductA1();
}
@Override
public AbstractProductB createProductB() {
// TODO Auto-generated method stub
return new ProductB1();
}
}
package FactoryTemolate.AbstractFactory;
public class ConcreateFactory2 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
// TODO Auto-generated method stub
return new ProductA2();
}
@Override
public AbstractProductB createProductB() {
// TODO Auto-generated method stub
return new ProductB2();
}
}
package FactoryTemolate.AbstractFactory;
public class Client {
public static void main(String[] args) {
//创建抽象工厂对象
AbstractFactory aFactory = new ConcreateFactory1();
//通过抽象工厂获取一系列的对象
aFactory.createProductA();
aFactory.createProductB();
}
}