从耦合关系谈起
耦合关系直接决定着软件面对变化时的行为
- 模块与模块之间的紧耦合使的软件面对变化时,相关的模块都要随之更改。
- 模块与模块之间的松耦合使的软件面对变化时,一些模块更容易被替代或者更改,但其他模块保持不变。
软件的对象经常要发生巨大的变化,但它却拥有比较稳定的接口
引入
我们继续来说”new”的问题,我们在简单工厂模式中,将实例化对象的工作推迟到了专门负责创建对象的工厂类中,这样,在我们事先预知的情况下,可以根据我们的需要动态创建产品类。但是,我们的预知是有限的,客户的变化可能是无限的。所以,就出现了问题,一旦客户的变化超越了我们的预知,我们就必须修改我们的源代码了。这是设计模式所不允许的,怎么办呢?工厂方法模式正是解决此类问题的。 问题:具体工厂类的创建工作不能满足我们的要求了,创建的工作变化了 解决思路:哪里变化,封装哪里。把具体工厂封装起来。
定义
工厂方法模式又称为工厂模式,在工厂方法模式中,父类负责定义创建对象的公共接口,而子类则负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成,即由子类来决定究竟应该实例化(创建)哪一个类。 工厂方式法模式(Factory Method),定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到子类。
意图(Intent)
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。
结构(Structure)
-
抽象产品类(Product):定义产品的接口
-
具体产品类(ConcreteProduct) :实现接口Product的具体产品类
-
抽象工厂类(Creator) :声明工厂方法(FactoryMethod),返回一个产品
-
真实的工厂(ConcreteCreator):实现FactoryMethod工厂方法,由客户调用,返回一个产品的实例
例子
据说清朝有个皇帝穿衣非常的奢侈,每种衣服(具体产品类)由一宫女(具体工厂类)专门负责,这样一来,每增加一种衣服(具体产品类),就要多出一个宫女(具体工厂类),但是他们各负其责,互不影响。皇帝之所以这样做,是因为针对穿衣服这件事来说,可扩展性是非常强的。
实例代码
抽象产品类:
public abstract class Procuct {
//产品类的公共方法
public void method1() {}
//抽象方法
public abstract void method2();
}
具体产品类:
public class ConcreteProduct1 extends Product {
public void method2(){}
}
public class ConcreteProduct2 extends Product {
public void method2(){}
}
抽象工厂类:
public abstract class Creator {
/*
* 创建一个产品对象,其输入参数类型可以自行设置
* 通常为String、Enum、Class等,也可以为空
*/
public abstract <T extends Product> T createProduct(Class<T> c);
}
具体工厂类:
public class ConcreteCreator {
public <T extends Product> T createProduct(Class<T> c) {
Product product = null;
try {
product = (Product)Class.forName(c.getName()).newInstance();
} catch (Exception e) {
//异常处理
}
return (T)product;
}
}
场景类:
public class Client {
public static void main(String[] args) {
Creator = new ConcreteCreator();
Product product = creator.createProduct(ConcreteProduct1.class);
/*
*继续业务处理
*/
}
}