精华内容
下载资源
问答
  • 本文目录一、什么是静态工厂方法?二、静态工厂方法的优势三、静态工厂方法的缺点四、总结 一、什么是静态工厂方法? 对于类而言,在我们需要获取一个实例时,最传统的方法都是通过new新建一个对象,这是jvm通过调用...
  • 主要介绍了Java设计模式之静态工厂模式,简单说明了静态工厂模式的概念、原理、实现与使用方法,需要的朋友可以参考下
  • 主要介绍了 Java静态工厂方法的实例详解的相关资料,希望通过本文大家能掌握java今天工厂方法,需要的朋友可以参考下
  • 主要介绍了Spring实战之使用静态工厂方法创建Bean操作,结合实例形式分析了静态工厂方法创建Bean的相关实现步骤与操作注意事项,需要的朋友可以参考下
  • 静态工厂

    2016-12-20 10:17:36
    简单工厂模式解释: 简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有...
    package com.hgh.effectivejava.staticfactory2;
    
    
    //service interface.1服务接口,这是提供者实现的
    public interface Service {
    
    }
    
    package com.hgh.effectivejava.staticfactory2;
    
    //service provider interface.4,服务者提供接口,这些提供者负责创建其服务实现的实例
    public interface Provider {
    
        Service newService();
    }
    
    package com.hgh.effectivejava.staticfactory2;
    
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    public class Services {
         private Services(){
         }
    
         private static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>();
    
         public static final String DEFAULT_PROVIDER_NAME = "<def>";
    
         //provider registration API 2.提供者注册API 这是系统用来注册实现的,让客户端访问他们的
         public static void registerDefaultProvider(Provider p){
             providers.put(DEFAULT_PROVIDER_NAME, p);
         }
         public static void registerProvider(String name , Provider p){
             providers.put(name, p);
         }
    
         //service access API 服务访问API,3,是客户端用来获取服务的实例的.
         public static Service newInstance(){
             return newInstance(DEFAULT_PROVIDER_NAME);
         }
    
         public static Service newInstance(String name){
             Provider p = providers.get(name);
             if (null == p) {
    
            }
            return p.newService();
         }
    
    }
    
    以下是转载内容
    

    简单工厂模式解释: 

           简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

    简单工厂模式的UML图: 

           简单工厂模式中包含的角色及其相应的职责如下:

           工厂角色(Creator):这是简单工厂模式的核心,由它负责创建所有的类的内部逻辑。当然工厂类必须能够被外界调用,创建所需要的产品对象。

           抽象(Product)产品角色:简单工厂模式所创建的所有对象的父类,注意,这里的父类可以是接口也可以是抽象类,它负责描述所有实例所共有的公共接口。

           具体产品(Concrete Product)角色:简单工厂所创建的具体实例对象,这些具体的产品往往都拥有共同的父类。

    简单工厂模式深入分析

           简单工厂模式解决的问题是如何去实例化一个合适的对象。

           简单工厂模式的核心思想就是:有一个专门的类来负责创建实例的过程。

           具体来说,把产品看着是一系列的类的集合,这些类是由某个抽象类或者接口派生出来的一个对象树。而工厂类用来产生一个合适的对象来满足客户的要求。

           如果简单工厂模式所涉及到的具体产品之间没有共同的逻辑,那么我们就可以使用接口来扮演抽象产品的角色;如果具体产品之间有功能的逻辑或,我们就必须把这些共同的东西提取出来,放在一个抽象类中,然后让具体产品继承抽象类。为实现更好复用的目的,共同的东西总是应该抽象出来的。

           在实际的的使用中,抽闲产品和具体产品之间往往是多层次的产品结构,如下图所示:

    简单工厂模式使用场景分析及代码实现: 

           GG请自己的女朋友和众多美女吃饭,但是GG自己是不会做饭的或者做的饭很不好,这说明GG不用自己去创建各种食物的对象;各个美女都有各自的爱好,到麦当劳后她们喜欢吃什么直接去点就行了,麦当劳就是生产各种食物的工厂,这时候GG不用自己动手,也可以请这么多美女吃饭,所要做的就是买单O(∩_∩)O哈哈~,其UML图如下所示:

           实现代码如下:

           新建立一个食物的接口:

    package com.diermeng.designPattern.SimpleFactory;

     

    /*

     * 产品的抽象接口

     */

    public interface Food {

        /*

         * 获得相应的食物

         */

        public void get();

    }

    接下来建立具体的产品:麦香鸡和薯条

    package com.diermeng.designPattern.SimpleFactory.impl;

    import com.diermeng.designPattern.SimpleFactory.Food;

     

    /*

     * 麦香鸡对抽象产品接口的实现

     */

    public class McChicken implements Food{

        /*

         * 获取一份麦香鸡

         */

        public void get(){

            System.out.println(“我要一份麦香鸡”);

        }

    }

    package com.diermeng.designPattern.SimpleFactory.impl;

    import com.diermeng.designPattern.SimpleFactory.Food;

     

    /*

     * 薯条对抽象产品接口的实现

     */

    public class Chips implements Food{

        /*

         * 获取一份薯条

         */

        public void get(){

            System.out.println(“我要一份薯条”);

        }

    }

    现在建立一个食物加工工厂:

    package com.diermeng.designPattern.SimpleFactory.impl;

    import com.diermeng.designPattern.SimpleFactory.Food;

     

     

    public class FoodFactory {

     

        public static Food getFood(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException {

            if(type.equalsIgnoreCase(“mcchicken”)) {

                return McChicken.class.newInstance();

     

            } else if(type.equalsIgnoreCase(“chips”)) {

                return Chips.class.newInstance();

            } else {

                System.out.println(“哎呀!找不到相应的实例化类啦!”);

                return null;

            }

     

     

        }

    }

    最后我们建立测试客户端:

    package com.diermeng.designPattern.SimpleFactory.client;

    import com.diermeng.designPattern.SimpleFactory.Food;

    import com.diermeng.designPattern.SimpleFactory.impl.FoodFactory;

     

    /*

     * 测试客户端

     */

    public class SimpleFactoryTest {

        public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {

     

            //实例化各种食物

            Food mcChicken = FoodFactory.getFood(“McChicken”);

            Food chips = FoodFactory.getFood(“Chips”);

            Food eggs = FoodFactory.getFood(“Eggs”);

     

            //获取食物

            if(mcChicken!=null){

                mcChicken.get();

            }

            if(chips!=null){

                chips.get();

            }

            if(eggs!=null){

                eggs.get();

            }

     

     

        }

    }

    输出的结果如下:

    哎呀!找不到相应的实例化类啦!

    我要一份麦香鸡

    我要一份薯条

    简单工厂模式的优缺点分析: 

           优点:工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。

          缺点:由于工厂类集中了所有实例的创建逻辑,这就直接导致一旦这个工厂出了问题,所有的客户端都会受到牵连;而且由于简单工厂模式的产品室基于一个共同的抽象类或者接口,这样一来,但产品的种类增加的时候,即有不同的产品接口或者抽象类的时候,工厂类就需要判断何时创建何种种类的产品,这就和创建何种种类产品的产品相互混淆在了一起,违背了单一职责,导致系统丧失灵活性和可维护性。而且更重要的是,简单工厂模式违背了“开放封闭原则”,就是违背了“系统对扩展开放,对修改关闭”的原则,因为当我新增加一个产品的时候必须修改工厂类,相应的工厂类就需要重新编译一遍。

          总结一下:简单工厂模式分离产品的创建者和消费者,有利于软件系统结构的优化;但是由于一切逻辑都集中在一个工厂类中,导致了没有很高的内聚性,同时也违背了“开放封闭原则”。另外,简单工厂模式的方法一般都是静态的,而静态工厂方法是无法让子类继承的,因此,简单工厂模式无法形成基于基类的继承树结构。

    简单工厂模式的实际应用简介: 

           作为一个最基本和最简单的设计模式,简单工厂模式却有很非常广泛的应用,我们这里以Java中的JDBC操作数据库为例来说明。

            JDBC是SUN公司提供的一套数据库编程接口API,它利用Java语言提供简单、一致的方式来访问各种关系型数据库。Java程序通过JDBC可以执行SQL语句,对获取的数据进行处理,并将变化了的数据存回数据库,因此,JDBC是Java应用程序与各种关系数据进行对话的一种机制。用JDBC进行数据库访问时,要使用数据库厂商提供的驱动程序接口与数据库管理系统进行数据交互。

    客户端要使用使用数据时,只需要和工厂进行交互即可,这就导致操作步骤得到极大的简化,操作步骤按照顺序依次为:注册并加载数据库驱动,一般使用Class.forName();创建与数据库的链接Connection对象;创建SQL语句对象preparedStatement(sql);提交SQL语句,根据实际情况使用executeQuery()或者executeUpdate();显示相应的结果;关闭数据库。

    展开全文
  • 主要介绍了Spring的实例工厂方法和静态工厂方法实例代码,具有一定借鉴价值,需要的朋友可以参考下
  • Spring依赖注入使用静态工厂设注入demo。完整可运行。
  • Effective Java学习:静态工厂方法

    多人点赞 2019-04-30 17:29:25
    静态工厂方法 静态工厂方法是什么?直接从字面应该就很好理解: 工厂方法:大家应该都知道,就是构建实例的方法呗。(比如:“江南皮革厂”就是创建“皮包”这个对象的工厂) 静态方法:这还有解释的必要么..........

    最近在啃《Effective Java》这本神书。简单记录一下,方便以后温习。

    静态工厂方法

    静态工厂方法是什么?直接从字面应该就很好理解:

    工厂方法:大家应该都知道,就是构建实例的方法呗。(比如:“江南皮革厂”就是创建“皮包”这个对象的工厂)

    静态方法:这还有解释的必要么.......

    合起来就是静态的构建对象的方法呗。。哦了,这就是静态工厂方法。本文到此结束,感谢大家观看!

    哈哈,开个玩笑。 虽然静态工厂方法是什么很好理解。可是静态工厂方法到底有什么用呢,我们又为什么要用它呢?


    一般情况下,java中我们创建对象要写一个公有的构造函数,外部调用构造函数来创建一个对象。静态工厂方法就是与它相对应的。代码分别如下:

    class People {
    
        private String sex = "男";
        private String appearance = "一般";
        private String asset = "穷";//原则上来讲,默认数据要符合普遍情况。
    
        //普通构造函数--无参
        public People() {
        }
    
        //普通构造函数--有参
        public People(String sex) {
            this.sex = sex;
        }
    
        public People(String sex, String appearance) {
            this.sex = sex;
            this.appearance = appearance;
        }
    
        public People(String sex, String appearance, String asset) {
            this.sex = sex;
            this.appearance = appearance;
            this.asset = asset;
        }
    
        //静态工厂方法
        public static People createGirlfriend() {//程序员的基本操作,new一个女朋友。
            People people = new People();
            people.sex = "女";
            people.appearance = "倾国倾城";
            people.asset = "市中心十栋楼";
            return people;
        }
    
    }

    上面就是一个简单的静态工厂方法,其实本质上就是加了一层封装。有了这层封装自己可以操作和控制很多东西。

    下面看看两者的区别:

     

    1.静态工厂方法的优点

    1.1 静态工厂方法是有名称的

    我们在java中应该经常看到类似这种构造函数:

    class People {
    
        private String sex = "男";
        private String appearance = "一般";
        private String asset = "穷";
    
        //普通构造函数--无参
        public People() {
        }
    
        //普通构造函数--有参
        public People(String sex) {
            this.sex = sex;
        }
    
        public People(String sex, String appearance) {
            this.sex = sex;
            this.appearance = appearance;
        }
    
        public People(String sex, String appearance, String asset) {
            this.sex = sex;
            this.appearance = appearance;
            this.asset = asset;
        }
    
    }

    当然,官方文档的注释还是很完善和规范的。我们可以看到每个构造函数的用处和每个参数的作用。可是如果在多点参数呢,又如果是自己写方法呢。(有时候懒再少些两行注释~~后期维护两行泪~) 调用的时候是不是就会一脸懵逼?我该调用哪个?这个参数是什么?要传什么值?况且每次构建对象的时候都要点进去看注释也挺麻烦的。

    为了解决上述问题,我们可以使用静态工厂方法。因为静态工厂方法是可以有名字的,这样构建对象时就非常直观。比如文章开始的第一个demo。通过静态工厂方法createGirlfriend()方法可以直接创建一个“People”的实例,同时我们可以直接从方法名看出我们创建出来的“people”实例是“女朋友”。是不是很方便易懂呢~~

     

    1.2 静态工厂方法可以不必在每次调用他们的时候都创建一个新对象

    这个应该很好理解,因为静态工厂方法是多一层封装的。所以在这里面我们可以自由控制返回的对象,可以全局只使用一个对象(单例)或者控制什么时候创建新的实例,什么时候使用缓存的实例。代码如下:

    class People {
    
        private String sex = "男";
        private String appearance = "一般";
        private String asset = "穷";
    
        //静态工厂方法
        public static People createGirlfriend() {
            People people = new People();//这里是我们可控制的,所以你可以选择new新的对象或者使用缓存的已创建的对象
            people.sex = "女";
            people.appearance = "倾国倾城";
            people.asset = "市中心十栋楼";
            return people;
        }
    
    }

     

    1.3 静态工厂方法可以返回原返回类型的任何子类型

    这一点也好理解,先看代码:

    class People {
    
        //静态工厂方法
        public static People createChildren() {
            Children people = new Children();
            return people;
        }
    
    }
    
    //People的子类
    class Children extends People {
        public Children() {
        }
    }

    这个很好理解了,Children是People的子类。所以在静态工厂方法中可以直接返回Children的实例。

    不过这里我们不得不提一下设计原则--里式替换原则:任何基类可以出现的地方,子类一定可以出现。 --百度百科

    最通俗的讲,就是我们在写子类的时候要注意:可以拓展父类功能和属性,但是不能修改。(也就是对扩展开放,对修改关闭)

     

    1.4 静态工厂方法返回的对象的类可以随着每次调用而发生改变,这取决于所传参数值

    理解:静态工厂方法可以根据参数不同返回不同的子类对象。代码如下:

    class People {
    
        /**
         * @param timeForSingle 单身时长
         * @return 对象
         */
        public static People createGirlfriend(int timeForSingle) {
            if (timeForSingle < 5) {//根据所传参数,返回不同的子类对象。
                EighteenBeauty eighteenBeauty = new EighteenBeauty();
                return eighteenBeauty;
            } else {//单身超过五年,看男生都感觉很清秀了呢~~
                Man man = new Man();
                return man;
            }
        }
    
    }
    
    //18岁年轻漂亮的小姑娘
    class EighteenBeauty extends People {
        public EighteenBeauty() {
        }
    }
    
    //男人
    class Man extends People {
        public Man() {
        }
    }

    OK,看代码就很好理解了。根据所传递参数不同返回了不同的子类对象。

     

    1.5 静态工厂方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在(该篇唯一难点)

    重头戏到了,这是本篇唯一难点。这个概念理解起来倒是很简单:静态工厂方法返回对象所属的类,在编写包含该静态工厂方法时可以不存在。(好像是把概念又抄了一遍,不过单从字面实在没什么可解释的了~~)。

    不过重点在于,怎么实现呢?

    这里直接从 这种静态工厂方法最典型的实现--服务提供者框架 来探讨。

    服务提供者框架包含四大组件:(概念不太好理解,可以直接先看下面的例子讲解,然后回过头来再看概念)

    1. 服务接口:这是服务提供者要去实现的接口
    2. 服务提供者接口:生成服务接口实例的工厂对象(就是用来生成服务接口的)(可选)
    3. 提供者注册API:服务者 提供服务者自身的实现
    4. 服务访问API:根据客户端指定的某种条件去实现对应的服务提供者

    概念太拗口,上栗子讲解:

    //四大组成之一:服务接口
    public interface LoginService {//这是一个登录服务
        public void login();
    }
    
    //四大组成之二:服务提供者接口
    public interface Provider {//登录服务的提供者。通俗点说就是:通过这个newLoginService()可以获得一个服务。
        public LoginService newLoginService();
    }
    
    /**
     * 这是一个服务管理器,里面包含了四大组成中的三和四
     * 解释:通过注册将 服务提供者 加入map,然后通过一个静态工厂方法 getService(String name) 返回不同的服务。
     */
    public class ServiceManager {
        private static final Map<String, Provider> providers = new HashMap<String, Provider>();//map,保存了注册的服务
    
        private ServiceManager() {
        }
    
        //四大组成之三:提供者注册API  (其实很简单,就是注册一下服务提供者)
        public static void registerProvider(String name, Provider provider) {
            providers.put(name, provider);
        }
    
        //四大组成之四:服务访问API   (客户端只需要传递一个name参数,系统会去匹配服务提供者,然后提供服务)  (静态工厂方法)
        public static LoginService getService(String name) {
            Provider provider = providers.get(name);
            if (provider == null) {
                throw new IllegalArgumentException("No provider registered with name=" + name);
    
            }
            return provider.newLoginService();
        }
    }

    OK,代码中注释的很清楚了。

    思考下,这么做有什么好处呢??重点看一下上面demo中的 “四大组成之四:服务访问API ”


    想一想,是不是以后想要增加服务时只需要实现服务提供者接口、服务接口,然后约定一个服务名就可以了?

     

    2.静态工厂方法的缺点

    2.1 如果类不含公有的或者受保护的构造器时,就是能被子类化

    如果类的构造方法是私有的,那么这个类就不能被继承了。这时候建议用复合代替继承实现类的拓展。

     

    2.2 静态工厂方法实际上就是静态方法,如果命名不规范的话程序员很难发现他们

    这时候就需要我们自我约束了,利用静态工厂方法时一定要遵循命名规范,下面是一些常用的静态工厂方法命名:

    1. from    类型转换方法,它只有单个参数,返回该类型的一个实例,并把它们合并起来。
    2. of    聚合方法,带有多个参数,返回该类型的一个实例,把他们合并起来。
    3. valueOf    比from和of更繁琐的一种替代方法。
    4. instance或者getInstance    返回的实例是通过方法的(如有)参数来描述的,但是不能说与参数具有同样的值。
    5. create或者newInstance    像instance或者getInstance一样,但create或者newInstance能够确保每次调用都返回一个新的实例
    6. getType    像getInstance一样,但是在工厂方法处于不同的类中的时候使用。Type表示工厂方法所返回的对象类型。
    7. newType    像getInstance一样,但是在工厂方法处于不同的类中的时候使用。
    8. type    getType和newType的精简版。

     

    展开全文
  • 静态工厂模式:用来生产同一等级结构中的任意产品(对于增加新的产品,需要覆盖已有的代码),又叫简单工厂模式 工厂方法模式:用来生产统一等级结构中的固定产品(支持增加的任意产品) 抽象工厂模式:围绕一个...

    1.简介

    工厂模式作用:实现了创建者和调用者的分离
    详细分类:

    1. 静态工厂模式:用来生产同一等级结构中的任意产品(对于增加新的产品,需要覆盖已有的代码),又叫简单工厂模式

    2. 工厂方法模式:用来生产统一等级结构中的固定产品(支持增加的任意产品)

    3. 抽象工厂模式:围绕一个禅机共产创建其他工厂,该超级工厂又称为其他工厂的工厂(工厂的工厂)。

    核心本质
    实例化对象不使用new,用工厂方法代替。
    将选择实现类,创建对象统一管理和控制,从而将调用者跟我们的实现类解耦。
    应用场景
    JDK中Calendar的getInstance方法
    JDBC中的Connection对象的获取
    Spring中IOC容器创建管理bean对象
    反射中Class对象的newInstance方法

    2.静态工厂模式

    /**
     * 静态工厂模式(简单工厂模式)
     * 大多数情况下都使用这种模式
     * 缺点:不满足开闭原则,每次增加一种类型,都需要在这里修改代码
     * 但是开闭原则需要付出比较大的代价
     */
    public class CarFactory {
        //方法一
        public static Car getCar(String car){
            if(car.equals("小黄单车")){
                return new XiaoHuang();
            }else if (car.equals("小红单车")){
                return new XiaoHong();
            }else if (car.equals("小蓝单车")){
                return new XiaoLan();
            }else{
                return null;
            }
        }
    
        //方法二(将每一种车都自己创建一个方法)
        public static Car getXiaoHong(){
            return new XiaoHong();
        }
        public static Car getXiaoLan(){
            return new XiaoLan();
        }
        public static Car getXiaoHuang(){
            return new XiaoHuang();
        }
    }
    
    //顾客
    public class Consumer  {
        public static void main(String[] args) {
        /*传统方法
            XiaoHong xh = new XiaoHong();
            xh.car();
            XiaoHuang xiaoHuang = new XiaoHuang();
            xiaoHuang.car();
        */
            
        /*  方法一
            Car c1 = CarFactory.getCar("小蓝单车");
            Car c2 = CarFactory.getCar("小红单车");
        */
      
        //方法二:
            Car c1 = CarFactory.getXiaoHong();
            Car c2 = CarFactory.getXiaoLan();
    
            c1.car();
            c2.car();
    
        }
    }
    //car接口
    public interface Car {
        void car();
    }
    //每一种车型
    public class XiaoLan implements Car {
        @Override
        public void car() {
            System.out.println("小蓝单车");
        }
    }
    

    在这里插入图片描述

    3.工厂方法模式

    /**
     * 工厂方法模式:需要哪个车就去哪个车的工厂去取
     * 优点:不修改已有代码的前提下,通过增加新的工厂类实现扩展
     * 缺点:类太多,比起简单工厂模式来说,虽然实现了开闭原则,但是很麻烦。
     */
    //工厂接口
    public interface CarFactory{
        Car getCar();
    }
    //每个车的工厂-小蓝车厂
    public XiaoLanFactory implements CarFactory{
        @Override
        public Car getCar() {
            return new XiaoLan();
        }
    }
    //每个车的工厂-小红车厂
    public class HongFactory implements CarFactory {
    
        @Override
        public Car getCar() {
            return new XiaoHong();
        }
    }
    //车接口
    public interface Car {
        void car();
    }
    //车产品-小蓝车
    public class XiaoLan implements Car {
        @Override
        public void car() {
            System.out.println("小蓝单车");
        }
    }
    //车产品-小红车
    public class XiaoHong implements Car {
        @Override public void car() {
            System.out.println("小红单车");
        }
    }
    //顾客
    public class Consumer  {
        public static void main(String[] args) {
    
            //需要什么车,就去哪个车的工厂
            Car c1 = new LanFactory().getCar();
            Car c2 = new HongFactory().getCar();
    
            c1.car();
            c2.car();
    
        }
    }
    

    在这里插入图片描述

    4.小结:

    通过以下方面对比:
    结构复杂度:选 静态工厂模式
    代码复杂度:选 静态工厂模式
    编程复杂度:选 静态工厂模式
    管理上的复杂度:选 静态工厂模式

    根据设计原则:选 工厂方法模式
    根据实际业务:选 静态工厂模式

    综上:
    静态工厂模式:虽然某种程度上不符合设计原则,但实际使用最多。
    工厂方法模式:不修改已有类的前提下,通过增加新的工厂类实现扩展。

    ( 简单提一下抽象工厂模式。)
    抽象工厂模式:不可以增加产品,可以增加产品族。

    展开全文
  • Java 设计模式之静态工厂方法模式

    千次阅读 2019-09-16 17:12:12
    静态工厂方法模式,又称为简单工厂模式,是最简单最易理解的工厂模式,本文通过一个 “月饼” 例子,一起来学习下这种设计模式吧!

    设计模式系列

    创建型设计模式

    Java 设计模式之单例模式

    Java 设计模式之静态工厂方法模式

    Java 设计模式之工厂方法模式

    Java 设计模式之抽象工厂模式

    Java 设计模式之Builder模式

    Java 设计模式之静态工厂、工厂方法、抽象工厂和 Builder 模式的区别

    结构型设计模式

    Java 设计模式之代理模式

    Java 设计模式之外观模式

    写在前面


    先来一个迟到的祝福,祝大家中秋节快乐!应个景吧,工厂模式系列的例子和代码,将以 “月饼” 为主题进行。

    工厂模式细分起来,分为三种:静态工厂方法模式、工厂方法模式、抽象工厂方法模式。本文我们先来了解最简单的静态工厂方法模式。

    定义


    静态工厂方法模式,又称为 简单工厂模式,属于创建型设计模式,但不属于 GOF 提出的 23 种设计模式之一。这种形式的工厂模式,是最常用,也最简单、最容易理解的工厂模式,其是由一个工厂类对象决定创建哪一种产品类的实例

    示例


    场景

    来我们来考虑一个场景:
    1、小A有一家月饼工厂,叫做 MooncakesFactory
    2、月饼有 五仁月饼 FiveKernel 、豆沙月饼 Beansand
    3、我们抽象出月饼的产品抽象类 Mooncakes ,拥有“吃”的行为(当然,应该是人吃月饼,而不是月饼吃自己,这里为了好理解,就将吃的行为赋给了月饼)。
    4、当想要某种类型的月饼时,通过工厂类得到相应的月饼类即可进行生产

    UML类图

    让我来看下它们的 UML 类图吧,如图 1 :
    静态工厂方法模式示例的 UML 类图

    图 1    静态工厂方法模式 示例的 UML 类图

    程序代码

    下面我们阅读下程序代码。


    程序清单 1     月饼的产品抽象类 Mooncakes
    public abstract class Mooncakes{
        abstract void eat();
    }
    

    可以看到,抽象类 Mooncakes 简单的抽象了一种行为,就是吃月饼 eat()



    程序清单 2     五仁月饼 实现类 FiveKernel
    public class FiveKernel extends Mooncakes{
    
        @Override
        public void eat() {
            System.out.println("吃一个五仁月饼");
        }
    
    }
    



    程序清单 3     豆沙月饼 实现类 Beansand
    public class Beansand extends Mooncakes{
    
        @Override
        public void eat() {
            System.out.println("吃一个豆沙月饼");
        }
    
    }
    




    下面我们来看下工厂类的代码:

    程序清单 4     月饼工厂类 MooncakesFactory
    public class MooncakesFactory {
    
        public static Mooncakes makeMooncakes(String type) {
            Mooncakes mooncakes = null;
            switch (type) {
            case "FiveKernel":
                mooncakes = new FiveKernel();
                break;
            case "Beansand":
                mooncakes = new Beansand();
                break;
            }
            return mooncakes;
        }
    
    }
    

    当想要某种类型的月饼时,通过工厂类得到相应的月饼类,即可开始生产。

    这就通过工厂,实现了对产品类实例的管理。

    那么,如果有了一种的新的月饼类型,比如蛋黄月饼,那么我们需要扩展一个新类 Yolk 继承抽象产品类 Mooncakes,同时还需要对工厂类 MooncakesFactory 进行修改,以便适应新的月饼类型(int type)。

    我们知道,我们的程序应该“ 面向扩展开放,面向修改关闭 ”,我们对工厂类的修改自然是不符合" 开闭原则 " 的,让我们用反射对工厂类进行优化吧:


    程序清单 5     用反射优化月饼工厂类 MooncakesFactory
    public class MooncakesFactory {
    
        public static <T extends Mooncakes> T makeMooncakes(Class<T> clz) {
            Mooncakes mooncakes = null;
            try {
                mooncakes = (Mooncakes) Class.forName(clz.getName()).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return (T) mooncakes;
        }
    
    }
    

    这样,无论我们扩展多少种月饼类型,只需要将相应的月饼类注入工厂的 makeMooncakes() 方法即可,不需要再对工厂类的代码进行修改。

    最后,我们在主函数中调用工厂得到月饼类的实例,即可开始生产。


    程序清单 6     工厂生产产品实例  进行产品生产
    public class Main {
        
        public static void main(String[] args) {
    
            MooncakesFactory.makeMooncakes(FiveKernel.class).eat();
            MooncakesFactory.makeMooncakes(Beansand.class).eat();
    
        }
    
    }
    

    结果示例,如图 2 :

    生产月饼,吃掉月饼

    图 2    生产月饼  吃掉月饼

    总结


    至此,静态工厂方法模式基本就聊完了。

    大家会发现,这种模式十分简单,优点也是十分明显:

    用户只需要关心自己想要什么类型的产品对象,而对产品对象的创建过程无须关心,全部交给工厂来做,降低了用户与产品类的耦合,也便于对产品的类型进行扩展。

    然而,正如前文所说,“ 静态工厂方法模式 ” 不属于 GOF 提出的 23 种设计模式之一,“ 工厂方法模式 ” 则包含其中,让我们移步下一讲,一起学习下 Java 设计模式之工厂方法模式 吧!

    另外,源码也有放在 Gihub 上:StaticFactoryPattern

    感谢

    • 《Android源码设计模式解析与实战》 何红辉 关爱民
    • 《Android进阶之光》 刘望舒
    展开全文
  • JavaEE spring静态工厂创建实例
  • Spring 动态工厂和静态工厂区别

    千次阅读 2020-04-01 16:54:02
    Spring 动态工厂和静态工厂区别 用过 Spring 系列的各位大牛应该都知道,这东西真香! 但最近在学习整理Spring 全家桶的东西时,发现 Spring 的 Ioc(不懂去百度,我相信你搜到这篇废话不会不懂 Ioc 的) 一个小东西...
  • 初步接触设计模式,初步了解静态工厂方法,了解还不全面,我们先一步步了解一下。 一、背景介绍 工厂模式是设计模式的一种,设计模式是自程序开发逐渐就有的,提高开发效率的一种设计思路,先前的开发者们一直在...
  • 什么是静态工厂方法 对于类而言,为了让使用者获取它自身的一个实例,最常用的方法就是提供一个公有的构造器。 当然,这里要介绍的是另一种方法——静态工厂方法,一个返回类的实例的静态方法。 举个例子,Boolean...
  • Bean的装配之动态工厂方式 (1) 如何理解Bean的装配? Bean的装配即bean(类对象)的装配 (2) 动态工厂方式创建Bean的步骤有哪些? ① 注册工厂 <!--使用Factory动态工厂创建对象 --> <bean id=...
  • java的静态工厂方法

    2019-11-19 20:41:03
    1.什么是静态工厂方法 类可以提供一个共有的静态工厂方法(static factory method),它只是一个放回类的实例的静态方法。 下面是一个来自Boolean(基本类型boolean的装箱类)的简单实例。 /** 将boolean基本类型转换...
  • 这三种方式分别为:使用静态工厂创建对象,使用实例工厂创建对象,使用无参构造函数创建对象。 工厂模式:工厂提供服务(方法),客户只需要满足服务的条件即可,解耦很明显,这里自己的责任自己负责,每一环没有...
  • 静态工厂方法模式

    2020-10-23 09:36:56
    静态工厂方法模式 今天我们来聊一聊静态工厂方法模式。 (这是我在实验室做完实验后无聊写的,可能会有遗漏和不足,敬请见谅!) 首先我们来看下面这道题目: 参照以下UML类图片段,并使用JAVA语言及静态工厂方法...
  • 静态工厂方法

    千次阅读 2019-02-18 23:04:50
    静态工厂方法(factory method) 定义:在 Java 中,获得一个类实例最简单的方法就是使用 new 关键字,通过构造函数来实现对象的创建。 例: Fragment fragment = new MyFragment(); // or Date date = new Date(); ...
  • 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单...
  • 在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法(Static Factory Method) 需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无需知道其实现过程 ...
  • 什么是静态工厂方法

    2020-05-11 09:14:25
    什么是静态工厂方法 在 Java 中,获得一个类实例最简单的方法就是使用 new 关键字,通过构造函数来实现对象的创建。 就像这样: Fragment fragment = new MyFragment(); // or Date date = new Date(); 不过在实际...
  • 静态工厂注入 当无法使用构造方法进行注入,此时可以使用静态工厂进行注入 配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi...
  • 静态工厂方法缺点 静态工厂方法的主要缺点在于,类如果不含有公有的或者受保护的构造器,就不能被子类化。对于公有的静态工厂所返回的非公有类,也同样如此。例如,要想将CollectionsFramework中的任何方便的实现类...
  • 前面几篇文章,我们学习了几种工厂模式和 Builder 模式,都可以用来得到产品对象,那他们有什么区别呢?我们该怎么选择呢?
  • 静态工厂方法和实例工厂方法区别

    千次阅读 2019-12-26 17:55:13
    在学习Spring bean的实例化方式的时候遇到的一个问题,Spring bean实例化有3种方法 1、构造器生成 2、静态工厂方法 3、实例工厂方法 那么问题来了,什么是静态工厂方法,什么是实例工厂方法? 1、静态工厂方法 就是...
  • 什么是静态工厂方法 静态工厂方法比构造器好在哪里 静态工厂方法有名称而构造器没有(前者可读性更好) 不必每次调用它们的时候都创建一个新对象 可以返回原返回类型的任何子类对象 创建泛型对象可以更加简洁 静态...
  • 主要介绍了C#的静态工厂方法与构造函数对比的优缺点,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 168,559
精华内容 67,423
关键字:

静态工厂