抽象工厂模式

什么是抽象工厂模式

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

可以简单理解成是围绕一个超级工厂来创建其他工厂(这个超级工厂是其他工厂的工厂)。

适用场景:

  • 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节。
  • 强调一系列相关的产品对象(属于同一产品簇)一起使用创建对象需要大量的重复代码。
  • 提供一个产品类的苦,所有的产品以同样的接口出现,从而使得客户端不依赖于具体实现。
  • 抽象工厂模式适用于稳定的结构(即,不经常做出改变的一个工厂),如果要做更改,需要修改一个接口及其所有实现类。

优点:

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

缺点:

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

为什么要使用抽象工厂模式

新时期有新问题

2021年6月2日后,智能终端可以使用Harmony OS了,一个设备可以轻松调用另一设备的算力、硬件,当然可以自由使用其他设备的应用。

这样,我们手头的播放器就不止两款了,假设现在有一个手机和一个平板电脑,上面都安装了bilibili和youku两个播放器。

我们要使用这四个播放器,可以使用简单工厂来实现:

简单工厂模式实现:

我们将一个终端看作一个工厂,这样就有两个工厂

两个工厂类:

public class PhonePlayerFactory {
    public Iplayer getPlayer(String player) {
        Iplayer iplayer;
        if ("bilibili".equals(player)) {
            iplayer = new PhoneBilibili();
        } else if ("youku".equals(player)) {
            iplayer = new PhoneYouku();
        } else {
            iplayer = null;
        }
        return iplayer;
    }
}
public class PadPlayerFactory {
    public Iplayer getPlayer(String player) {
        Iplayer iplayer;
        if ("bilibili".equals(player)) {
            iplayer = new PadBilibili();
        } else if ("youku".equals(player)) {
            iplayer = new PadYouku();
        } else {
            iplayer = null;
        }
        return iplayer;
    }
}

客户端:

public class User {
    
    public static void main(String[] args) {
        PadPlayerFactory padPlayerFactory = new PadPlayerFactory();
        PhonePlayerFactory phonePlayerFactory = new PhonePlayerFactory();
        String type = getType();
        Iplayer player1 = padPlayerFactory.getPlayer(type);
        Iplayer player2 = phonePlayerFactory.getPlayer(type);

        player1.play();
        player2.play();
    }

    private static String getType() {
        Scanner scanner = new Scanner(System.in);
        return scanner.nextLine();
    }
}
存在的问题
  • 两个Factory明明做的是相同的事,但却没有统一标准。

为了解决这个问题,我们就需要一个能创建工厂的工厂,即,抽象工厂。

抽象工厂模式实现:

  1. 用一个接口来规范一个工厂可以生产出bilibili和youku两个播放器,即IPlayerFactory。
  2. 由两个具体工厂来实现该规范,即PhonePlayerFactory和PadPlayerFactory。

工厂接口:

public interface IPlayerFactory {
    IPlayer getBilibiliPlayer();

    IPlayer getYoukuPlayer();
}

两个工厂实现类:

public class PhonePlayerFactory implements IPlayerFactory {
    @Override
    public IPlayer getBilibiliPlayer() {
        return new PhoneBilibili();
    }

    @Override
    public IPlayer getYoukuPlayer() {
        return new PhoneYouku();
    }
}
public class PadPlayerFactory implements IPlayerFactory {
    @Override
    public IPlayer getBilibiliPlayer() {
        return new PadBilibili();
    }

    @Override
    public IPlayer getYoukuPlayer() {
        return new PadYouku();
    }
}

播放器接口:

public interface IPlayer {
    void play();
}

四个播放器:

public class PhoneBilibili implements IPlayer {
    @Override
    public void play() {
        System.out.println("手机Bilibili播放。");
    }
}
public class PhoneYouku implements IPlayer {
    @Override
    public void play() {
        System.out.println("手机Youku播放。");
    }
}
public class PadBilibili implements IPlayer {
    @Override
    public void play() {
        System.out.println("平板电脑bilibili播放。");
    }
}
public class PadYouku implements IPlayer {
    @Override
    public void play() {
        System.out.println("平板电脑Youku播放。");
    }
}

客户端:

import java.util.Scanner;

public class User {
    public static void main(String[] args) {
        String type = getType();
        IPlayerFactory playerFactory;

        if ("pad".equals(type)) {//这里可以再封装出一个工厂,用于生产工厂。
            playerFactory = new PadPlayerFactory();
        } else if ("phone".equals(type)) {
            playerFactory = new PhonePlayerFactory();
        }else {
            System.out.println("无此设备");
            return;
        }

        type = getType();
        IPlayer player;
        if ("bilibili".equals(type)) {
            player = playerFactory.getBilibiliPlayer();
        } else if ("youku".equals(type)) {
            player = playerFactory.getYoukuPlayer();
        } else {
            System.out.println("没有此播放器");
            return;
        }

        player.play();
    }

    private static String getType() {
        Scanner scanner = new Scanner(System.in);
        return scanner.nextLine();
    }
}

类图

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值