1、简单工厂模式(静态工厂方法模式)
描述
- 简单工厂的定义:提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类。看下面的例子。
代码
- Fruit接口
package factory;
public interface Fruit {
public void draw();
}
- Apple类
package factory;
public class Apple implements Fruit {
public void draw() {
System.out.println("苹果真香");
}
}
- Orange类
package factory;
public class Orange implements Fruit {
public void draw() {
System.out.println("橘子巨香");
}
}
- FruitFactory工厂类
package factory;
public class Factory {
public static Fruit getPerson(String fruitName){
if(fruitName == null)
return null;
if( fruitName.equalsIgnoreCase("Apple"))
return new Apple();
else if( fruitName.equalsIgnoreCase("Orange"))
return new Orange();
else
return null;
}
}
- 测试类
package factory;
public class Main {
public static void main(String[] args) {
Fruit apple = Factory.getPerson("Apple");
Fruit orange = Factory.getPerson("Orange");
apple.draw();
orange.draw();
}
}
- 结果:
- 优点
1 解耦 :把对象的创建和使用的过程分开
2降低代码重复: 如果创建某个对象的过程都很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。
3 降低维护成本 :由于创建过程都由工厂统一管理,所以发生业务逻辑变化,不需要找到所有需要创建对象B的地方去逐个修正,只需要在工厂里修改即可,降低维护成本。 - 缺点
1 扩展性差(我想增加另一个水果,除了新增一个水果类,还需要修改工厂类方法)
2 不同的产品需要不同额外参数的时候 不支持。
适用场景
其实由定义也大概能推测出其使用场景,首先由于只有一个工厂类,所以工厂类中创建的对象不能太多,否则工厂类的业务逻辑就太复杂了,其次由于工厂类封装了对象的创建过程,所以客户端应该不关心对象的创建。总结一下适用场景:
(1)需要创建的对象较少。
(2)客户端不关心对象的创建过程。
2、工厂方法
描述
- 由于简单工厂模式只适用于固定不变的几个产品,但实际情况确是我们需要动态的增加产品。所以就出现了工厂方法(简单工厂模式的改进版),创建一个工厂接口。如果出现新的水果类,我们只需要增加实现工厂接口的类和实现水果接口的类,不必改变原有工厂的代码。
代码
- 工厂接口
package factory;
public interface IFactory {
public Fruit getFruit(String fruitName);
}
- 工厂实现类
package factory;
public class Factory {
public Fruit getFruit(String fruitName){
if( fruitName == null)
return null;
if( fruitName.equalsIgnoreCase("Apple"))
return new Apple();
else if( fruitName.equalsIgnoreCase("Orange"))
return new Orange();
else
return null;
}
}
- 水果的代码和上面的是一样的。
- 测试类
package factory;
public class Main {
public static void main(String[] args) {
Factory factory = new Factory();
Fruit apple = factory.getFruit("Apple");
apple.draw();
Fruit orange = factory.getFruit("Orange");
orange.draw();
}
}
适用场景
(1)客户端不需要知道它所创建的对象的类。例子中我们不知道每个图片加载器具体叫什么名,只知道创建它的工厂名就完成了床架过程。
(2)客户端可以通过子类来指定创建对应的对象。
以上场景使用于采用工厂方法模式。
3、抽象工厂模式
- 有了工厂方法模式,可以解决很大部分创造类的问题,但还有一个现实中的问题,有一个工厂的话可以创造一系列产品 ,如果工厂方法模式的话就需要创造一系列的工厂来完成这种效果,如何来解决这个问题呢?对于一些系列工厂问题就可以用一个可以系列描述的工厂来表示,每个工厂都有系列的的生产方法,也就是说是生产工厂的工厂。
- 抽象工厂是生产一整套有产品的(至少要生产两个产品),这些产品必须相互是有关系或有依赖的,而工厂方法中的工厂是生产单一产品的工厂。
//抽象工厂类
abstract class Factory{
abstract ProductA create();
abstract ProductB create();
}
//工厂M
class FactoryM{
public ProductA create(){
return new ProductA();
}
public ProductB create(){
return new ProductB();
}
}
//工厂N
class FactoryN{
public ProductA create(){
return new ProductA();
}
public ProductB create(){
return new ProductB();
}
}
//产品父类
abstract class Product{}
//产品子类A
abstract class ProductA extends Product{}
//产品子类B
abstract class ProductB extends Product{}
//系列M产品
class ProductAM extends ProductA{}
class ProductBM extends ProductB{}
//系列N产品
class ProductAN extends ProductA{}
class ProductBN extends ProductB{}
public class App{
public static void main(String[] args){
ProductA p;
Factory f=new FactoryM()
//消费者类中创造A产品
p=f.create();
}
}
适用场景
(1)和工厂方法一样客户端不需要知道它所创建的对象的类。
(2)需要一组对象共同完成某种功能时。并且可能存在多组对象完成不同功能的情况。
(3)系统结构稳定,不会频繁的增加对象。(因为一旦增加就需要修改原有代码,不符合开闭原则)