设计模式

设计模式 | 抽象工厂模式及典型应用

2019-01-03  本文已影响2人  小旋锋的简书

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。

在抽象工厂模式中,每一个具体工厂都提供了多个工厂方法用于产生多种不同类型的产品。

角色

在抽象工厂模式包含如下几个角色:

在抽象工厂中声明了多个工厂方法,用于创建不同类型的产品,抽象工厂可以是接口,也可以是抽象类或者具体类

具体工厂实现了抽象工厂,每一个具体的工厂方法可以返回一个特定的产品对象,而同一个具体工厂所创建的产品对象构成了一个产品族

示例

首先定义我们的抽象产品 ArticleVideo,他们是产品族的抽象类,有一个 Article 就有一个 Video

public abstract class Article {
    public abstract void produce();
}

public abstract class Video {
    public abstract void produce();
}

具体产品 JavaArticlePythonArticlePythonVideoJavaVideo

public class JavaArticle extends Article {
    @Override
    public void produce() {
        System.out.println("编写Java课程笔记记");
    }
}

public class PythonArticle extends Article {
    @Override
    public void produce() {
        System.out.println("编写Python课程笔记");
    }
}

public class JavaVideo extends Video {
    @Override
    public void produce() {
        System.out.println("录制Java课程视频");
    }
}

public class PythonVideo extends Video {
    @Override
    public void produce() {
        System.out.println("录制Python课程视频");
    }
}

定义我们的抽象工厂 CourseFactory,与工厂方法模式不同,工厂方法模式中一个工厂只生产一个产品,而抽象工厂模式中一个工厂生产一族产品,有多个工厂方法

public interface CourseFactory {
    Video getVideo();
    Article getArticle();
}

具体工厂 JavaCourseFactoryPythonCourseFactory,它们都继承抽象工厂接口 CourseFactory

public class JavaCourseFactory implements CourseFactory {
    @Override
    public Video getVideo() {
        return new JavaVideo();
    }

    @Override
    public Article getArticle() {
        return new JavaArticle();
    }
}

public class PythonCourseFactory implements CourseFactory {
    @Override
    public Video getVideo() {
        return new PythonVideo();
    }

    @Override
    public Article getArticle() {
        return new PythonArticle();
    }
}

客户端只需要指定具体工厂,就可以获取该工厂生产的一族产品

public class Test {
    public static void main(String[] args) {
        CourseFactory courseFactory = new JavaCourseFactory();
        Video video = courseFactory.getVideo();
        Article article = courseFactory.getArticle();
        video.produce();
        article.produce();
    }
}

输出

录制Java课程视频
编写Java课程笔记

也可以利用反射机制和配置文件,当需要修改具体工厂的时候就不需要修改客户端代码,只改配置文件即可

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        // 从配置文件或数据库等外部渠道获取具体工厂类名
        String factoryName = "com.designpattern.JavaCourseFactory";
        // 通过反射机制获取工厂类
        Class c = Class.forName(factoryName);
        CourseFactory courseFactory = (CourseFactory) c.newInstance();
        Video video = courseFactory.getVideo();
        Article article = courseFactory.getArticle();
        video.produce();
        article.produce();
    }
}

最终的类图如下所示

示例.抽象工厂类图

抽象工厂模式总结

抽象工厂模式的主要优点如下:

抽象工厂模式的主要缺点如下:

适用场景

抽象工厂模式的典型应用及源码分析

我们来看 java.sql 包下的 Connection 接口,该接口定义了与特定数据库的连接 Connection,执行 SQL statements 并返回 results

public interface Connection  extends Wrapper, AutoCloseable {
    Statement createStatement() throws SQLException;
    PreparedStatement prepareStatement(String sql) throws SQLException;
    CallableStatement prepareCall(String sql) throws SQLException;
    DatabaseMetaData getMetaData() throws SQLException;
    Savepoint setSavepoint() throws SQLException;
    Clob createClob() throws SQLException;
    Blob createBlob() throws SQLException;
    SQLXML createSQLXML() throws SQLException;
    // ...省略...
}

其中 StatementPreparedStatementCallableStatementDatabaseMetaDataSavepointClobBlobSQLXML 等均为接口

我们来看 Statement 接口

public interface Statement extends Wrapper, AutoCloseable {
    ResultSet executeQuery(String sql) throws SQLException;
    int executeUpdate(String sql) throws SQLException;
    void close() throws SQLException;
    int getMaxFieldSize() throws SQLException;
    boolean execute(String sql) throws SQLException;
    // ...省略...
}

其中的 ResultSet 又是一个接口

public interface ResultSet extends Wrapper, AutoCloseable {
    boolean next() throws SQLException;
    void close() throws SQLException;
    boolean wasNull() throws SQLException;
    String getString(int columnIndex) throws SQLException;
    //...省略...
}

我们可以看一下他们的实现类

Connection的实现类 Statement的实现类 ResultSet的实现类

可以看出这里边的抽象工厂模式,Connection 为抽象工厂,工厂方法很多,其中一个抽象产品为 Statement,同时 Statement 也是一个抽象工厂,工厂方法也很多,其中一个抽象产品为 ResultSet,具体工厂和具体产品则为他们的实现类

参考:
刘伟:设计模式Java版
慕课网java设计模式精讲 Debug 方式+内存分析

后记

欢迎评论、转发、分享,您的支持是我最大的动力

更多内容可访问我的个人博客:http://laijianfeng.org

关注【小旋锋】微信公众号,及时接收博文推送

关注_小旋锋_微信公众号
上一篇 下一篇

猜你喜欢

热点阅读