设计模式1、2 - 工厂模式(Factory Pattern)、抽象工厂模式(Abstract Factory Pattern)

设计模式1、2 - 工厂模式(Factory Pattern)、抽象工厂模式(Abstract Factory Pattern)

  • ==需要单独看抽象工厂,以加深抽象工厂理解的话,可以直接跳到2中的图==
  • 1. 工厂模式(Factory Pattern)- 简单工厂、工厂模式
  • 2. 抽象工厂模式(Abstract Factory Pattern)

需要单独看抽象工厂,以加深抽象工厂理解的话,可以直接跳到2中的图

1. 工厂模式(Factory Pattern)- 简单工厂、工厂模式

为什么有new,还需要工厂呢?

先说答案:灵活控制生产过程, 权限、修饰、日志。

开始比划:比如有个人可以开车、开飞机、开轮船上班,那么对于这些车、飞机、轮船对象可能就需要实现一个接口,当想用车上班,就new Car,想用船上班 就new Ship,如下所示:

public class MainTest {
    public static void main(String[] args) {
        TravelTools travelTools = new Car();
        // 对车的权限、日志
        // xxxx
        
        travelTools.goToWork();
		
        
        TravelTools travelTools1 = new Ship();
        // 对船的权限、日志
        // xxxx
        
        travelTools1.goToWork();
    }
}
interface TravelTools{
    void goToWork();
}
class Car implements TravelTools{
    @Override
    public void goToWork() {
        System.out.println("go to work by Car Car Car");
    }
}
class Ship implements TravelTools{
    @Override
    public void goToWork() {
        System.out.println("go to work by Ship Ship Ship");
    }
}

这种情况下,如果想在船或者某个交通工具生产的过程中,做某些权限设定、或者属性等信息做一些日志等,那么每新建一种类型的交通工具,就得修改代码(改注释的那个地方),以完成新类型交通工具的日志支持。

那么这时候,如果new对象的过程,让一个工厂去做,把日志权限的控制也放到工厂里,那么可以不用修改主要的逻辑代码,以适应灵活扩展。

以下,就做了一个==简单工厂==,这样,每当创建对象的时候,就由对应的工厂对他做权限处理,而不侵入main方法的逻辑业务代码,导致反复修改main方法。

public class FactoryPattern {
    // 模拟主要逻辑业务
    public static void main(String[] args) {
        // 简单工厂
        TravelToolsFactory factory = new TravelToolsFactory();
        // 用户输入一个 Car 或者 Ship 放到下面的函数中当参数即可 这里省略 直接用Car
        TravelTools travelTools = factory.createTravelTool("Car");
        travelTools.goToWork();
    }
}

// 简单工厂
class TravelToolsFactory{
    public TravelTools createTravelTool(String TravelToolType){
        if(TravelToolType == "Car")
            return createCar();
        else if(TravelToolType == "Ship")
            return createShip();
        return null;
    }

    private Car createCar(){
        // 做日志 权限
        // xxx
        return new Car();
    }
    private Ship createShip(){
        // 做日志 权限
        // xxx
        return new Ship();
    }
}

但是这样并不是最优的方式,因为很容易发现,当想添加新类型的交通工具时候,就得修改TravelToolsFactory这个类的代码,根据开闭原则,这样当然不是最优,那么,如果把工厂的构建,也交给扩展,相当把工厂作为一个可插拔的模块,就会更加灵活,以如下方式:每当想更换交通工具,只需要编写新的工厂,并改下面第4行的代码,new一个新的工厂,这种方式,就是==工厂模式==。

public class MainTest {
    public static void main(String[] args) {
        // 工厂模式
        AbstractTravelToolsFactory absFactory = new ShipTravelToolsFactory(); // 如果想更换交通工具,只需要编写新的工厂,并改这里创建工厂
        TravelTools travelTools = absFactory.createTravelTools();
        travelTools.goToWork();
    }
}

// 工厂模式 -- 交通工具工厂 -- 这样的好处是若想增加火箭交通工具, 只需要再写火箭的创建工厂,并在里面做相应权限控制即可
abstract class AbstractTravelToolsFactory{
    abstract TravelTools createTravelTools();
}

// 交通工具
interface TravelTools{
    void goToWork();
}


// 交通工具:车
class Car implements TravelTools{
    @Override
    public void goToWork() {
        System.out.println("go to work by Car Car Car");
    }
}
// 车的工厂
class CarTravelToolsFactory extends AbstractTravelToolsFactory{
    @Override
    TravelTools createTravelTools() {
        // 做业务权限控制
        Car car = new Car();
        return car;
    }
}



// 交通工具:船
class Ship implements TravelTools{
    @Override
    public void goToWork() {
        System.out.println("go to work by Ship Ship Ship");
    }
}
// 船的工厂
class ShipTravelToolsFactory extends AbstractTravelToolsFactory{
    @Override
    TravelTools createTravelTools() {
        // 做业务权限控制
        Ship ship = new Ship();
        return ship;
    }
}

所以,工厂模式的主要是目的为了在某个对象的创建过程中,如果想要进行某些权限控制时,可以用该方法,以减少代码的修改,满足开闭原则。

2. 抽象工厂模式(Abstract Factory Pattern)

那么通过1的工厂模式,我们已经相对做的ok了,但是今天来了新需求,说这人上班不但要坐交通工具,还要玩手机或者看报纸, 同时还要喝咖啡或者牛奶!三个一起开搞,相当于对于这人来说,要给他配置一套东西(产品族),出行的,看的,喝的。

那么这时候,我们就需要在工厂模式的基础上,再进行更高层次的抽象,搞一个抽象的工厂,用于生产一套(族)抽象的东西,而具体的工厂继承这个抽象工厂并实现相应的方法,以生成一系列的真实的东西

先屡屡实体,这里面涉及到:交通工具TraveTools(有Car、Ship);看的Reading(有NewsParper、Phone);喝的Drinking(有Milk、Coffee)

那么抽象工厂AbstractFactory 就需要生产三个抽象东西:交通工具TraveTools、看的Reading、喝的Drinking

具体工厂就得自由搭配实际的东西,生产实际的3种东西。如我这里的:

套餐1工厂 MenuOneFactory 生产:Car [ 交通工具 ]、NewsParper [ 看的 ]、Milk [ 喝的 ]

套餐2工厂 MenuTwoFactory 生产:Ship[ 交通工具 ]、Phone[ 看的 ]、Coffee [ 喝的 ]

具体的整个结构如下:看左边抽象工厂的那几个抽象方法,像不像插座? 看右边具体的工厂实现的3个方法像不像插头,刚好通过3个接口联系起来,每当想要添加新的套餐的时候,新建一个套餐工厂,插上去就好了!是不是可扩展性好了许多!

设计模式1、2 - 工厂模式(Factory Pattern)、抽象工厂模式(Abstract Factory Pattern)_第1张图片

具体的代码如下:

public class MainTest {
    public static void main(String[] args) {
        // 这样,如果想重新构建一个套餐(家族), 重新添加一个套餐构建工厂, new一个新的套餐工厂,即可全部修改
//        AbstractFactory factory = new MenuOneFactory();
        MenuTwoFactory factory = new MenuTwoFactory(); // 套餐2工厂
        
        // 就算需要新的套餐,以下部分的代码也不需要改动
        TravelTools travelTools = factory.createTravelTools();
        travelTools.goToWork();
        Reading reading = factory.createReading();
        reading.read();
        Drinking drinking = factory.createDrinking();
        drinking.drink();
    }
}

// 抽象工厂用于生产一些列抽象东西
abstract class AbstractFactory{
    abstract TravelTools createTravelTools();
    abstract Reading createReading();
    abstract Drinking createDrinking();
}

// 套餐1   车、报纸、牛奶   ,具体的工厂,生产一些列具体东西
class MenuOneFactory extends AbstractFactory {
    @Override
    TravelTools createTravelTools() {
        return new Car();
    }

    @Override
    Reading createReading() {
        return new NewsParper();
    }

    @Override
    Drinking createDrinking() {
        return new Milk();
    }
}

//套餐2    船、 手机、 咖啡  ,具体的工厂,生产一些列具体东西
class MenuTwoFactory extends AbstractFactory {
    @Override
    TravelTools createTravelTools() {
        return new Ship();
    }

    @Override
    Reading createReading() {
        return new Phone();
    }

    @Override
    Drinking createDrinking() {
        return new Coffee();
    }
}

// 出行的
interface TravelTools{
    void goToWork();
}
// 看的
interface Reading {
    void read();
}
// 喝的
interface Drinking{
    void drink();
}

class Car implements TravelTools { xxx }

class Ship implements TravelTools { xxx }

class NewsParper implements Reading { xxx }

class Phone implements Reading { xxx }

class Coffee implements Drinking { xxx }

class Milk implements Drinking { xxx }

你可能感兴趣的:(设计模式,设计模式,抽象工厂模式,java)