六大常用设计模式:二、工厂模式

2.1、介绍

工厂模式的核心本质:

  • 实例化对象不使用 new 创建,用工厂方法代替;
  • 将选择实现类、创建对象统一管理和控制,从而使调用者跟实现类解耦。

核心思想就是实现创建者和调用者的分离

详细分类:

  • 简单工厂模式(用来生产同一等级结构中的任意产品。如果增加新产品,需要覆盖已有代码。该模式中只有一个工厂,又称为静态工厂模式)
  • 工厂方法模式(用来生产同一等级结构中的固定产品。可以增加任意产品。该模式中有多个工厂,并且实现了同一个接口。在新增产品的时候,没有动原来的代码,是新建了类)
  • 抽象工厂模式(围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂)

这种类型的设计模式属于创建型模式。

2.2、简单工厂模式

以消费者买车为例,使用简单工厂模式,在控制台实现输出“买到五菱车!”和“买到宝马车!”。

先创建接口:Car ,里面有方法 name()

public interface Car {
    
    
    void name();
}

创建实现类 Wuling 实现接口 Car

public class Wuling implements Car {
    
    
    @Override
    public void name() {
    
    
        System.out.println("买到五菱车!");
    }
}

创建实现类 Baoma ,实现接口 Car

public class Baoma implements Car {
    
    
    @Override
    public void name() {
    
    
        System.out.println("买到宝马车!");
    }
}

重点来了,创建车工厂类 CarFactory ,由车工厂实例化对象:

public class CarFactory {
    
    
    public static Car getCar(String car) {
    
    
        if (car.equals("五菱")){
    
    
            return new Wuling();
        } else if (car.equals("宝马")){
    
    
            return new Baoma();
        } else {
    
    
            return null;
        }
    }
}

消费者买车类 Consumer ,根据车名直接调用工厂类买车:

public class Consumer {
    
    
    public static void main(String[] args) {
    
    
        Car car1 = CarFactory.getCar("五菱");
        Car car2 = CarFactory.getCar("宝马");

        car1.name();
        car2.name();
    }
}

控制台结果如图:

在这里插入图片描述

另外,如果要买其他车,需要创建该车的实现类,并修改车工厂的代码,只是这样做会违背开闭原则。从设计原则来讲,是不支持简单工厂模式的,但在实际开发中该模式用的最多。

2.3、工厂方法模式

工厂方法模式不会违背开闭原则。

它是在简单工厂模式的基础上,创建车工厂接口,然后一一创建车实现车工厂接口:

已有接口 Car 、实现类 Wuling 、实现类 Baoma ,代码同简单工厂模式一样,现在创建接口车工程 CarFactory

public interface CarFactory {
    
    
    Car getCar();
}

创建实现类 WulingFactory 实现车工厂接口,生产五菱车:

public class WulingFactory implements CarFactory {
    
    
    @Override
    public Car getCar() {
    
    
        return new Wuling();
    }
}

创建实现类 BaomaFactory 实现车工厂接口,生产宝马车:

public class BaomaFactory implements CarFactory {
    
    
    @Override
    public Car getCar() {
    
    
        return new Baoma();
    }
}

工厂搭建完毕,下面是消费者买车的代码 Consumer ,直接向该车的工厂调用方法:

public class Consumer {
    
    
    public static void main(String[] args) {
    
    
        Car car1 = new WulingFactory().getCar();
        Car car2 = new BaomaFactory().getCar();
        car1.name();
        car2.name();
    }
}

结果跟简单工厂模式一样。

如果要消费者要买其他车,需要创建该车的实现类实现接口 Car 和该车的车工厂类实现 CarFactory 。工厂方法模式满足了开闭原则,只是在代码量上比简单工厂模式要多。

2.4、抽象工厂模式

定义:抽象工厂模式提供了一个创建一系列相关或者相互依赖的接口,无需指定它们具体的类。

适用场景:

  • 客户端(即应用层)不依赖产品类实例如何被创建、实现等细节。
  • 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码。
  • 提供一个产品类的库,所有产品以同样的接口出现,从而使得客户端不依赖于具体的实现。

优点:

  • 具体产品在应用层的代码隔离,无需关心创建的细节;
  • 将一个系列的产品统一到一起创建。

缺点:

  • 规定了所有可能被创建的产品集合,产品族中扩展新产品困难;
  • 增加了系统的抽象性和理解难度。

举例:使用抽象工厂模式在控制台输出小米系列产品“小米手机打电话”、“小米手机发短信”、“小米路由器打开WIFI”。

首先我们需要两个接口,一个生产手机 IphoneProduct

public interface IphoneProduct {
    
    
    void CallUp();// 手机打电话
    void SendSMS();// 手机发短信
}

一个生产路由器 RouterProduct

public interface RouterProduct {
    
    
    void OpenWIFI();// 路由器打开WIFI
}

接口写好了,下面该小米产品实现这两个接口,创建实现类 XiaomiIphone ,实现接口 IphoneProduct

public class XiaomiIphone implements IphoneProduct {
    
    
    @Override
    public void CallUp() {
    
    
        System.out.println("小米手机打电话");
    }

    @Override
    public void SendSMS() {
    
    
        System.out.println("小米手机发短信");
    }
}

创建实现类 XiaomiRouter ,实现接口 RouterProduct

public class XiaomiRouter implements RouterProduct {
    
    
    @Override
    public void OpenWIFI() {
    
    
        System.out.println("小米路由器打开WIFI");
    }
}

下面重点来了,创建抽象产品工厂接口 ProductFactory

public interface ProductFactory {
    
    
    // 生产手机
    IphoneProduct iphoneProduct();
    // 生产路由器
    RouterProduct routerProduct();
}

然后再创建接口小米系列产品的工厂 XiaomiFactory ,实现 ProductFactory 接口:

public class XiaomiFactory implements ProductFactory{
    
    
    // 生产小米手机
    @Override
    public IphoneProduct iphoneProduct() {
    
    
        return new XiaomiIphone();
    }
    // 生产小米路由器
    @Override
    public RouterProduct routerProduct() {
    
    
        return new XiaomiRouter();
    }
}

最后,创建消费者类 Consumer 购买小米手机打电话发短信、购买小米路由器打开WIFI:

public class Consumer {
    
    
    public static void main(String[] args) {
    
    
        System.out.println("====== 小米系列产品 ======");
        // 创建小米工厂
        XiaomiFactory xiaomiFactory = new XiaomiFactory();
        // 小米工厂生产手机
        IphoneProduct iphoneProduct = xiaomiFactory.iphoneProduct();
        iphoneProduct.CallUp();
        iphoneProduct.SendSMS();
        // 小米工厂生产路由器
        RouterProduct routerProduct = xiaomiFactory.routerProduct();
        routerProduct.OpenWIFI();
    }
}

控制台运行结果如下:

在这里插入图片描述

如果要生产其他系列产品的手机和路由器,需要创建三个该系列的实现类,一个实现 IphoneProduct 接口,一个实现 RouterProduct 接口,一个实现 ProductFactory 接口。

猜你喜欢

转载自blog.csdn.net/weixin_60808029/article/details/122607347
今日推荐