设计模式 -- 工厂模式_工厂设计模式csdn_赵不酷的博客-程序员秘密

技术标签: java  设计模式  

所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合。工厂是很有威力的技巧,帮助我们针对抽象编程,而不要针对具体类编程。

理论介绍
  • 工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
  • 抽象工厂模式:提供一个接口,用于创建相关或者依赖对象的家族,而不需要明确指定具体类。
应用场景
  • 工厂方法模式:可以将你的客户代码从需要实例化的具体类中解耦。或者如果你目前还不知道将来需要实例化哪些具体类时,可以选择使用。使用方法简单,只需要继承成子类,并实现他的工厂方法。
  • 抽象工厂模式:需要创建产品家族和想让制造的相关产品集合时,可以选择使用。这是通过对象的组合
代码实现参考
工厂方法模式
//PizzaStore.java
package factory_pattern.factory1;

public abstract class PizzaStore {

    //orderPizza()调用createPizza()
    public Pizza orderPizza(String type){
        Pizza pizza;
        pizza = createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }

    //把工厂对象的这个方法移到这里来
    abstract Pizza createPizza(String type);
}

将PizzaStore定义为抽象类,让每个地方具体的NYPizzaStore和ChicagoPizzaStore去继承PizzaStore。

package factory_pattern.factory1;

public class NYPizzaStore extends PizzaStore {
    @Override
    Pizza createPizza(String type) {
        if (type.equals("cheese")){
            return new NYStyleCheesePizza();
        }else if (type.equals("veggie")){
            return new NYStyleVeggiePizza();
        }else if (type.equals("clam")){
            return new NYStyleClamPizza();
        }else if (type.equals("pepperoni")){
            return new NYStylePepperoniPizza();
        }else {
            return null;
        }
    }
}

-------------------------------------------------------------------------------------
public class ChicagoPizzaStore extends PizzaStore {
    @Override
    Pizza createPizza(String type) {
        if (type.equals("cheese")){
            return new ChicagoCheesePizza();
        }else if (type.equals("veggie")){
            return new ChicagoVeggiePizza();
        }else if (type.equals("clam")){
            return new ChicagoClamPizza();
        }else if (type.equals("pepperoni")){
            return new ChicagoPepperoniPizza();
        }else {
            return null;
        }
    }
}

让每个具体的类的createPizza()创建各自风味的不同种类的Pizza。

工厂方法模式

package factory_pattern.factory1;

public class Test {
    public static void main(String[] args) {
        NYPizzaStore pizzaStore = new NYPizzaStore();
        Pizza pepperoni = pizzaStore.orderPizza("pepperoni");
        System.out.println(pepperoni.getClass().getSimpleName());

        System.out.println("---------------------------------");

        ChicagoPizzaStore chicagoPizzaStore = new ChicagoPizzaStore();
        Pizza clam = chicagoPizzaStore.orderPizza("clam");
        System.out.println(clam.getClass().getSimpleName());

    }
}

那么只需要创建一个具体的PizzaStore,在orderPizza()方法中选择口味,就可以了。
这我们就利用Pizza工厂定制了Pizza。

抽象工厂方法

抽象工厂模式与前者虽然操作不一样,但目的一致。

抽象工厂模式
这时考虑到需要建造一个原料工厂来生成原料。由于每个地区存在差异,将所有的原料抽象成一个接口。

package factory_pattern.factory2;
public interface PizzaIngredientFactory {
    public Dough createDough();
    public Sauce createSauce();
    //...other ingredient...
}

同样需要具体的工厂类实现。

package factory_pattern.factory2;

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
    @Override
    public Dough createDough() {
        return null;
    }

    @Override
    public Sauce createSauce() {
        return null;
    }
}

重做Pizza…

package factory_pattern.factory2;

public abstract class Pizza {
    Dough dough;
    Sauce sauce;
    abstract void prepare();
    void bake(){}
    void cut(){}
    void box(){}
}

package factory_pattern.factory2;

public class CheesePizza extends Pizza {
    PizzaIngredientFactory ingredientFactory;

    public CheesePizza(PizzaIngredientFactory ingredientFactory) {
        this.ingredientFactory = ingredientFactory;
    }

    @Override
    void prepare() {
        dough = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
    }
}

总结一下,我们到底做了什么。我们引入新类型的抽象工厂,来创建Pizza原料家族(集合)。通过抽象工厂所提供的接口,可以创建产品的家族,利用这个接口书写代码,我们的代码将从实际工厂解耦,以便在不同的上下文中实现各式各样的工厂,制造出不同的产品。

补充

依赖倒置原则:不能让高层组件依赖低层组件,两者都应该依赖于抽象。

祝进步
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhaohancsdn/article/details/88891794

智能推荐

day0319_pika521197的博客-程序员秘密

day0319参数形参和实参ES6中…argES5中 arguments回调函数递归函数命名函数递归通过函数名调用匿名函数递归通过匿名函数内部arguments实现重构map 之后讲原型 this 回调returnreturn解决多分支...

python删除字符串中的数字_2.5年没练习了要加油的博客-程序员秘密

educoder实训平台 python第二关删除字符串中的数字

统计了300位硬件工程师的工资,我悟了_硬件工程师2万月薪难吗_记得诚的博客-程序员秘密

大家好,我是记得诚。上周日,在公众号和自己的几个交流群,做了一个工程师薪资小调查。心想着金三银四到了,希望统计一些工程师的薪资数据,给大家的求职应聘带来一些参考,也希望一定程度上能激励到大家。共计300+工程师填写了在线表格,事实上还不止,因为在线表格是有被恶意篡改风险的,所以提前暂停了收集。这次共筛选了260份有效数据,扫码可以查看完整的数据。今天这篇文章,简单分析一下这些数据。1、统计260个工程师工作年限分布。其中1年、2年、3年、10年以上工作经验的工程师是比较多的。2、统计26

如何将字符串反转?_将一个字符串进行反转。_小黑爱上排骨的博客-程序员秘密

1.StringBuilder的reverse()方法,最简单public static String reverse4(String s) { return new StringBuffer(s).reverse().toString();}2.使用字符串数组,实现从尾部开始逐个逆序放入字符串public static String reverse3(String s) { char[] array = s.toCharArray(); String reverse = "";

JAVA 方法区是在堆里面吗_方法区在堆里面吗_akaks0的博客-程序员秘密

三种情况:1、 java7之前,方法区位于永久代(PermGen),永久代和堆相互隔离,永久代的大小在启动JVM时可以设置一个固定值,不可变;2、 java7中,static变量从永久代移到堆中;3、 java8中,取消永久代,方法存放于元空间(Metaspace),元空间仍然与堆不相连,但与堆共享物理内存,逻辑上可认为在堆中...

HBase 过滤器 (二)_第1关:常用的专用过滤器_devalone的博客-程序员秘密

继  HBase 过滤器 (一)1.3 专用过滤器 (Dedicated Filters)----HBase 提供的第二类过滤器直接基于 FilterBase 并实现了更特定的应用场景。其中的很多过滤器事实上只适用于执行扫描操作时,因为它们过滤整个行。对于 get() 调用,这些过滤器的限制过于苛刻:包括所有行,后者什么也不包括。    ■ 前缀过滤器 (PrefixFilter)...

随便推点

Failed to execute goal com.spotify:docker-maven-plugin:1.0.0:build (default-cli) on project_bug程序猿的博客-程序员秘密

项目场景:springboot项目集成docker插件进行打包问题描述:springboot项目集成docker用插件打包时报错:Failed to execute goal com.spotify:docker-maven-plugin:1.0.0:build (default-cli) on project fset-admin: Exception caught原因分析:发现是因为在docker build之前没有进行maven打包,找不到jar包所导致的解决方案:在mvn dock

任意系统升Windows10(microsoft官网)_GoldKingStar的博客-程序员秘密

打开https://www.microsoft.com/zh-cn/software-download/windows10点击“立即下载工具”下载好后点击“保留”单击“MediaCreationTool20H2.exe”如果弹出此窗口,则点击“运行”;如没有,则不管

分布式架构常见面试问题_分布式框架 面试题_雨田说码的博客-程序员秘密

Spring Cloud AlibabaNacos服务注册及健康状态如何检测?项目中如何实现服务的调用?Nacos的配置管理模型以及配置数据的获取?为什么要限流,Sentinel 限流常用算法?网关层面如何实现负载均衡以及常用算法?Docker写出几个Docker操作镜像的指令?如何理解Docker中的数据卷?Redis基于Redis如何实现一个活动的投票系统?如何理解缓存穿透和雪崩?Redis的高可用如何保证?...

硬件工程师入门和进阶_硬件工程师入门小册子 记得诚下载_记得诚的博客-程序员秘密

很多新人焦虑的点在于:硬件的知识点太多了,各种电阻元器件,特性、选型我都还不懂,绘图软件还没学会,PCB也不会画,什么时候才能做项目。焦虑是因为学习方法不对,我们不可能把所有的知识点都学好,都准备好,然后才去做项目,这也是不可能的,罗马也不是一天建成的。用自上而下的方法对项目进行分解,从硬件架构,到各功能模块,再到各功能模块下的电子元器件,再熟悉电子元器件,学会选型。第二点就是打地基,到建筑堡垒的过程,知识体系越完善,基础越牢,堡垒越稳定,出错概率越小。,更深的知识点,可以留到项目不急或者业余时间去学习。.

MyBatisPlus笔记_BigDevil_的博客-程序员秘密

文章目录学习(引)MyBatis-Plus使用1(引)MyBatis-Plus使用2参考入门demo==注意==pom 依赖application.yml 配置文件pojodaoservicecontrollerconfig(mybatisPlus分页插件)启动类学习(引)MyBatis-Plus使用1(引)MyBatis-Plus使用2参考【Springboot整合MybatisPlus(超详细)完整教程~】https://www.cnblogs.com/liuyj-top/p/12976

推荐文章

热门文章

相关标签