zoukankan      html  css  js  c++  java
  • Spring中常见的设计模式——工厂模式

    一、简单工厂模式

      简单工厂模式(Simple Factory Pattern)由一个工厂对象决定创建哪一种产品类的实例,简单工厂模式适用于工厂类负责创建对象较少的情况,且客户端只需要传入工厂类的参数,对于如何创建对象不关心。

    public interface IBlog {
        //写随笔
        public void write();
    }
    public class JavaBlog implements IBlog {
        @Override
        public void write() {
            System.out.println("写java随笔");
        }
    }
    public class WriteBlog {
        public static void main(String[] args) {
            IBlog blog = new JavaBlog();
            blog.write();
        }
    }

      上述代码中,父类 IBlog 指向子类JavaBlog 的引用,应用层需要依赖JavaBlog,如果增加PythonBlog等等更多的课程,客户端就会越来越臃肿。因此要把依赖减弱,把创建细节隐藏。现在我们用简单工厂优化:

    public class BlogFactory {
        public IBlog create(Class<? extends IBlog> clazz) {
            if (null != clazz) {
                try {
                    return clazz.newInstance();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }

    客户端改变:

      public static void main(String[] args) {
            BlogFactory blogFactory = new BlogFactory();
            IBlog blog = blogFactory.create(JavaBlog.class);
            blog.write();
        }

      简单工厂模式在JDK中很常见,如Calender类(感兴趣去看源码),还有logback,LoggerFactory中有很多重载的方法getLogger()。但是简单工厂也有缺点:工厂类的职责相对过重,不易于扩展过于复杂的产品结构。

    二、工厂方法模式

       工厂方法模式(Factory Method Pattern)是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法模式让类的实例化推迟到子类中进行。在工厂方法模式中,用户只需要关心所需产品对应工厂,无须关心创建的细节,而且加入新产品时符合开闭原则。

      工厂方法模式主要解决产品扩展问题。在简单工厂模式中,随着产品的增多,如果不同语言书写随笔的逻辑各不相同,工厂职责越来越多,那工厂里面就会乱搞一气,狗屁不通。根据单一职责原则,我们将只能进行拆分,不同工厂做不同事,Java随笔由Java工厂创建,Python随笔由Python工厂创建,对工厂本身进行抽象。

    先创建工厂类:

    public interface IBlogFactory {
        IBlog create();
    }

    再创建对应工厂:

    public class JavaBlogFactory implements IBlogFactory {
        @Override
        public IBlog create() {
            return new JavaBlog();
        }
    }
    
    public class PythonBlogFactory implements IBlogFactory {
        @Override
        public IBlog create() {
            return new PythonBlog();
        }
    }

    客户端:

    public class CreateBlog {
        public static void main(String[] args) {
            IBlogFactory factory = new PythonBlogFactory();
            IBlog blog = factory.create();
            blog.write();
    
            factory = new JavaBlogFactory();
            blog = factory.create();
            blog.write();
        }
    }

    总结来说就是:不同工厂抽象出一个工厂头子,不同的工厂创建不同的实例。

    工厂方法模式适用于以下场景:

    1.创建对象需要大量重复代码。

    2.客户端(应用层)不依赖于产品类实例如何被创建、如何被实现等细节。

    3.一个类通过其子类来指定创建哪个对象。

    缺点:

    1.类的个数容易过多,增加复杂度。

    2.增加了系统的抽象性和理解难度。

    三、抽象工厂

      抽象工厂(Abstract Factory Pattern)提供一个黄健一系列相关或相互依赖对象的接口,无需指定具体类。客户端(应用层)不依赖于产品类实例如何被创建、如何被实现等细节,强调的是一系列相关得产品对象(属于同一产品族)一起使用创建对象需要大量重复代码。需要提供一个产品类的库,所有产品以同样接口出现,从而是客户端不依赖于具体实现。

    产品族:同一家的不同产品,比如小米,华为,苹果;

    产品等级:不同种类的产品,比如 手机,电视,电脑。

    工厂要做的就是生产我们牌子的所有产品。以博客为例,java分类的博客有随笔、文章、日记等。

    首先创建文章和日记的抽象接口:

    public interface IDocument {
        void write();
    }
    
    public interface INote {
        void make();
    }

    再创建抽象工厂:

    public interface BlogFactory {
        INote createNote();
    
        IDocument createDocument();
    }

    实现Java文章和日记:

    public class JavaDocument implements IDocument {
        @Override
        public void write() {
            System.out.println("写Java文章");
        }
    }
    
    public class JavaNote implements INote {
        @Override
        public void make() {
            System.out.println("写Java笔记");
        }
    }

    实现Java产品族具体工厂:

    public class JavaBlogFactory implements BlogFactory {
        @Override
        public INote createNote() {
            return new JavaNote();
        }
    
        @Override
        public IDocument createDocument() {
            return new JavaDocument();
        }
    }

    实现Python文章和日记、实现Python具体工厂参考Java的。

    客户端调用:

    public class BlogTest {
        public static void main(String[] args) {
            JavaBlogFactory factory = new JavaBlogFactory();
            factory.createDocument().write();
            factory.createNote().make();
        }
    }

      上述代码描述了两个产品族的工厂,如果想要扩展产品等级(就是再加点评啥的),要调整抽象工厂、具体工厂。由此可见抽象工厂模式的缺点:

    1.规定所有可能被创建的产品集合,产品族(Java系列)中扩展新产品很困难,需要修改抽象工厂及实现;

    2.增加系统抽象性和理解难度;

      我们可以利用工厂模式创建好数据源连接池并放到容器中,业务需要时再取出。就避免了用一次创建一次的尴尬。

  • 相关阅读:
    Spring Boot 返回 XML 数据,一分钟搞定!
    Spring Cloud Alibaba Sentinel 整合 Feign 的设计实现
    周末去面试,进去 5 分钟就出来了…
    Spring Boot 返回 JSON 数据,一分钟搞定!
    Java 11 已发布,String 还能这样玩!
    Hashtable 为什么不叫 HashTable?
    Java 中初始化 List 集合的 6 种方式!
    HashMap 和 Hashtable 的 6 个区别,最后一个没几个人知道!
    毕业不到一年,绩效打了个D!
    poj 3111 K Best (二分搜索之最大化平均值之01分数规划)
  • 原文地址:https://www.cnblogs.com/xcgShare/p/11935551.html
Copyright © 2011-2022 走看看