总结一下这段时间对于工厂模式的学习理解。
工厂模式总的来说可以简单分为三类(简单工厂模式,工厂方法模式,抽象工厂模式),但是在大话设计模式一书中只列出了后两类,在我们的实际应用当中,简单工厂模式却是很容易使用到的。下面分别来介绍这三类工厂模式。
一、简单工厂模式(也称静态工厂模式)
在介绍之前,先说一下为什么我们要使用工厂模式,在不使用工厂模式的情况下,我们要创建Product一个对象,通常是通过new Product()来实现的,这并没有什么问题,但是在Product类派生出两个子类ProductA和ProductB的情况下,我们要创建一个ProductA和ProductB,则需要new两次,当Product种类越来越多的时候,我们就可以把创建Product类的职责交给一个工厂类来管理。用一个类来管理这些Product的创建。简单工厂模式其实就是其最简单方便的一种实现。
Product可以是基类,也可以是抽象公用接口
public interface Product {
void info();
}
ProductA和ProductB则继承Product
public class ProductA implements Product{
@Override
public void info() {
//print info
System.out.println("this is a productA");
}
public void FunctionPA(){
System.out.println("I can't do something like this");
}
}
public class ProductB implements Product{
@Override
public void info() {
//print info
System.out.println("this is a productB");
}
public void FunctionPB(){
System.out.println("I can do something like this");
}
}
工厂类负责管理对象的创建
public class simmpleFactory {
public static ProductA CreateProductA(){
return new ProductA();
}
public static ProductB CreateProductB(){
return new ProductB();
}
}
简单工厂模式是以静态方法的形式创建对象的,所以也称为静态工厂模式,简单工厂模式虽然实现了对对象创建的管理,但是却不符合开闭原则,因为
如果新增类ProductC,需要对simmpleFactory类进行修改。工厂方法模式则解决了此问题。
二、工厂方法模式
工厂方法模式与简单工厂模式最大的不同是,简单工厂模式只有一个工厂类,而工厂方法模式则实现了统一接口的一些列的工厂类,结构上较简单工厂模式稍微复杂一点。
Product
public interface Product {
void info();
}
ProductA和ProductB
public class ProductA implements Product{
@Override
public void info() {
//print info
System.out.println("this is a productA");
}
public void FunctionPA(){
System.out.println("I can't do something like this");
}
}
public class ProductB implements Product{
@Override
public void info() {
//print info
System.out.println("this is a productB");
}
public void FunctionPB(){
System.out.println("I can do something like this");
}
}
工厂接口
public interface abstractFactory {
Product creatProduct();
}
工厂类
public class ProductAFactory implements abstractFactory{
@Override
public ProductA creatProduct() {
return new ProductA();
}
}
public class ProductBFactory implements abstractFactory {
@Override
public ProductB creatProduct() {
return new ProductB();
}
}
具体调用
ProductA product1;
ProductB product2;
void test(){
product1 = new ProductAFactory().creatProduct();
product2 = new ProductBFactory().creatProduct();
product1.info();
product1.FunctionPA();
product2.info();
product2.FunctionPB();
}
输出:
this is a productA
I can't do something like this
this is a productB
I can do something like this
工厂方法模式与静态工厂模式相比虽然满足了开闭原则,但是结构更为复杂,在比较简单的系统中静态工厂模式的优势更为明显,虽然扩展的时候需要
修改工厂类,但是仅仅只需要增加新扩展的类的实例化函数,修改代码较少。而工厂方法模式在使用的时候需要实例化工厂类,静态工厂模式由于使用
静态方法,所以更加方便。在具体的项目中,到底使用哪一个还是需要视情况而定。
工厂方法模式还衍生出一种通过泛型与反射实现的方法:
Product与ProductA,ProductB同上,
工厂方法如下:
public class ProductFactory{
public static <T extends Product> T creatProduct(Class<T> cls) {
T product = null;
try {
product = (T) Class.forName(cls.getName()).newInstance();
} catch (Exception e) {
}
return product;
}
}
具体调用如下:
ProductA product1;
ProductB product2;
void test(){
product1 = ProductFactory.creatProduct(ProductA.class);
product2 = ProductFactory.creatProduct(ProductB.class);
product1.info();
product1.FunctionPA();
product2.info();
product2.FunctionPB();
}
输出:
this is a productA
I can't do something like this
this is a productB
I can do something like this
利用上述实现的工厂方法模式既符合开闭原则便于扩展,同时避免了创建多个工厂类,使用的时候也不需要实例化工厂类,但其效率相比较低。
三、抽象工厂模式
抽象方法适用于产品等级划分比较复杂的情况,其中涉及“产品族”与“产品等级”的概念。所谓产品族,ProductA与ProductB是不同类型的产品,可称其为不同的产品族,而ProductA与ProductB同时又有劣品(cheap)与优品(expens-
ive)之分,则劣品与优品之间就构成了产品等级。
具体例子如下:
Product,CheapProducA,ExpensiveProducA,CheapProducB,ExpensiveProducB
public interface Product {
void info();
}
public class CheapProductA implements Product {
@Override
public void info() {
//print info
System.out.println("this is a cheap productA");
}
public void FunctionPA(){
System.out.println("only productA can do this");
}
}
public class ExpensiveProductA implements Product{
@Override
public void info() {
//print info
System.out.println("this is a expensive productA");
}
public void FunctionPA(){
System.out.println("only productA can do this");
}
}
public class CheapProductB implements Product {
@Override
public void info() {
//print info
System.out.println("this is a cheap productB");
}
public void FunctionPB(){
System.out.println("only productB can do this");
}
}
public class ExpensiveProductB implements Product {
@Override
public void info() {
//print info
System.out.println("this is a expensive productB");
}
public void FunctionPB(){
System.out.println("only productB can do this");
}
}
抽象工厂:
public interface abstractFactory {
Product creatProductCheap();
Product creatProductExpensive();
}
工厂类:
public class ProductAFactory implements abstractFactory {
@Override
public Product creatProductCheap() {
return new CheapProductA();
}
@Override
public Product creatProductExpensive() {
return new ExpensiveProductA();
}
}
public class ProductBFactory implements abstractFactory {
@Override
public Product creatProductCheap() {
return new CheapProductB();
}
@Override
public Product creatProductExpensive() {
return new ExpensiveProductB();
}
}
具体调用:
Product product1;
Product product2;
Product product3;
Product product4;
abstractFactory productFactory;
void test(){
productFactory = new ProductAFactory();
product1 = productFactory.creatProductCheap();
product2 = productFactory.creatProductExpensive();
productFactory = new ProductBFactory();
product3 = productFactory.creatProductCheap();
product4 = productFactory.creatProductExpensive();
product1.info();
product2.info();
product3.info();
product4.info();
((CheapProductA)product1).FunctionPA();
((ExpensiveProductA)product2).FunctionPA();
((CheapProductB)product3).FunctionPB();
((ExpensiveProductB)product4).FunctionPB();
}<span style="white-space:pre"> </span>
输出结果:
this is a cheap productA
this is a expensive productA
this is a cheap productB
this is a expensive productB
only productA can do this
only productA can do this
only productB can do this
only productB can do this
一开始只在后花园中种蔬菜类的时候可以使用简单工厂模式,由工厂负责生成具体的蔬菜类。
(本文例子中此时Product为蔬菜类,ProductA与ProductB对应不同蔬菜种类)
但是如果后花园要引进水果类的时候简单模式就行不通了,因此需要使用工厂方法模式,将产品类族分开。
(本文例子中此时Product为果蔬类,ProductA与ProductB分别对应水果类与蔬菜类)
但是如果后花园的规模继续扩大到地狱范围的分割时,比如说一个在北京,一个在上海的时候,工厂方法模式就不够用了,因为对两个后花园来说,
每个后花园的植物是要被种在一起的,并且两个后花园用工厂方法模式是无法体现其区别的。
(本文例子中此时Product为果蔬类,ProductA与ProductB分别对应水果类与蔬菜类,假设北京产出的水果与蔬菜味劣品(cheap)(PS:空气不好)
,上海产出的水果与蔬菜味优品(expensive)(其实大城市空气都不太好))