前言(简单工厂模式)
在了解工厂方法模式之前,我们先看一个简单工厂例子
简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
1、定义一个接口interface Car,里面有个show()方法 2、有两个实现类Benz(奔驰)和BMW(宝马),对show()方法进行具体重写 3、定义一个简单工厂,根据用户输入的参数得到对应的对象
public class SimpleFactoryPattern {
public static void main(String[] args) {
Car car = SimpleFactory.getCar("宝马");
car.show();
}
}
interface Car{
public void show();
}
class Benz implements Car{
@Override
public void show() {
System.out.println("我是一辆奔驰!");
}
}
class BMW implements Car{
@Override
public void show() {
System.out.println("我是一辆宝马!");
}
}
class SimpleFactory {
public static Car getCar(String type){
if (type.equals("奔驰")){
return new Benz();
}else if (type.equals("宝马")){
return new BMW();
}else {
System.out.println("所获得的产品不存在");
}
return null;
}
}
输出结果:我是一辆宝马!
代码不难看懂,那么这种利用工厂创建实例对象和普通的new语句调用类的构造方法创建对象有什么好处呢?
- 封装创建自身实例的细节,并且控制自身实例的数目。客户在使用的时候不需要履行创建产品的义务,可以很方便的创建
- 解耦合,把对象创建和使用分开
- 降低代码重复,如果创建某个对象的过程都很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。
- 降低维护成本:由于创建过程都由工厂统一管理,所以发生业务逻辑变化,不需要找到所有需要创建某个对象的地方去逐个修正,只需要在工厂里修改即可,降低维护成本。
大概了解了简单工厂模式的设计和使用工厂的好处后,让我们来看看今天的主题----工厂方法模式
一、工厂方法模式定义
简单工厂模式和工厂方法模式之间有什么区别呢? 重点说“开闭原则”
开闭原则:在面向对象编程领域中,开闭原则规定“软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”,这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。
比如说那个简单工厂的例子,如果我们要再加一个产品----奥迪,那么就要在工厂里多加上一个if else判断奥迪对象的创建,这就修改了类。如果以后还要再进一步增加产品,就又要对类进行不断的修改,还要对检查引用该方法的类能否正常运行,这样后期的维护就会变得非常麻烦。
既然工厂方法模式可以满足“开闭原则”,那么先来看看工厂模式的定义。
“工厂方法模式”是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。它定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使得一个类的实例化延迟到子类,
二、模式结构(案例)
1、抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。 比如说我定义一个interface接口作为抽象工厂,对使用者开放创建对象的方法
interface ApplicationFactory {
public Car1 createProduct();
}
2、具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。 我定义了两个具体工厂,实现了工厂接口方法,一个工厂用来创建奔驰车对象,另一工厂用来创建宝马车对象。
class createBenz1 implements ApplicationFactory {
@Override
public Car1 createProduct() {
return new Benz1();
}
}
class createBWM1 implements ApplicationFactory {
@Override
public Car1 createProduct() {
return new BWM1();
}
}
3、抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。 写一个抽象产品接口,定义了一个用来展示产品的方法show()
interface Car1 {
public void show();
}
4、具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。 现在就是对产品进行具体描述,根据业务写对应的内容
class Benz1 implements Car1 {
public void show() {
System.out.println("奔驰车产品展示!");
}
}
class BWM1 implements Car1 {
public void show() {
System.out.println("宝马车产品展示!");
}
}
测试类
public class FactoryMethodPattern {
public static void main(String[] args) {
ApplicationFactory factory = new createBenz1();
Car1 product = factory.createProduct();
product.show();
}
}
输出结果:奔驰车产品展示!
我们测试的时候就会发现,使用者同样只需要在使用的时候调用对应的工厂拿到想要的产品对象即可,不需要知道对象的创建是如何实现的,这里体现工厂模式它很好地封装了细节,专注业自身业务。
对于“开闭原则”:如果需要增加产品,简单工厂模式是需要对工厂类进行修改的,而工厂方法模式则是对工厂类进行增加即可,即符合开闭原则。
三、应用场景与优点
应用场景: 1、当你不知道该使用对象的确切类型的时候 2、当你希望为库或框架提供扩展其内部组件的方法时
优点: 1、将具体产品和创建者解耦 2、复合单一职责原则 3、复合开闭原则
四、总结
- 工厂模式中,
“开闭原则“ 要求允许新产品加入系统时,无需对业务类进行修改。但简单工厂模式 需要修改工厂类,而工厂方法模式 不需要修改,只需添加工厂类。前者不符合开闭原则,后者符合。 工厂方法模式 它定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使得一个类的实例化延迟到子类,工厂方法模式 的设计有着封装创建自身实例的细节 ,解耦合 ,降低代码重复 ,有利于维护 等特点
参考链接: http://c.biancheng.net/view/1348.html
|