java设计模式--三种工厂模式详解


Posted in Java/Android onJuly 21, 2021

简单工厂

简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)。当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式。

由于创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法模式(Static Factory Method)。

java设计模式--三种工厂模式详解

  • Product表示产品接口,也可用抽象类实现,封装产品间共有的属性。
  • ConcreteProduct*表示具体的实际产品。
  • Factory表示工厂,工厂根据需要来创建相应的产品。

这样一来,当添加新的产品C时,只需要修改工厂部分代码即可,而传统方法需要在每一个创建产品的地方都进行修改。可以理解为把具体的产品创建封装成一个工厂类。

举个例子,大富翁的地图创建:

  • AbstractBlock是接口,表示抽象的地块,包括方法printBlock()打印地块。
  • Empty、Prison、Park实现上述接口,表示空地(*)、监狱(&)和公园(#)。
  • SimpleFactory是创建地块的简单工厂。

类图:

java设计模式--三种工厂模式详解

代码:

1.产品接口

public interface AbstractBlock {
    public void printBlock();
}

2.产品接口实现子类

public class Empty implements AbstractBlock{
    @Override
    public void printBlock() {
        System.out.print("* ");
    }
}
public class Park implements AbstractBlock{
    @Override
    public void printBlock() {
        System.out.print("# ");
    }
}
public class Prison implements AbstractBlock{
    @Override
    public void printBlock() {
        System.out.print("& ");
    }
}

3.简单工厂类

public class SimpleFactory {
    public AbstractBlock getBlock(String type){ //根据传参创建不同的地块
        if(type.equalsIgnoreCase("Empty")){
            return new Empty();
        } else if(type.equalsIgnoreCase("Park")){
            return new Park();
        } else if(type.equalsIgnoreCase("Prison")){
            return new Prison();
        }
        return null;
    }
}

4.调用工厂

public class Map {
    public void getMap(){
        SimpleFactory simpleFactory=new SimpleFactory();  //实例化工厂
        ArrayList<AbstractBlock> map=new ArrayList<AbstractBlock>();  //地块集合
        String []types=new String[3];
        types[0]="Empty";
        types[1]="park";
        types[2]="Prison";
        Random rd = new Random();
        for(int i=1;i<=12;i++){  //随机用工厂创建地块并放入集合
            int tt = rd.nextInt(types.length);
            map.add(simpleFactory.getBlock(types[tt]));
        }
        //地图大小写死了,不是重点
        for(int i=0;i<12;i++){
            map.get(i).printBlock();
            if(i==3||i==5||i==7)
                System.out.println();
            if(i==4||i==6)
                System.out.print("    ");
        }
    }
}

5.测试

public class MonoPoly {
    public static void main(String[] args) {
        Map map=new Map();
        map.getMap();
    }
}

运行结果

java设计模式--三种工厂模式详解

工厂方法

不难发现,当增加新的产品时需要对简单工厂类修改,或创建多个简单工厂。(比如增加一个法院地块)工厂方法进一步解耦合,把工厂类抽象,不再负责所有实例的创建,而是把具体的创建工作交给了子类去完成,实例化延迟到子类加载,由子类来决定要实例化的类。

java设计模式--三种工厂模式详解

抽象化工厂类,把具体实例化工作交给其子类实现。

代码:

1.工厂接口

public interface AbstractFactory {
    public AbstractBlock createBlock();
}

2.工厂实现子类

public class EmptyFactory implements AbstractFactory {
    @Override
    public AbstractBlock createBlock() {
        return new Empty();
    }
}
public class ParkFactory implements AbstractFactory {
    @Override
    public AbstractBlock createBlock() {
        return new Park();
    }
}
public class PrisonFactory implements AbstractFactory {
    @Override
    public AbstractBlock createBlock() {
        return new Prison();
    }
}

3.产品接口

public interface AbstractBlock {
    public void printBlock();
}

4.产品实现子类

public class Empty implements AbstractBlock {
    @Override
    public void printBlock() {
        System.out.print("* ");
    }
}
public class Park implements AbstractBlock {
    @Override
    public void printBlock() {
        System.out.print("# ");
    }
}
public class Prison implements AbstractBlock {
    @Override
    public void printBlock() {
        System.out.print("& ");
    }
}

5.调用

public class Map {
    public void getMap() {
        ArrayList<AbstractBlock> map=new ArrayList<AbstractBlock>();  //地块集合
        AbstractFactory abstractFactory;
        Random rd = new Random();
        for(int i=1;i<=12;i++){  //随机用工厂创建地块并放入集合
            int tt = rd.nextInt(3);
            if(tt==0)abstractFactory=new EmptyFactory();
            else if(tt==1)abstractFactory=new ParkFactory();
            else abstractFactory=new PrisonFactory();
            map.add(abstractFactory.createBlock());
        }
        //地图大小写死了,不是重点
        for(int i=0;i<12;i++){
            map.get(i).printBlock();
            if(i==3||i==5||i==7)
                System.out.println();
            if(i==4||i==6)
                System.out.print("    ");
        }
    }
}

6.测试

public class MonoPoly {
    public static void main(String[] args) {
        Map map=new Map();
        map.getMap();
    }
}

运行结果:

java设计模式--三种工厂模式详解

抽象工厂

不难发现当创建新的产品接口时,也需要对工厂方法修改,或创建多个工厂方法。(比如增加魔法地块簇,对应组产品魔法公园、魔法空地、魔法监狱等)

抽象工厂将工厂方法进一步抽象。定义了一个接口用于创建相关或有依赖关系的对象簇,而无需指明具体的类。可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。

java设计模式--三种工厂模式详解

把工厂类抽象后,对应不同子类工厂(普通/魔法),生产对应的一组产品。最后调用时统一调用抽象接口即可,不必知道具体对象,面向接口编程。

1.产品接口

public interface AbstractBlock {
    void printBlock();
}

2.产品抽象子类-普通产品

public abstract class NormalAbstractBlock implements AbstractBlock {
    public abstract void printBlock();
}

2.2普通空地

public class NormalEmpty extends NormalAbstractBlock {
    public void printBlock() {
        System.out.print("* ");
    }
}

2.3普通公园

public class NormalPark  extends NormalAbstractBlock {
    public void printBlock() {
        System.out.print("# ");
    }
}

2.4普通监狱

public class NormalPrison extends NormalAbstractBlock {
    public void printBlock() {
        System.out.print("& ");
    }
}

3.1产品抽象子类-魔法产品

public abstract class MagicAbstractBlock implements AbstractBlock {
    public abstract void printBlock();
}

3.2魔法空地

public class MagicEmpty  extends MagicAbstractBlock {
    public void printBlock() {
        System.out.print("e ");
    }
}

3.3魔法公园

public class MagicPark extends MagicAbstractBlock {
    public void printBlock() {
        System.out.print("g ");
    }
}

3.4魔法监狱

public class MagicPrison extends MagicAbstractBlock {
    public void printBlock() {
        System.out.print("p ");
    }
}

4.工厂接口

public interface AbstractFactory {
    AbstractBlock getEmpty();
    AbstractBlock getPrison();
    AbstractBlock getPark();
}

5.工厂实现子类-普通工厂

public class NormalFactory implements  AbstractFactory {
    public AbstractBlock getEmpty() { return new NormalEmpty(); }
    public AbstractBlock getPrison() { return new NormalPrison(); }
    public AbstractBlock getPark() { return new NormalPark(); }
}

6.工厂实现子类-魔法工厂

public class MagicFactory implements AbstractFactory {
    public AbstractBlock getEmpty() { return new MagicEmpty(); }
    public AbstractBlock getPrison() {return new MagicPrison(); }
    public AbstractBlock getPark() { return new MagicPark(); }
}

7.调用

public class Map {
    public void getMap(AbstractFactory af){
        ArrayList<AbstractBlock> map=new ArrayList<AbstractBlock>();
        map.add(af.getEmpty());
        map.add(af.getPrison());
        map.add(af.getPark());
        Random rd = new Random(3);
        int col=12;
        for(int i=1;i<=col;i++){
            int tt = rd.nextInt(3);
            map.get(tt).printBlock();
            if(i==4||i==6||i==8)
                System.out.println();
            if(i==5||i==7)
                System.out.print("    ");
        }
    }
}

8.测试

public class Monopoly {
    public void play(){
        Map map=new Map();
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入指令(1输出普通地图,2输出魔法地图)");
        int order;
        order  = scan.nextInt();
        if(order == 1){
            map.getMap(new NormalFactory());
        }else{
            map.getMap(new MagicFactory());
        }
    }
}

运行结果:

java设计模式--三种工厂模式详解

java设计模式--三种工厂模式详解

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注三水点靠木的更多内容!

Java/Android 相关文章推荐
springboot中一些比较常用的注解总结
Jun 11 Java/Android
springboot如何初始化执行sql语句
Jun 22 Java/Android
使用springMVC所需要的pom配置
Sep 15 Java/Android
Android自定义scrollview实现回弹效果
Apr 01 Java/Android
Android基于Fresco实现圆角和圆形图片
Apr 01 Java/Android
零基础学java之循环语句的使用
Apr 10 Java/Android
Spring Data JPA框架Repository自定义实现
Apr 28 Java/Android
springboot读取nacos配置文件
May 20 Java/Android
SpringBoot全局异常处理方案分享
May 25 Java/Android
Ubuntu18.04下QT开发Android无法连接设备问题解决实现
Jun 01 Java/Android
SpringBoot使用ip2region获取地理位置信息的方法
Jun 21 Java/Android
Spring boot实现上传文件到本地服务器
Aug 14 Java/Android
gateway与spring-boot-starter-web冲突问题的解决
Jul 16 #Java/Android
springboot集成springCloud中gateway时启动报错的解决
Jul 16 #Java/Android
JavaWeb 入门篇(3)ServletContext 详解 具体应用
JavaWeb 入门:Hello Servlet
JavaWeb 入门篇:创建Web项目,Idea配置tomcat
mybatis 获取无数据的字段不显示的问题
Jul 15 #Java/Android
Lombok的详细使用及优缺点总结
Jul 15 #Java/Android
You might like
一个简单计数器的源代码
2006/10/09 PHP
PHP配置把错误日志以邮件方式发送方法(Windows系统)
2015/06/23 PHP
PHP.vs.JAVA
2016/04/29 PHP
ThinkPHP框架分布式数据库连接方法详解
2017/03/14 PHP
javascript英文日期(有时间)选择器
2007/05/02 Javascript
Angular.js中ng-if、ng-show和ng-hide的区别介绍
2017/01/20 Javascript
详解webpack+vue-cli项目打包技巧
2017/06/17 Javascript
vue + element-ui的分页问题实现
2018/12/17 Javascript
解决vue addRoutes不生效问题
2020/08/04 Javascript
使用Python的Bottle框架写一个简单的服务接口的示例
2015/08/25 Python
python3实现全角和半角字符转换的方法示例
2017/09/21 Python
Python利用heapq实现一个优先级队列的方法
2019/02/03 Python
浅谈Python编程中3个常用的数据结构和算法
2019/04/30 Python
在Django中实现添加user到group并查看
2019/11/18 Python
python实现超市商品销售管理系统
2019/11/22 Python
python数据库开发之MongoDB安装及Python3操作MongoDB数据库详细方法与实例
2020/03/18 Python
python3中的logging记录日志实现过程及封装成类的操作
2020/05/12 Python
python使用re模块爬取豆瓣Top250电影
2020/10/20 Python
python爬虫爬取淘宝商品比价(附淘宝反爬虫机制解决小办法)
2020/12/03 Python
全球最大的跑步用品商店:Road Runner Sports
2016/09/11 全球购物
意大利在线药房:Saninforma
2021/02/11 全球购物
内勤主管岗位职责
2014/04/03 职场文书
节能环保口号
2014/06/12 职场文书
应届生求职自荐信
2014/07/04 职场文书
火锅店的活动方案
2014/08/15 职场文书
2014年政风行风工作总结
2014/11/22 职场文书
优秀教师先进事迹材料
2014/12/15 职场文书
2015学校图书管理员工作总结
2015/05/11 职场文书
2015年妇幼卫生工作总结
2015/05/23 职场文书
无房证明样本
2015/06/17 职场文书
2016学习医德医风心得体会
2016/01/25 职场文书
写给医护人员的一封感谢信
2019/09/16 职场文书
Feign调用传输文件异常的解决
2021/06/24 Java/Android
Win11黑色桌面背景怎么办?Win11黑色壁纸解决方法汇总
2022/04/05 数码科技
《游戏王:大师决斗》新活动上线 若无符合卡组可免费租用
2022/04/13 其他游戏
苹果的回收机器人可以通过拆解iPhone获取大量的金和铜并外公布了环境保护最新进展
2022/04/21 数码科技