天天看点

java的简单工厂模式,工厂方法模式,抽象工厂模式

 工厂模式细分下来有三大类:简单工厂、工厂方法、抽象工厂

简单工厂模式

准确的说简单工厂不是一个模式,而是一种编程习惯。

由三种角色组成:

工厂角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。

抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。

具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。

例子如下:

   我们需要造3种不同的车(电车,油车,混动车),用户自行指定需要什么车,就给用户创建什么车的对象。

车的对象接口

public interface Car {
    public void createCar();
}
           

创建车的类型,并实现接口

public class DCar implements Car{
    @Override
    public void createCar() {
        System.out.println("造出电车");
    }
}

public class FCar implements Car{
    @Override
    public void createCar() {
        System.out.println("造出混动车");
    }
}

public class YCar implements Car{

    @Override
    public void createCar() {
        System.out.println("造出油车");
    }
}
           

工厂类

public class CarFactory {
    public Car CreateCar(String CarName){
        Car car=null;
        switch (CarName){
            case "油车":
                car=new YCar();
                break;
            case "电车":
                car=new DCar();
                break;
            case "混动车":
                car=new FCar();
                break;
        }
        return car;
    }
}
           

 测试类

public class TestCar {
    public static void main(String[] args) {
        CarFactory carFactory=new CarFactory();
        Car car=carFactory.CreateCar("混动车");
        car.createCar();
    }
}
           

测试结果

造出混动车
           

优点:

将创建实例的工作与使用实例的工作分开,实现了解耦;

把初始化实例时的工作放到工厂里进行,使代码更容易维护。 更符合面向对象的原则 。

缺点:

工厂类集中了所有实例的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;

违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。

工厂方法模式

作用:将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。

由四种角色组成:

抽象工厂角色:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。

具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。

抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。

具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

例子还是接着我们上面的实例

车的接口

public interface Car {
    public void createCar();
}
           
车的类型,实现接口

      
public class DCar implements Car{
    @Override
    public void createCar() {
        System.out.println("造出电车");
    }
}

public class FCar implements Car{
    @Override
    public void createCar() {
        System.out.println("造出混动车");
    }
}

public class YCar implements Car{

    @Override
    public void createCar() {
        System.out.println("造出油车");
    }
}
           
我们的车类工厂改为接口      
public interface CarFactory {
    public Car createCar();
}
           

 我们创建个个汽车的工厂类来实现接口

public class DCarFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new DCar();
    }
}

public class FCarFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new FCar();
    }
}

public class YCarFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new YCar();
    }
}
           

 测试类

public class TestCar {
    public static void main(String[] args) {
        CarFactory carFactory=new DCarFactory();
        Car car=carFactory.createCar();
        car.createCar();
        CarFactory fixFactory=new FCarFactory();
        Car fcar=fixFactory.createCar();
        fcar.createCar();
    }
}
           

运行结果

造出电车
造出混动车
           

优点:

    符合开-闭原则 符合单一职责原则。

    不使用静态工厂方法,可以形成基于继承的等级结构。

缺点:

    增加了代码量。

    工厂使用太单一。

抽象工厂模式

作用:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

与工厂方法如出一辙,四种角色组成:

抽象工厂角色:这是抽象工厂模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。

具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。

抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。

具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

现在我们先创建每种车的一个抽象接口

public interface DCar {
    void CreateCar();
}

public interface FCar {
    void CreateCar();
}


public interface YCar {
    void CreateCar();
}
           

我们现在分别用奔驰和宝马车这两个产品来实现这三个接口

public class BenzDCar implements DCar{
    @Override
    public void CreateCar() {
        System.out.println("奔驰电车");
    }
}

public class BenzFCar implements FCar{
    @Override
    public void CreateCar() {
        System.out.println("奔驰混动车");
    }
}


public class BenzYCar implements YCar{
    @Override
    public void CreateCar() {
        System.out.println("奔驰油车");
    }
}
           
public class BmwDCar implements DCar{
    @Override
    public void CreateCar() {
        System.out.println("宝马电车");
    }
}

public class BmwFCar implements FCar{
    @Override
    public void CreateCar() {
        System.out.println("宝马混动");
    }
}

public class BmwYCar implements YCar{
    @Override
    public void CreateCar() {
        System.out.println("宝马油车");
    }
}
           

创建两个宝马工厂和比亚迪工厂分别来实现抽象工厂CarFactory

public interface CarFactory {
      DCar CreateDCar();
      YCar CreateYCar();
      FCar CreateFCar();
}
           
public class BenzFactory implements CarFactory{
    @Override
    public DCar CreateDCar() {
        return new BenzDCar();
    }

    @Override
    public YCar CreateYCar() {
        return new BenzYCar();
    }

    @Override
    public FCar CreateFCar() {
        return new BenzFCar();
    }
}
           
public class BmwFactory implements CarFactory{
    @Override
    public DCar CreateDCar() {
        return new BmwDCar();
    }

    @Override
    public YCar CreateYCar() {
        return new BmwYCar();
    }

    @Override
    public FCar CreateFCar() {
        return new BmwFCar();
    }
}
           

测试类

public class TestCar {
    public static void main(String[] args) {
        CarFactory carFactory = new BenzFactory();
        DCar dCar=carFactory.CreateDCar();
        dCar.CreateCar();

        CarFactory carFactory1 = new BmwFactory();
        FCar fCar=carFactory1.CreateFCar();
        fCar.CreateCar();

    }
}
           

测试结果

奔驰电车
宝马混动
           

优点:

增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。

当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。

缺点: 

增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,灵活性低