工厂模式

工厂模式:
实现了创建者和调用者的分离。
详细分类:
简单工厂模式
工厂方法模式
抽象工厂模式

面向对象设计的基本原则:
OCP(开闭原则,Open-Closed Principle):一个软件的实体应当对扩展开放,对修改关闭。
DIP(依赖倒转原则,Dependence Inversion Principle):要针对接口编程,不要针对实现编程。
LoD(迪米特法则,Law of Demeter):只与你直接的朋友通信,而避免和陌生人通信。

核心本质:
实例化对象,用工厂方法代替new操作。
将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。

工厂模式:
简单工厂模式
  用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有代码)
工厂方法模式
  用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂模式
  用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)

不使用简单工厂的情况

Car接口

public interface Car {
    void ruun();
}
View Code

Audi类实现Car接口

public class Audi implements Car {
    @Override
    public void ruun() {
        System.out.println("Audi run...");        
    }
}
View Code

Byd实现Car接口

public class Byd implements Car {
    @Override
    public void ruun() {
        System.out.println("Byd run...");
    }
}
View Code

Client01调用者

public class Client01 {   //调用者
    
    public static void main(String[] args) {
        Car c1 = new Audi();
        Car c2 = new Byd();
        
        c1.run();
        c2.run();
        
    }
}
View Code


简单工厂模式也叫静态工厂模式
要点:
简单工厂模式也叫静态工厂模式,就是工厂类一般是使用静态方法,通过接收的参数(如类名称的字符串)的不同来返回不同的对象实例。
对于增加新产品无能为力!不修改代码的话,是无法扩展的。

SimpleFactory--传入类型名称创建不同对象

public class SimpleFactory {
    public static Car createCar(String type){
        Car c = null;
        if("Audi".equalsIgnoreCase(type)){
            c = new Audi();
        }else if("Byd".equalsIgnoreCase(type)){
            c = new Byd();
        }
        return c;
    }
}
View Code

CarFactory--存在创建不同类型实例的方法

public class CarFactory {
    public static Car createAudi(){
        return new Audi();
    }
    
    public static Car createByd(){
        return new Byd();
    }
}
View Code


工厂方法模式

为了避免简单工厂模式的缺点,不完全满足OCP。
工厂方法模式和简单工厂模式最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类。(工厂方法模式存在多个实现了共同抽象工厂接口的工厂类)。

CarFactory--接口,抽象方法createCar()

public class AudiFactory implements CarFactory {

    @Override
    public Car createCar() {
        return new Audi();
    }

}
View Code

AudiFactory实现CarFactory接口

public class AudiFactory implements CarFactory {

    @Override
    public Car createCar() {
        return new Audi();
    }

}
View Code

BydFactory实现CarFactory接口

public class BydFactory implements CarFactory {

    @Override
    public Car createCar() {
        return new Byd();
    }

}
View Code

Client调用者
使用各自实现CarFactory接口的工厂类,实现创建对象。

public class Client {
    public static void main(String[] args) {
        Car c1 = new AudiFactory().createCar();
        Car c2 = new BydFactory().createCar();
        
        c1.run();
        c2.run();
    }
}
View Code


简单工厂模式和工厂方法模式的比较:
1、结构复杂度
简单工厂模式,只需要一个工厂类,而工厂方法模式的工厂类随着产品类个数的增加而增加。这会使得工厂类越来越多。增加了结构的复杂度。
2、代码复杂度
代码复杂度和结构复杂度一堆矛盾。
简单工厂模式随着产品类别的增加,需要增加很多创建这些类别实例的方法。
而工厂方法模式每一个工厂类中只有一个创建该你类的方法,值完成单一创建实例的任务,代码简介。
3、客户端编写难度
工厂方法模式虽然在工厂类结构中引入了从满足OCP(对扩展开放,对修改关闭)原则,但是在编码过程中需要对很多的工厂类进行实例化。
简单工厂模式,创建工厂类实力的方法是静态方法,在编码过程中无序实例化。
4、管理上的难度
工厂方法模式满足OCP,有非常良好的扩展性。
简单工厂模式亦有良好的扩展性--扩展时仅需修改少量的代码(修改工厂类的代码)就可以满足扩展性的要求。尽管这没有完全满足OCP的原则。
但是对于代码的维护性来说简单工厂较为方便。

抽象工厂模式
用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。


两个产品族的Engine

public interface Engine {
    void run();
    
    void start();
}

class LowEngine implements Engine{

    @Override
    public void run() {
        System.out.println("转的慢...");
    }

    @Override
    public void start() {
        System.out.println("启动慢...");
    }
}

class LuxuryEngine implements  Engine{

    @Override
    public void run() {
        System.out.println("转的快...");
    }

    @Override
    public void start() {
        System.out.println("启动快...");
    }
}
View Code

两个产品组的Tyre

public interface Tyre {
    void revolve();
}

class LowTyre implements Tyre{
    @Override
    public void revolve() {
        System.out.println("磨损的块...");
    }
}

class  LuxyryTyre implements Tyre{
    @Override
    public void revolve() {
        System.out.println("磨损的慢...");        
    }
}
View Code

两个产品族的Seat

public interface Tyre {
    void revolve();
}

class LowTyre implements Tyre{
    @Override
    public void revolve() {
        System.out.println("磨损的块...");
    }
}

class  LuxyryTyre implements Tyre{
    @Override
    public void revolve() {
        System.out.println("磨损的慢...");        
    }
}
View Code

client

public class Client {
    public static void main(String[] args) {
        CarFactory carFactory = new LowCarFactory();
        Engine low_engine = carFactory.createEngine();
        low_engine.start();
        low_engine.run();
    }
}
View Code


工厂模式要点:
简单工厂模式(静态工厂模式)
  虽然某种程度不符合设计原则,但实际使用最多。
工厂方法模式
  不修改已有类的前提下,通过增加新的工厂类实现扩展。
抽象工厂模式
  不可以增加产品,可以增加产品族!

应用场景
  JDK中Calendar的getInstance方法
  JDBC中Connection对象的获取
  Hibernate中SessionFactory创建Session
  spring中IOC容器创建管理bean对象
  XML解析时的DocumentBuilderFactory创建解析器对象
  反射中Class对象的newInstance()


posted @ 2018-12-09 08:57  payn  阅读(160)  评论(0)    收藏  举报