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


    简单工厂设计模式,不是标准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

        

      

  • 相关阅读:
    《Java编程思想第四版》附录 B 对比 C++和 Java
    《Java编程思想第四版》附录 C Java 编程规则
    《尚学堂_史上最易懂的设计模式视频》--章节1 责任链模式-- 过滤器模式
    《Effective Java中文版(第2版).pdf》-笔记
    javascript面试--网络收集
    眼睛问题
    网易云课堂《JS原创视频教程-知识点类》
    定时刷新页面SetInterval 和setTimeout -时间间隔可以动态设定
    MSSQL无法启动-原来电脑登录密码改了,重启后要设置
    Thymeleaf--:fragment
  • 原文地址:https://www.cnblogs.com/jiangliushibuzhuan/p/11433506.html
Copyright © 2020-2023  润新知