• 设计模式学习总结(三)--工厂模式


    工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

    简单工厂模式

    定义

    简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

    实例

    需求:以学习课程为例

    课程抽象类:

    public interface ICourse {
        void learn();
    }
    

    Java 课程:

    public class JavaCourse implements ICourse {
        @Override
        public void learn() {
            System.out.println("正在学习 Java ......");
        }
    }
    

    Mysql 课程:

    public class MysqlCourse implements ICourse {
        @Override
        public void learn() {
            System.out.println("正在学习 Mysql ......");
        }
    }
    

    课程工厂类:

    public class CourseFactory {
    
        public static final int COURSE_JAVA = 1;
        public static final int COURSE_MYSQL = 2;
    
        public ICourse getCourse(int courseType) {
            switch (courseType) {
                case COURSE_JAVA:
                    return new JavaCourse();
                case COURSE_MYSQL:
                    return new MysqlCourse();
                default:
                    return null;
            }
        }
    }
    

    学习 Java 课程:

    public static void main(String[] args) {
        CourseFactory factory = new CourseFactory();
        ICourse course = factory.getCourse(CourseFactory.COURSE_JAVA);
        course.learn();
    }
    

    优缺点

    • 优点:简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。

    • 缺点:很明显工厂类集中了所有实例的创建逻辑,容易违反 GRASPR 的高内聚的责任分配原则

    工厂方法模式

    定义

    工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现 开-闭 原则,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。

    在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

    实例

    以上面的课程为例,我们将工厂对象变为接口:

    public interface ICourseFactory {
    
        ICourse getCourse();
    
    }
    

    实现两个课程各自的工厂:

    public class JavaCourseFactory implements ICourseFactory {
        @Override
        public ICourse getCourse() {
            return new JavaCourse();
        }
    }
    
    public class MysqlCourseFactory implements ICourseFactory {
        @Override
        public ICourse getCourse() {
            return new MysqlCourse();
        }
    }
    

    测试类调用:

    public static void main(String[] args) {
        ICourseFactory factory;
        // 学习 java
        factory = new JavaCourseFactory();
        ICourse javaCourse = factory.getCourse();
        javaCourse.learn();
        // 学习 Mysql
        factory = new MysqlCourseFactory();
        ICourse mysqlCourse = factory.getCourse();
        mysqlCourse.learn();
    }
    

    优缺点

    优点:

    • 屏蔽产品类。产品类的实现如何变化,调用者都不需要关心,只需关心产品的接口,只要接口保持不变,系统中的上层模块就不会发生变化。

    • 典型的解耦框架。高层模块只需要知道产品的抽象类,其他的实现类都不需要关心,符合迪米特法则,符合依赖倒置原则,符合里氏替换原则。

    • 多态性:客户代码可以做到与特定应用无关,适用于任何实体类。

    缺点:

    • 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
    • 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到 DOM、反射等技术,增加了系统的实现难度。

    抽象工厂模式

    定义

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

    抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。

    在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。

    实例

    针对一门课程除了学习外,我们应该还要有输出笔记操作,我们来实现下笔记对象。

    增加笔记接口

    public interface INote {
    
        void write();
    
        void read();
    
    }
    

    具体笔记实现:

    public class JavaNote implements INote {
        @Override
        public void write() {
            System.out.println("写 Java 笔记");
        }
    
        @Override
        public void read() {
            System.out.println("读 Java 笔记");
        }
    }
    
    public class MysqlNote implements INote {
        @Override
        public void write() {
            System.out.println("写 Mysql 笔记");
        }
    
        @Override
        public void read() {
            System.out.println("读 Mysql 笔记");
        }
    }
    

    修改工厂接口:

    public interface ICourseFactory {
    
        ICourse getCourse();
    
        INote getNote();
    }
    

    工厂实现:

    public class JavaCourseFactory implements ICourseFactory {
        @Override
        public ICourse getCourse() {
            return new JavaCourse();
        }
    
        @Override
        public INote getNote() {
            return new JavaNote();
        }
    }
    
    public class MysqlCourseFactory implements ICourseFactory {
        @Override
        public ICourse getCourse() {
            return new MysqlCourse();
        }
    
        @Override
        public INote getNote() {
            return new MysqlNote();
        }
    }
    

    测试类:

    public static void main(String[] args) {
        ICourseFactory factory;
        // 学习 java
        factory = new JavaCourseFactory();
        ICourse javaCourse = factory.getCourse();
        javaCourse.learn();
        INote javaNote = factory.getNote();
        javaNote.read();
        // 学习 Mysql
        factory = new MysqlCourseFactory();
        ICourse mysqlCourse = factory.getCourse();
        mysqlCourse.learn();
        INote mysqlNote = factory.getNote();
        mysqlNote.read();
    }
    

    优缺点

    优点:

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

    缺点:

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

  • 相关阅读:
    Anglarjs 工具方法
    AngularJs $scope 里面的$apply 方法和$watch方法
    CentOS 下tomcat安装
    Phonegap Android 项目使用Cordova
    Phonegap 原生控件(Android)与html混合
    Phonegap 通信原理
    Phonegap 开发环境搭建
    Phonegap 通知 Notification
    Phonegap 工作原理
    Angularjs MVC
  • 原文地址:https://www.cnblogs.com/markLogZhu/p/11453099.html
Copyright © 2020-2023  润新知