设计模式之工厂模式

设计模式

设计模式代表了最佳的实践,作为一个初入编程界的菜鸟,你可以不懂设计模式,但是作为一个开发经验3+的码农,设计模式就显得很重要了。

设计模式共有23种,分为三大类:创建型模式、结构型模式和行为型模式。

今天简单聊下创建型模式中的工厂模式与抽象工厂模式。

工厂模式

工厂模式是Java中最常用的设计模式之一,属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,不直接创建一个对象,而是使用工厂来创建对象(使用一个共同的interface来指向该对象),避免将创建逻辑暴露给客户端。

实现:

创建一个Cup接口和它的实现类,然后定义一个CupFactory工厂类。CupFactory工厂类中通过不同的标识来判断创建哪种类型的Cup对象。

在这里插入图片描述

①创建Cup接口:

public interface Cup {
    void color();
}

②创建Cup接口的实现:

@Slf4j
public class RedCup implements Cup{
    @Override
    public void color() {
        log.info("my color is red");
    }
}
@Slf4j
public class WhiteCup implements Cup{
    @Override
    public void color() {
        log.info("my color is white");
    }
}
@Slf4j
public class YellowCup implements Cup{
    @Override
    public void color() {
        log.info("my color is yellow");
    }
}

③创建工厂类:

public class CupFactory {
    // 根据cup类型获取cup对象
    public Cup getCup(String cupType) {
        if (null == cupType) {
            return null;
        }
        Cup cup = null;
        switch (cupType) {
            case "white":
                cup = new WhiteCup();
                break;
            case "yellow":
                cup = new YellowCup();
                break;
            case "red":
            default:
                cup = new RedCup();
                break;
        }
        return cup;
    }
}

④使用工厂创建Cup对象:

通过工厂来获取具体的对象,不需要知道对象的创建逻辑。

public class Demo {
    public static void main(String[] args) {
        // 创建一个cup 工厂
        CupFactory factory = new CupFactory();

        // 从工厂中获取redCup对象
        Cup redCup = factory.getCup("red");
        redCup.color();

        // 从工厂中获取whiteCup对象
        Cup whiteCup = factory.getCup("white");
        whiteCup.color();

        // 从工厂中获取yellowCup对象
        Cup yellowCup = factory.getCup("yellow");
        yellowCup.color();
    }
}

日志打印如下:

INFO []2023-03-12 21:42:58.428[org.im.designpattern.RedCup][15][main][INFO]-my color is red
INFO []2023-03-12 21:42:58.433[org.im.designpattern.WhiteCup][15][main][INFO]-my color is white
INFO []2023-03-12 21:42:58.433[org.im.designpattern.YellowCup][15][main][INFO]-my color is yellow

工厂模式适用于不同条件下创建不同实例时。

优点:

  1. 调用者只需要知道具体的对象类型即可创建对象。
  2. 调用者不需要知道对象的具体创建逻辑。
  3. 可扩展性好,在增加一种对象时,只需要扩展工厂类即可。

不足:

​ 每增加一种对象时,就需要增加一个具体实现类和扩展工厂类,使得系统中的类的数量成倍增加,增加了系统的复杂性,同时违背了开闭原则。

抽象工厂模式

抽象工厂模式中通过一个超级工厂,创建其他工厂,该超级工厂被称为工厂的工厂。

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

实现:

创建Cup和Vehicle两个接口,以及实现两个接口的实现类。然后创建抽象工厂AbstractFactory,以及两个继承抽象工厂的工厂类CupFactory和VehicleFactory,分别用于创建Cup和Vehicle对象。

在这里插入图片描述

① 创建Cup和Vehicle两个接口以及其实现类:

public interface Cup {
    void color();
}

@Slf4j
public class RedCup implements Cup{
    @Override
    public void color() {
        log.info("my color is red");
    }
}

@Slf4j
public class WhiteCup implements Cup{
    @Override
    public void color() {
        log.info("my color is white");
    }
}

@Slf4j
public class YellowCup implements Cup{
    @Override
    public void color() {
        log.info("my color is yellow");
    }
}
public interface Vehicle {
    void run();
}

@Slf4j
public class Car implements Vehicle{
    @Override
    public void run() {
        log.info("car run");
    }
}

@Slf4j
public class Train implements Vehicle{
    @Override
    public void run() {
        log.info("train run");
    }
}

@Slf4j
public class Bus implements Vehicle{
    @Override
    public void run() {
        log.info("bus run");
    }
}

②创建抽象工厂类以及工厂类:

public abstract class AbstractFactory {
    // 创建Cup工厂
    abstract Cup getCup(String cupType);
    // 创建vehicle工厂
    abstract Vehicle getVehicle(String vehicleType);
}

public class CupFactory extends AbstractFactory{
    @Override
    public Cup getCup(String cupType) {
        if (null == cupType) {
            return null;
        }
        Cup cup = null;
        switch (cupType) {
            case "white":
                cup = new WhiteCup();
                break;
            case "yellow":
                cup = new YellowCup();
                break;
            case "red":
            default:
                cup = new RedCup();
                break;
        }
        return cup;
    }

    @Override
    Vehicle getVehicle(String vehicle) {
        return null;
    }
}



public class VehicleFactory extends AbstractFactory{
    @Override
    public Vehicle getVehicle(String vehicleType) {
        if (null == vehicleType) {
            return null;
        }
        Vehicle vehicle = null;
        switch (vehicleType) {
            case "car":
                vehicle = new Car();
                break;
            case "train":
                vehicle = new Train();
                break;
            case "bus":
            default:
                vehicle = new Bus();
                break;
        }
        return vehicle;
    }

    @Override
    public Cup getCup(String cupType) {
        return null;
    }
}

③创建工厂生成器类,通过传递工厂类型,创建不同的工厂:

public class FactoryProducer {
    // 根据 工厂类型,创建对应的工厂
    public static AbstractFactory getFactory(String factoryType) {
        if ("cup".equals(factoryType)) {
            return new CupFactory();
        } else if ("vehicle".equals(factoryType)) {
            return new VehicleFactory();
        }
        return null;
    }
}

④Demo中使用抽象工厂来创建工厂,以及工厂来创建具体对象:

public class Demo {
    public static void main(String[] args) {
        // 通过工厂生成器,根据工厂类型cup创建 cup 工厂
        AbstractFactory cupFactory = FactoryProducer.getFactory("cup");

        // 从工厂中获取redCup对象
        Cup redCup = cupFactory.getCup("red");
        redCup.color();

        // 从工厂中获取whiteCup对象
        Cup whiteCup = cupFactory.getCup("white");
        whiteCup.color();

        // 从工厂中获取yellowCup对象
        Cup yellowCup = cupFactory.getCup("yellow");
        yellowCup.color();

        // 通过工厂生成器,根据工厂类型vehicle创建 vehicle 工厂
        AbstractFactory vehicleFactory = FactoryProducer.getFactory("vehicle");
        // 从工厂中获取car对象
        Vehicle car = vehicleFactory.getVehicle("car");
        car.run();

        // 从工厂中获取train对象
        Vehicle trainFactory = vehicleFactory.getVehicle("train");
        trainFactory.run();

        // 从工厂中获取bus对象
        Vehicle busFactory = vehicleFactory.getVehicle("bus");
        busFactory.run();
    }
}

运行Demo,打印日志如下:

INFO []2023-03-13 21:31:59.111[org.im.designpattern.RedCup][15][main][INFO]-my color is red
INFO []2023-03-13 21:31:59.119[org.im.designpattern.WhiteCup][15][main][INFO]-my color is white
INFO []2023-03-13 21:31:59.121[org.im.designpattern.YellowCup][15][main][INFO]-my color is yellow
INFO []2023-03-13 21:31:59.129[org.im.designpattern.Car][15][main][INFO]-car run
INFO []2023-03-13 21:31:59.135[org.im.designpattern.Train][15][main][INFO]-train run
INFO []2023-03-13 21:31:59.142[org.im.designpattern.Bus][15][main][INFO]-bus run

抽象工厂模式适用于系统的产品有多个产品族,而系统只消费某一族的产品。

比如:1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。

优点:

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

不足:

​ 产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值