简单工厂模式(静态工厂模式)深入理解 完全剖析

最近在学习设计模式,对简单工厂模式工厂类中的static方法甚是不解,于是找到下面这篇博客,帮助我理解。尊重原作的创作权,链接为:http://apple277315540.blog.163.com/blog/static/4872344820096191299693/

以下是原作的内容,我记录下来仅供日后复习方便。

/*仔细阅读了一下阎宏的《java与模式》中的简单工厂模式一章,又结合网上的搜索结果,写下自己对简单工厂的理解,希望大家多多批评指正。什么是简单工厂模式呢?

 * 简单工厂模式:是类的创建模式,要叫做静态方法模式,简单产品模式是一个工厂对象决定创建出哪一种产品类的实例。

 */我们为什么要使用简答工厂模式呢,它的有优点又是什么呢?

/*简单工厂模式的优点:使用简单工厂模式的优点   实现责任的分割该模式的核心是工厂类,工厂类含有必要的选择逻辑,可以决定什么时候创建哪一个产品的实例,而客户端则免去直接创建产品的责任,而仅仅是消费产品。也就是说简单工厂模式在不改变客户端代码的情况可以动态的增加产品。(总有人对简单工厂模式增加产品后客户端代码不改变存有疑问,这里指的不改变,是指原来的消费产品的代码不必改变,您如果是要消费新的产品当然得把新的产品加上啊),也就在某种程度上满足开闭原则,但它并不完全满足开闭原则,因为没当增加新的产品时,都需要修改工厂类。所有出现了以后的工厂方法模式(工厂方法暂不介绍在后续的文章里我将继续写一下)。下面来具体看一下例子。,

*/

//本文例子是利用java的反射机制实现建造模式中的简单工厂模式 利用Class.forName来根据字符创动态的创建类。

//由于Apple  Grape 都有相同的Say()方法 但没有共同的商业逻辑 所以抽象出一个水果接口

//利用工厂类生产水果

 

//假设所有的水果都具有一个say方法 所以我们抽象出一个水果的接口

package com.xiang.staticfactory;

interface Friut {

   public void say();

}

//下面的苹果类和草莓类 都实现这个水果接口

class Apple implements Friut {

   public void say() {

      System.out.println("I am an Apple");

   }

}

 

class Grape implements Friut {

   public void say() {

      System.out.println("I am a Grape");

   }

}

 

//下面我们就开始创建工厂类了  为什么要使用工厂类呢? 因为我们要使直接的程序尽量的满足开闭原则

//根据java的反射机制我们根据客户端传过来的字符串来动态的实例化客户端消费的水果

class FriutFactory {

   public static Friut getFriut(String type) {

      Friut f = null;

      try {

        f = (Friut) Class.forName("com.xiang.staticfactory." + type)

              .newInstance();

      } catch (InstantiationException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

      } catch (IllegalAccessException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

      } catch (ClassNotFoundException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

      }

      return f;

   }

}

 

public class StaticFactory {

   public static void main(String[] args) {

      //假设传过去的是Apple

      Friut f = FriutFactory.getFriut("Apple");

      if(f!=null){

       f.say();

      }else{

        System.out.println("暂时不生产此种水果");

      }

   }

 

}

/*在网上总有人问这样的问题

 * 2.为什么工厂类中的方法必须是静态的   我如果把这个类写成下面这样

 * class FriutFactory {

   public  Friut getFriut(String type) {

      Friut f = null;

      try {

        f = (Friut) Class.forName("com.xiang.staticfactory." + type)

              .newInstance();

      } catch (InstantiationException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

      } catch (IllegalAccessException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

      } catch (ClassNotFoundException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

      }

      return f;

   }

}

    然后在主函数中这样写不可以么?

    public class StaticFactory {

   public static void main(String[] args) {

      FriutFactory f = new FriutFactory();

      Friut f = f.getFriut("Apple");

      if(f!=null){

       f.say();

      }else{

        System.out.println("暂时不生产此种水果");

      }

   }

 

}  下面咱们就来探讨一下 ,其实这样写在语法上并没有错误。但却完全没理解java面向对象设计的精髓,

 *  如果直接NewFriutFactory的对象,客户端就必须自己控制工厂类的构造和生成,客户端必须非常清楚工厂的构造函数

 *  (比如构造函数有多少个参数,输入参数时有什么条件等等),也知道工厂的内部细节,

 *  一旦工厂扩展或者改变了,客户端在没有得到通知的情况下就不知道怎么调用了。而是用静态方法构造客户端则完全不关心

 *  你是如何构造对象的所以客户端不需要了解工厂的构造细节,一旦工厂内部发生变化,客户端也不需要关心。它只需要关心最后的结果就行了,

 *  因为所有的细节都在工厂内部被处理完了。

 

 *

 */

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值