首页 > 其他分享 >设计模式[2]-工厂模式

设计模式[2]-工厂模式

时间:2024-08-23 11:04:24浏览次数:12  
标签:return 模式 工厂 GameConsole new 设计模式 createGameConsole public

代码:https://gitee.com/Aes_yt/design-pattern

工厂模式

1. 简单工厂模式

简单工厂模式主要包括三种角色:
  • 简单工厂 : 创建具体产品
  • 抽象产品 : 具体产品的父类
  • 具体产品 : 简单工厂创建的对象
例子:

设计一个游戏机类(GameConsole) 作为抽象产品,然后设计具体的产品(PlanStation4,XboxOne,WiiU),最后在简单工厂中创建具体的产品。逻辑很简单。

image-20211211215848285

GameConsole:

public abstract class GameConsole {
    public abstract String getName();

    public void play() {
        powerOn();
        System.out.println("正在用 " + getName() + " 玩游戏");
        powerOff();
    }

    private void powerOn() {
        System.out.println("开机 >>> ");
    }

    private void powerOff() {
        System.out.println("关机 >>>");
    }
}

PlayStation4:

public class PlayStation4 extends GameConsole {
    @Override
    public String getName() {
        return "playStation 4";
    }
}

XboxOne:

public class XboxOne extends GameConsole {
    @Override
    public String getName() {
        return "Xbox One";
    }
}

WiiU:

public class WiiU extends GameConsole {
    @Override
    public String getName() {
        return "Wii U";
    }
}

简单工厂类:GameConsoleSimpleFactory

public class GameConsoleSimpleFactory {

    public GameConsole createGameConsole(String type) {
        if ("Sony".equals(type)) {
            return new PlayStation4();
        } else if ("Microsoft".equals(type)) {
            return new XboxOne();
        } else if ("Nintendo".equals(type)) {
            return new WiiU();
        } else {
            throw new RuntimeException("不支持的游戏机");
        }
    }
}

测试类:

@Test
    void createGameConsole() {
        String[] arr = new String[]{"Sony", "Microsoft", "Nintendo"};
        GameConsoleSimpleFactory factory = new GameConsoleSimpleFactory();

        for (String type : arr) {
            GameConsole console = factory.createGameConsole(type);
            console.play();
            System.out.println();
        }
    }

输出:

开机 >>> 
正在用 playStation 4 玩游戏
关机 >>>

开机 >>> 
正在用 Xbox One 玩游戏
关机 >>>

开机 >>> 
正在用 Wii U 玩游戏
关机 >>>
优缺点

简单工厂类工厂和产品职责区分明确,但是工厂类过于单一,如果需要引入更多的类,则需要改动工厂类,不便拓展,类型过多时,也会造成逻辑复杂。

tips:

可以在工厂方法加static关键字,无需实例化工厂类。

public static GameConsole createGameConsole(String type)

2. 工厂方法模式

工厂方法模式主要包括四种角色:
  • 抽象工厂 : 只提供创建产品的接口
  • 具体工厂 : 实现抽象工厂的抽象方法,完成产品的创建
  • 抽象产品 : 具体产品的父类
  • 具体产品 : 具体工厂所创建的对象
例子:

将简单工厂模式的例子用工厂方法模式进行实现。

image-20211211223508840

抽象产品和具体产品类不变:GameConsole 类、PlayStation4类、XboxOne类、WiiU类不变。

抽象工厂:

GameConsoleFactory:

public interface GameConsoleFactory {
    GameConsole createGameConsole();
}

具体工厂类:

MicrosoftGameConsoleFactory:

public class MicrosoftGameConsoleFactory implements GameConsoleFactory {
    @Override
    public GameConsole createGameConsole() {
        return new XboxOne();
    }
}

NintendoGameConsoleFactory:

public class NintendoGameConsoleFactory implements GameConsoleFactory {
    @Override
    public GameConsole createGameConsole() {
        return new WiiU();
    }
}

SonyGameConsoleFactory:

public class SonyGameConsoleFactory implements GameConsoleFactory {
    @Override
    public GameConsole createGameConsole() {
        return new PlayStation4();
    }
}

测试类

@Test
void createGameConsole() {
    play(new SonyGameConsoleFactory());
    play(new NintendoGameConsoleFactory());
    play(new MicrosoftGameConsoleFactory());
}

private void play(GameConsoleFactory gameConsoleFactory) {
    GameConsole gameConsole = gameConsoleFactory.createGameConsole();
    gameConsole.play();
}

输出:

开机 >>> 
正在用 playStation 4 玩游戏
关机 >>>
开机 >>> 
正在用 Wii U 玩游戏
关机 >>>
开机 >>> 
正在用 Xbox One 玩游戏
关机 >>>
优缺点

优点创建对象灵活,若后期有添加新的产品,不需要改旧的代码,只需要建新的具体产品类和具体的工厂类即可。

缺点也很明显,创建的类变多了,增加了系统的复杂性。

3. 抽象工厂模式

抽象工厂模式主要包括四种角色:
  • 抽象工厂 : 提供创建产品的接口,但有多个创建产品的方法,可以创建多个不同等级的产品
  • 具体工厂 : 实现抽象工厂的多个抽象方法,完成产品的创建
  • 抽象产品 : 具体产品的父类
  • 具体产品 : 具体工厂所创建的对象

抽象工厂模式是工厂方法模式的升级版。它的角色和工厂方法模式一样都是这四种。

为什么需要用到抽象工厂方法模式呢,我们可以看看上面游戏机的例子。现在如果我们还需要创建游戏机相关的游戏手柄,那么我们利用工厂方法模式来创建的话,除了建游戏手柄抽象类和具体类以外,就还需要再建游戏手柄抽象工厂还有各个品牌的游戏手柄的具体工厂。这样类创建就会过多。

所以,在使用同一个产品族的情况下,利用抽象工厂模式能够对同一产品族的不同等级的产品进行很好的创建管理。

注:同一产品族:索尼游戏机,索尼游戏手柄,这是同一产品族下的不同等级产品。

例子:

image-20211212000557018

新增游戏手柄Gamepad抽象类,和具体的实现类

public abstract class Gamepad {
    public abstract void getName();
}
public class MicrosoftGamepad extends Gamepad{
    @Override
    public void getName() {
        System.out.println("微软游戏手柄");
    }
}
public class SonyGamepad extends Gamepad {
    @Override
    public void getName() {
        System.out.println("索尼游戏手柄");
    }
}
public class NintendoGamepad extends Gamepad {
    @Override
    public void getName() {
        System.out.println("任天堂游戏手柄");
    }
}

原本的抽象工厂改名为游戏设备工厂GameDeviceFactory,新增创建一个游戏手柄的抽象方法

GameDeviceFactory:

public interface GameDeviceFactory {
    /**
     * @param
     * @return "com.yt.design.abstractfactory.GameConsole"
     * @description 创建游戏机对象
     * @author lzf
     * @date 2021/12/11 22:14
     */
    GameConsole createGameConsole();

    /**
     * @param
     * @return "com.yt.design.abstractfactory.Gamepad"
     * @description 创建手柄对象
     * @author lzf
     * @date 2021/12/11 23:57
     */
    Gamepad createGamepad();
}

具体工厂:

MicrosoftGameDeviceFactory:

public class MicrosoftGameDeviceFactory implements GameDeviceFactory {
    @Override
    public GameConsole createGameConsole() {
        return new XboxOne();
    }

    @Override
    public Gamepad createGamepad() {
        return new MicrosoftGamepad();
    }
}

MicrosoftGameDeviceFactory:

public class NintendoGameDeviceFactory implements GameDeviceFactory {
    @Override
    public GameConsole createGameConsole() {
        return new WiiU();
    }

    @Override
    public Gamepad createGamepad() {
        return new NintendoGamepad();
    }
}

SonyGameDeviceFactory:

public class SonyGameDeviceFactory implements GameDeviceFactory {
    @Override
    public GameConsole createGameConsole() {
        return new PlayStation4();
    }

    @Override
    public Gamepad createGamepad() {
        return new SonyGamepad();
    }
}

测试类:

class GameDeviceFactoryTest {

    @Test
    void createGameConsole() {
        show(new MicrosoftGameDeviceFactory());
        show(new SonyGameDeviceFactory());
        show(new NintendoGameDeviceFactory());
    }

    private void show(GameDeviceFactory gameDeviceFactory) {
        GameConsole gameConsole = gameDeviceFactory.createGameConsole();
        Gamepad gamepad = gameDeviceFactory.createGamepad();

        gameConsole.play();
        gamepad.getName();
        System.out.println();
    }
}

输出:

开机 >>> 
正在用 Xbox One 玩游戏
关机 >>>
微软游戏手柄

开机 >>> 
正在用 playStation 4 玩游戏
关机 >>>
索尼游戏手柄

开机 >>> 
正在用 Wii U 玩游戏
关机 >>>
任天堂游戏手柄
优缺点

抽象工厂模式可以在同一个抽象工厂类创建不同产品等级的对象,当增加新的产品族时也不需要修改代码,只需要创建新的具体工厂类即可。

但是,当产品族需要再加新的产品等级时,比如在增加一个游戏遥控器类,那么还是需要修改所有的抽象工厂类和具体产品类的代码的。

标签:return,模式,工厂,GameConsole,new,设计模式,createGameConsole,public
From: https://www.cnblogs.com/Aeons/p/18375609

相关文章

  • 设计模式[1]-单例模式
    代码:https://gitee.com/Aes_yt/design-pattern单例模式单例模式(Singleton)是一种创建型设计模式,能够保证一个类只有一个实例,并提供了访问该实例的全局节点。单例的实现步骤有以下步骤,首先将默认构造函数设置为私有,然后创建一个静态方法来调用私有构造函数来创建对象。单例类......
  • Scratch编程环境的暗色模式:探索可访问性的边界
    标题:Scratch编程环境的暗色模式:探索可访问性的边界Scratch,这个广受欢迎的图形化编程平台,由麻省理工学院媒体实验室开发,一直致力于为用户提供友好且易于访问的编程体验。随着用户对编程环境个性化需求的增长,Scratch的编程环境是否支持暗模式或可访问性选项,成为了编程教育领......
  • C++设计模式1:单例模式(懒汉模式和饿汉模式,以及多线程问题处理)
    饿汉单例模式        程序还没有主动获取实例对象,该对象就产生了,也就是程序刚开始运行,这个对象就已经初始化了。 classSingleton{public: ~Singleton() { std::cout<<"~Singleton()"<<std::endl; } staticSingleton*get_instance() { return&sin......
  • 火影忍者2——漩涡鸣人(仙人模式)篇
    老规矩,谈火影~火影忍者之——漩涡鸣人(仙人模式)篇众所周知,鸣仙是一个早期的A忍,技能破坏力贼大,一般遇到鸣仙(除非我用了青水+神卡)我是直接退的普攻一技能螺旋丸普通状态下一技能长摁放出两个分身释放螺旋丸,属于远程技能,但释放时的施法动作容易被打断,点击是本体出去,......
  • Java设计模式之代理模式:静态代理VS动态代理,与其他模式的对比分析和案例解析
    一、代理模式简介代理模式(ProxyPattern)是一种结构型设计模式,它提供了一个代理对象,用来控制对另一个对象的访问。这种模式通常用于在访问对象时引入额外的功能,而不改变对象的接口。代理模式的核心思想是为其他对象提供一种代理,以控制对这个对象的访问。在现实生活中,代理模......
  • 设计模式之责任链模式
    责任链模式是面向对象的23种设计模式中的一种,属于行为模式范围。责任链模式(ChainofResponsibility),见名知意:就是每一个处理请求的处理器组合成一个链表,链表中的每个节点(执行器)都有机会处理发送的请求。大致的结构是这个样子: 举一个简单的例子:某公司有一名新员工要入职,则入职......
  • Flannel Wireguard 模式
    FlannelWireGuard模式一、环境信息主机IPubuntu172.16.94.141软件版本docker26.1.4helmv3.15.0-rc.2kind0.18.0clab0.54.2kubernetes1.23.4ubuntuosUbuntu20.04.6LTSkernel5.11.5内核升级文档二、安装服务kind配置......
  • 三防平板加固终端助力汽车工厂更快交付高质量车辆
    随着汽车的市场需求量不断扩大,如何简化生产检验流程以提高汽车生产效率和安全性成为了汽车制造商的主要关注点。过去基于纸质化的检验流程已无法满足更高质量、更具成本效益的车辆生产要求,能够取代繁琐且易出错的纸质文件,提供对整个生产检验流程的全面可见性和问题可追溯性的数......
  • Flannel IPsec 模式
    FlannelIPSec模式一、环境信息主机IPubuntu172.16.94.141软件版本docker26.1.4helmv3.15.0-rc.2kind0.18.0clab0.54.2kubernetes1.23.4ubuntuosUbuntu20.04.6LTSkernel5.11.5内核升级文档二、安装服务kind配置文件......
  • 分布式事务的Seata AT模式原理
    Seata官网地址:https://seata.apache.org/zh-cn/AT模式优点:无侵入式代码,只需要添加注解,底层采用Seata代理的数据源DataSourceProxy缺点:依赖于数据库,目前只适用于postgresql、oracle、mysql、polardb-x、sqlserver、达梦数据库等数据库,比如业务逻辑中含有redis、es等操作需要控......