设计模式笔记(二):简单工厂设计模式

简单工厂设计模式,不是标准23种设计模式,但是因为它较为常用,故而放到设计模式当中来。

在了解简单工厂设计模式之前,我们来复习一下JAVA接口的知识。

一:JAVA接口

  在java中,接口是一种特殊的类,接口中的所有方法都是抽象方法(abstract),接口中的所有属性都是常量,在接口中,我们定义的是方法但没有具体实现,我们需要在写一个继承类(implements),在这个继承类里具体实现接口中的方法。

  根据接口的概念,接口通常用于来定义实现类的外观(实现类的行为定义),它的作用就是封装隔离,外部调用只能通过接口进行调用,但是却不知道内部的具体实现。

  这样使用接口,外部调用与内部实现被隔离开来,故而只要接口不变,内部实现的变化就不会影响外部的引用,那么可扩展行和维护性就会大大提升,有一句是这样说的“接口就是系统可插拔性的保证”。  

接口实现:

  //定义接口

  public interface IFire{

    public void fire();

  }

  //接口的Impl

  public class Handit implements IFire{
       public void IFire() {
              System.out.println("我是匪徒,我在开火。。。。。");
        }
  }

  //ClientTest

  public class Client  {

    public static void main(String[] args){

      IFrie  handit  =new Handit();

      handit.IFire();

  }  

   这样写的不好就是外部能知道接口,而且还知道具体实现类是Handit这样就有“封装隔离”发生了冲突,那这么办呢 我们就可以使用简单工厂来实现这个方法。

 

二: 简单工厂

 

  统一接口,选择实现

 

  简单工厂提供一个创建对象实例的功能,被创建实例的类型可以使接口、抽象类、具体类。

  简单工厂按我的意思就是在原有的接口基础上,创建一个工厂,用来创建接口对象。

  具体代码如下:

  //定义接口

  public interface IFire{

 

    public void fire();

 

  }

 

  //接口的Impl

 

  public class Handit implements IFire{
       public void IFire() {
              System.out.println("我是匪徒,我在开火。。。。。");
        }
  }

  //创建一个工厂

  public class  CSFactory {

    public static IFire getInstance(int number){

       if(number == 1){

         return new Handit();      

       }else{

         return null;

         }

    }  

  }

  //ClientTest

  public class Client  {

 

    public static void main(String[] args){

 

      IFrie  handit  =CSFactory.getInstacne(1);

 

      handit.IFire();

 

  }

  我们把实现类 HanditImpl ()放到CSFactory 中,而CSFactory是位于封装内部的,简单工厂和实现类就在一起了 ,而外部即使知道了  简单工厂CSFactory,但是却不知道是那个具体实现类,那么就解决了刚才的问题。

  

  简单工厂的优缺点:

  优点:(1)封装隔离,将具体实现类封装起来,不让外部方法知道。

     (2)解耦,通过简单工厂实现了客户端和具体实现类的解耦;外部根本不知道具体是由谁来实现的,也不知道如何实现,外       部只知道是通过工厂获取的。

  缺点:(1)增加外部调用的而复杂度,外部想调用就必须知道number代表各个值都对应的方法,这样既对外部增减使用难度,而且         也暴露了内部参数。

     (2)不方便扩展

  那么我们怎么解决这个缺点呢

  解决办法:利用java反射机制创建

    我用一个简单案例来体现这个方法;

    小时候玩的CS,里面有保卫者和突袭者,它们有个共同的功能开火;

    这样,我们先定义一个接口开火IFire(),它的两个实现分别是保卫者Police()和突袭者Handit(),有一工厂就叫做CSFactory(),那么我    们用反射机制的原理来做。

  代码如下:

  //接口IFire()

  public interface IFire {

          public void IFire();
  }
  //简单工厂CSFactory()

  public class CSFactory {
    
      private static Properties prop = null;
      private static InputStream is = null;
    
      //初始化放在静态块中
      static {
          prop = new Properties();
          is = CSFactory.class.getResourceAsStream("impls.properties");
          try {
                prop.load(is);
            } catch (IOException e) {
               e.printStackTrace();
            }
       }
      public static IFire  getInstance(String name) {
          IFire  obj = null;
          try {
              obj=(IFire)Class.forName(prop.getProperty(name)).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 obj;
      }   
  }

  //突袭者&保卫者

  public class Handit implements IFire{

      @Override
      public void IFire() {
          // TODO Auto-generated method stub
          System.out.println("我是匪徒,我在挨揍。。。。。");

    }
  }
  public class PoliceMan implements IFire{

      @Override
      public void IFire() {
          // TODO Auto-generated method stub
         System.out.println("我是保卫者,我开火:嘟嘟嘟嘟嘟嘟");

     }

  }

  //ClientDemo 
  public class ClientDemo {

      public static void main(String[] args) {
          IFire handit= CSFactory.getInstance("handit");
          IFire policeMan= CSFactory.getInstance("policeMan");
          handit.IFire();
          policeMan.IFire();    
        
      }
  }
    //impls.properties

    

 

  

 

 

posted @ 2019-08-31 12:00  江流石不转  阅读(129)  评论(0编辑  收藏  举报