zoukankan      html  css  js  c++  java
  • 23种设计模式之工厂模式

    工厂模式属于创建型设计模式,用工厂方法代替new操作,让子类去决定实例化哪个类,工厂方法将一个类的实例化延迟到子类

    推荐访问我的个人网站,排版更好看呦:https://chenmingyu.top/design-factory-method/

    什么是工厂模式

    定义一个创建对象的接口,由子类去决定实例化哪一个类,将实例化对象的操作延迟到子类

    优点:

    1. 解耦:调用方不用负责对象的创建,只需要使用,明确各自的职责
    2. 维护方便:后期如果创建对象时需要修改代码,也只需要去工厂方法中修改,易拓展

    工厂模式细分为:简单工厂,工厂模式,抽象工厂

    简单工厂

    以游戏为例子,涉及四个类:GameFactory(游戏工厂类),Gameable(游戏接口),ShootGame(射击类游戏),TowerDefenceGame(塔防类游戏)

    比如游戏工厂,工厂方法通过出入的参数生成生成不同产品类型的游戏

    Gameable

    游戏接口,提供一个校验账户信息的接口

    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 11:19
     * @description:
     */
    public interface Gameable {
    
        /**
         * 校验账户信息
         * @param nickName
         */
        void validateAccount(String nickName);
    }
    
    ShootGame

    射击类游戏,实现Gameable接口

    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 11:26
     * @description: 射击类游戏
     */
    public class ShootGame implements Gameable{
    
        @Override
        public void validateAccount(String nickName) {
            System.out.println("射击游戏校验昵称:"+nickName);
        }
    }
    
    TowerDefenceGame

    塔防类游戏,实现Gameable接口

    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 11:28
     * @description: 塔防类游戏
     */
    public class TowerDefenceGame implements Gameable{
    
        @Override
        public void validateAccount(String nickName) {
            System.out.println("塔防游戏校验昵称:"+nickName);
        }
    }
    
    GameFactory

    游戏工厂,封装了创建游戏对象的过程

    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 11:29
     * @description: 工厂类
     */
    public class GameFactory {
    
        /**
         * 根据传入类型生成实例
         * @param gameType
         * @return
         */
        public static Gameable creator(String gameType){
            Gameable gameable = null;
            if(StringUtils.isEmpty(gameType)){
                return gameable;
            }
            if("shoot".equalsIgnoreCase(gameType)){
                gameable = new ShootGame();
            }else if("towerDefence".equalsIgnoreCase(gameType)){
                gameable = new TowerDefenceGame();
            }
            return gameable;
        }
    }
    
    测试

    客户端决定实例化哪个对象

    public static void main(String[] args) {
        Gameable shootGame = GameFactory.creator("shoot");
        shootGame.validateAccount("明羽");
        System.out.println("... 分割线 ...");
        Gameable towerDefenceGame = GameFactory.creator("towerDefence");
        towerDefenceGame.validateAccount("明羽");
    }
    

    输出

    射击游戏校验昵称:明羽
    ... 分割线 ...
    塔防游戏校验昵称:明羽
    

    如果要新增一个拳击类游戏的话,就需要新建一个拳击游戏类,然后修改工厂方法。

    工厂模式

    工厂模式跟简单工厂模式的区别在于简单工厂只有一个工厂类,提供了一个工厂方法,由入参决定生产那个产品,而工厂模式则定义一个工厂接口,不同的产品工厂实现工厂接口,生产的产品由产品工厂决定

    以游戏为例子,在上面四个类的基础上修改GameFactory(游戏工厂类)为接口,新增了两个类:ShootGameFactory(射击类游戏工厂),TowerDefenceGameFactory(塔防类游戏工厂)

    修改了的GameFactory
    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 11:29
     * @description: 工厂类
     */
    public interface GameFactory {
    
        /**
         * 生成实例
         * @return
         */
        Gameable creator();
    }
    
    ShootGameFactory

    实现GameFactory,重写creator()

    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 15:14
     * @description: 射击类游戏工厂
     */
    public class ShootGameFactory implements GameFactory{
    
        @Override
        public Gameable creator() {
            return new ShootGame();
        }
    }
    
    TowerDefenceGameFactory

    实现GameFactory,重写creator()

    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 15:15
     * @description: 塔防类游戏工厂
     */
    public class TowerDefenceGameFactory implements GameFactory{
    
        @Override
        public Gameable creator() {
            return new TowerDefenceGame();
        }
    }
    
    测试
    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 11:38
     * @description:
     */
    public class FactoryTest {
    
        public static void main(String[] args) {
    
            GameFactory shootGameFactory = new ShootGameFactory();
            Gameable shootGame = shootGameFactory.creator();
            shootGame.validateAccount("明羽");
            System.out.println("... 分割线 ...");
            GameFactory towerDefenceGameFactory = new TowerDefenceGameFactory();
            Gameable towerDefenceGame = towerDefenceGameFactory.creator();
            towerDefenceGame.validateAccount("明羽");
        }
    }
    

    输出

    射击游戏校验昵称:明羽
    ... 分割线 ...
    塔防游戏校验昵称:明羽
    

    抽象工厂

    抽象工厂比工厂模式更为抽象,工厂模式只生产一种产品族,而抽象工厂生产多个产品族

    产品族是指同一工厂生产的一组不同产品结构的一组产品,比如射击游戏工厂生产单人射击游戏和双人射击游戏两款产品,这里的单人射击游戏产和双人射击游戏两款产品统称为产品族

    以上面的游戏为例,现在有射击游戏和塔防游戏俩款游戏,现在需求变了,要求射击类游戏又细分为单人和双人两款游戏产品,塔防类游戏细分为单人和双人两款游戏产品。这时射击类游戏和塔防类游戏就是两个产品族,旗下分别有两款产品一款是单人游戏,一款是双人游戏

    类图

    有点复杂,画个类图,看着清晰一些

    1. GameFactory:抽象工厂,规定了生成单人和双人两种游戏
    2. ShootGameFactory,ShootGameFactory:具体工厂,负责生产具体的射击类和塔防类单,双人游戏
    3. Gameable是抽象产品,ShootGame和TowerDefenceGame是抽象类,继承Gameable
    4. SingleShootGame,DoubleShootGame,SingleTowerDefenceGame,DoubleTowerDefenceGame是具体产品
    GameFactory

    抽象工厂,规定了生成单人和双人两种游戏

    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 11:29
     * @description: 抽象工厂
     */
    public interface GameFactory {
    
        /**
         * 生产单人游戏
         * @return
         */
        Gameable createSingleGame();
    
        /**
         * 生产双人游戏
         * @return
         */
        Gameable createDoubleGame();
    
    }
    
    ShootGameFactory

    具体工厂,负责生产具体的射击类单人游戏和射击类双人游戏

    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 18:20
     * @description: 设计游戏制造厂
     */
    public class ShootGameFactory implements GameFactory{
    
        @Override
        public Gameable createSingleGame() {
            return new SingleShootGame();
        }
    
        @Override
        public Gameable createDoubleGame() {
            return new DoubleShootGame();
        }
    }
    
    TowerDefenceGameFactory

    具体工厂,负责生产具体的塔防类单人游戏和塔防类双人游戏

    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 18:20
     * @description: 塔防游戏制造厂
     */
    public class TowerDefenceGameFactory implements GameFactory {
    
        @Override
        public Gameable createSingleGame() {
            return new SingleTowerDefenceGame();
        }
    
        @Override
        public Gameable createDoubleGame() {
            return new DoubleTowerDefenceGame();
        }
    }
    
    Gameable

    抽象产品,所有游戏产品均实现该接口

    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 11:19
     * @description: 游戏接口
     */
    public interface Gameable {
    
        /**
         * 校验账户信息
         * @param nickName
         */
        void validateAccount(String nickName);
    
    
        /**
         * 游戏人数
         */
        void getPlayerNumber();
    }
    
    ShootGame和TowerDefenceGame

    抽象类,实现Gameable接口

    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 11:26
     * @description: 射击类游戏
     */
    public abstract class ShootGame implements Gameable{
    
        @Override
        public void validateAccount(String nickName) {
            System.out.println("射击游戏校验昵称:"+nickName);
        }
    
    }
    
    /**
     * @auther: chenmingyu
     * @date: 2019/2/14 11:28
     * @description: 塔防类游戏
     */
    public abstract class TowerDefenceGame implements Gameable{
    
        @Override
        public void validateAccount(String nickName) {
            System.out.println("塔防游戏校验昵称:"+nickName);
        }
    
    }
    
    具体产品

    共四款游戏产品:SingleShootGame,DoubleShootGame,SingleTowerDefenceGame,DoubleTowerDefenceGame

    /**
     * @auther: chenmingyu
     * @date: 2019/2/15 16:55
     * @description: 单人射击游戏
     */
    public class SingleShootGame extends ShootGame {
    
        @Override
        public void getPlayerNumber() {
            System.out.println("这是一个单人玩的射击游戏");
        }
    }
    
    
    /**
     * @auther: chenmingyu
     * @date: 2019/2/15 16:57
     * @description: 双人射击游戏
     */
    public class DoubleShootGame extends ShootGame{
    
        @Override
        public void getPlayerNumber() {
            System.out.println("这是一个双人玩的射击游戏");
        }
    }
    
    /**
     * @auther: chenmingyu
     * @date: 2019/2/15 17:17
     * @description: 单人塔防游戏
     */
    public class SingleTowerDefenceGame extends TowerDefenceGame{
    
        @Override
        public void getPlayerNumber() {
            System.out.println("这是一个单人玩的塔防游戏");
        }
    }
    
    /**
     * @auther: chenmingyu
     * @date: 2019/2/15 17:18
     * @description: 双人塔防游戏
     */
    public class DoubleTowerDefenceGame extends TowerDefenceGame{
        @Override
        public void getPlayerNumber() {
            System.out.println("这是一个双人玩的塔防游戏");
        }
    }
    
    测试
    public static void main(String[] args) throws Exception{
    
        ShootGameFactory shootGameFactory = new ShootGameFactory();
        shootGameFactory.createSingleGame().getPlayerNumber();
        shootGameFactory.createDoubleGame().getPlayerNumber();
    
        TowerDefenceGameFactory towerDefenceGameFactory = new TowerDefenceGameFactory();
        towerDefenceGameFactory.createSingleGame().getPlayerNumber();
        towerDefenceGameFactory.createDoubleGame().getPlayerNumber();
    }
    

    输出

    这是一个单人玩的射击游戏
    这是一个双人玩的射击游戏
    这是一个单人玩的塔防游戏
    这是一个双人玩的塔防游戏
    
  • 相关阅读:
    UE4免费了
    c# 下 根据Datatable的结构动态创建表
    SharePoint 调用 WebService操作List小记
    同步SharePoint List数据到关系数据库
    如何提升SharePoint 2010的性能
    DataX的使用
    C#调用RabbitMQ实现消息队列
    在SharePoint2010上使用QuickFlow和QuickFlowDesigner
    QUICKFLOW安装
    如何设置IIS程序池的回收时间,才能最大程度的减少对用户的影响?
  • 原文地址:https://www.cnblogs.com/cmyxn/p/10387529.html
Copyright © 2011-2022 走看看