• 三:java设计模式之工厂模式


    一、工厂模式的作用,为什么要用工厂模式?

    a.工厂模式是为了解耦:把对象的创建和使用的过程分开。就是Class A 想调用Class B,那么只是调用B的方法,而至于B的实例化,就交给工厂类。

    b.工厂模式可以降低代码重复。如果创建B过程都很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。可以把这些创建对象B的代码放到工厂里统一管理。既减少了重复代码,也方便以后对B的维护。

    c.工厂模式可以减少错误,因为工厂管理了对象的创建逻辑,使用者不需要知道具体的创建过程,只管使用即可,减少了使用者因为创建逻辑导致的错误。

    二、工厂模式的一些适用场景。

     对象的创建过程/实例化准备工作很复杂,需要很多初始化参数,查询数据库等。

    类本身有好多子类,这些类的创建过程在业务中容易发生改变,或者对类的调用容易发生改变。

    三、简单工厂模式。

    创建一个工厂类,在类中通过传入的参数不同创建不同的实体类。有新需求时需要更改工厂类中的代码,违背了开闭原则。

    //创建抽象产品类 ,定义具体产品的公共接口;
    interface ICourse {
        /**
         * 录制视频
         * @return
         */
        void record();
    }
    
    //创建具体产品类(继承抽象产品类), 定义生产的具体产品;
    class JavaCourse implements ICourse {
    
        public void record() {
            System.out.println("录制Java课程");
        }
    }
    
    class PythonCourse implements ICourse {
    
        public void record() {
            System.out.println("录制Python课程");
        }
    }  
    //第一种方式,根据参数来判断哪个类来处理。
    //新建工厂。
    class CourseFactory {
     ICourse create(String name){
            if("java".equals(name)){
                return new JavaCourse();
            }else if("python".equals(name)){
                return new PythonCourse();
            }else {
                return null;
            }
        }
    }
    //调用工厂类来实例化需要的类。
    class testFactory(){
        public static void main(String[] args) {
            CourseFactory factory = new CourseFactory();
            ICourse course = factory.create("Java");
            course.record();
        }
    } 
    

     

    //第二种写法,通过反射的方式
        public ICourse create(String className){
            try {
                if (!(null == className || "".equals(className))) {
                    return (ICourse) Class.forName(className).newInstance();
                }
    
            }catch (Exception e){
                e.printStackTrace();
            }
            return null;
        }
    
    //调用(通过全路径去反射获取)
      ICourseFactory factory = new ICourseFactory();
        ICourse course = factory.create("com.gupaoedu.vip.pattern.factory.JavaCourse");
        course.record();
    
    
    或者
    
     public ICourse create(Class<? extends ICourse> clazz) {
        try {
          if (null != clazz) {
            return clazz.newInstance();
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
        return null;
      }
    
    //调用
        CourseFactory factory = new CourseFactory();
        ICourse course = factory.create(JavaCourse.class);
        course.record();
    

    简单工厂模式的优点:

    1、工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;

    2、简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。

    3、客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。

    4、通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

    简单工厂模式的缺点:

    1、由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。

    2、使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。

    3、系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。

    4、简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

    简单工厂模式的在JDK或者Spring当中的运用例子:

    待补充

    四、工厂方法模式

    工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。

    主要是将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。

    //步骤1: 创建抽象工厂类,定义具体工厂的公共接口
    public interface ICourseFactory {
        ICourse create();
    }
    
    //步骤2: 创建抽象产品类 ,定义具体产品的公共接口;
    public interface ICourse {
        void record();
    }
    
    //步骤3: 创建具体产品类(继承抽象产品类), 定义生产的具体产品;
    //产品1
    public class JavaCourse implements ICourse {
    
        public void record() {
            System.out.println("录制Java课程");
        }
    }
    //产品2
    public class PythonCourse implements ICourse {
    
        public void record() {
            System.out.println("录制Python课程");
        }
    }
    
    
    //步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法(每个产品对应一个实现的工厂);
    //工厂1
    public class JavaCourseFactory implements ICourseFactory {
        public ICourse create() {
            return new JavaCourse();
        }
    }
    
    //工厂2
    public class PythonCourseFactory implements ICourseFactory {
    
        public ICourse create() {
            return new PythonCourse();
        }
    }
    
    //步骤5:外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例
    public class FactoryMethodTest {
    
        public static void main(String[] args) {
            ICourseFactory factory = new PythonCourseFactory();
            ICourse course = factory.create();
            course.record();
    
            factory = new JavaCourseFactory();
            course = factory.create();
            course.record();
        }
    }

    工厂方法模式的优点:

    1、更符合开-闭原则 
    新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可

    2、符合单一职责原则 
    每个具体工厂类只负责创建对应的产品

    3、不使用静态工厂方法,可以形成基于继承的等级结构。

    工厂方法模式的缺点:

    1、添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销;

    2、由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。

    3、虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另外一种产品,仍然需要修改实例化的具体工厂类;

    4、一个具体工厂只能创建一种具体产品

    工厂方法模式的在JDK或者Spring当中的运用例子:

    待补充

    五、抽象工厂模式

    为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

    代码和工厂方法模式类似,只是抽象工厂不但可以创建单个产品,而且还能创建产品族(关联产品)

    //步骤1: 创建抽象工厂类,定义具体工厂的公共接口
    public interface ICourseFactory {
          INote createNote();
    
        IVideo createVideo();
    }
    
    //步骤2: 创建抽象产品类 ,定义具体产品的公共接口(多个相关产品,形成产品族);
    //笔记
    public interface INote {
        void edit();
    }
    //视频
    public interface IVideo {
        void record();
    }
    
    
    //步骤3: 创建具体产品类(继承抽象产品类), 定义生产的具体产品;
    //产品1
    public class JavaNote implements INote {
    
        public void edit() {
            System.out.println("编写Java笔记");
        }
    }
    
    //产品2
    public class JavaVideo implements IVideo {
        public void record() {
            System.out.println("录制Java视频");
        }
    }
    
    
    
    //步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法(每个产品对应一个实现的工厂);
    //只需要一个工厂,就能处理上面多种关联产品,如果产品之前存在关联关系,那么可以直
    //接在此工厂内部进行维护
    public class JavaCourseFactory implements CourseFactory {
    
        public INote createNote() {
            return new JavaNote();
        }
    
        public IVideo createVideo() {
            return new JavaVideo();
        }
    }
    
    
    //步骤5:外界通过调用具体工厂类的方法,创建多个产品。
    public class FactoryMethodTest {
    
        public static void main(String[] args) {
    
            JavaCourseFactory factory = new JavaCourseFactory();
    
            factory.createNote().edit();
            factory.createVideo().record();
    
        }
    }

    抽象工厂模式的优点:

            抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。

    抽象工厂模式的缺点:

           产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。

    抽象工厂在JDK和Spring中的运用:

    待补充

  • 相关阅读:
    Mysql中自增字段(AUTO_INCREMENT)的一些常识
    MyBatis动态传入表名
    Linux创建连接命令 ln -s创建软连接
    leaflet 使用turfjs实现前端自定义插值
    java后台@RequestBody和@RequestParam
    在jeecg-boot中密码的使用
    在jeecg-boot中使用代码生成器&mybatis-plus
    Pyppeteer 爬取实战
    【转】GitHub不再支持密码验证解决方案
    【转】pyppeteer+chromium手动安装Mac版本
  • 原文地址:https://www.cnblogs.com/HaveChen/p/11796972.html
Copyright © 2020-2023  润新知