JAVA设计模式--工厂方法模式

简介:

1、工厂方法模式的引进

前面一章刚说过简单工厂模式,我们知道。简单工厂模式不管针对什么样的产品结构都採用以不变应万变的策略,就是仅仅有一个工厂角色,全部的产品都通过这个万

能工厂类来创建,这个工厂类中包括了全部产品的创建逻辑,可是当我们系统中要添加一种新的产品的时候。那么我们就须要改动工厂类了,须要在工厂类中添加新

的产品创建逻辑,所以,这就不符合我们编敲代码的"开-闭"原则。

所以就有了我们今天要说的工厂方法模式,首先,工厂方法模式中。核心工厂类不再负责详细产品的创建,而是将该职责交给了子类去做。这个核心类摇身一变变成

了抽象工厂角色,也就是全部详细工厂角色的父类,仅负责给出详细工厂子类必须实现的接口。而不去接触详细产品的创建细节了。

这么进一步抽象的操作就使得我们能够在不改动本身程序的前提下引进新的产品了,符合了我们程序设计的"开-闭"原则。

2、工厂方法模式的层级结构与各种角色


从上图能够分析出工厂方法模式的几个角色:

(1)抽象工厂角色(BaseFactory):这个角色是整个工厂方法模式的核心,全部创建对象的工厂类必须继承这种方法

(2)详细工厂角色(Factory_A):这个角色实现了抽象工厂角色的方法。详细工厂角色含有与应用密切相关的逻辑。负责创建相应的详细的产品,与详细产品

     角色一一相应

(3)抽象产品角色(BaseProduct):工厂方法模式所创建的全部产品的超类型,也就是全部产品类的共同拥有父类或者共同接口。

(4)详细产品角色(Product_A):继承或实现抽象产品角色。

client通过声明抽象工厂类对象。可获取到抽象工厂类对象的子类工厂,通过子类工厂创建产品的方法(显示返回抽象产品。实际返回详细产品)得到详细产品

类。当我们的系统中须要新增一种产品的时候,那我们不用改动原来的代码。仅仅须要在系统中添加一个详细工厂类和一个与之相相应的详细产品类就可以。

3、使用JAVA接口或者JAVA抽象类

我们也看到了,上面的抽象工厂类和抽象产品类我都是使用JAVA抽象类来实现的。实际中我们怎么选择呢。

假设详细工厂角色具有共同的逻辑。那么共同的逻辑就能够向上移动到抽象工厂角色中。这也就意味着抽象工厂角色应当由一个JAVA类实现,而且抽象工厂角色提

供默认的工厂方法。这个时候使用JAVA接口就不太合适,由于JAVA接口只描写叙述了方法的特征,而抽象类是能够描写叙述出方法的详细逻辑实现的。

事实上上面那个用例图没有必要用JAVA抽象类,由于他没有什么共同拥有逻辑须要在父类中实现。

对于没有共同拥有逻辑须要在父类中描写叙述的。那么使用JAVA接口好一些,由于我们JAVA语言是一种单继承语言。它仅仅能继承一个父类,所以使用继承的时候要谨慎,

而JAVA接口没这个限制,一个类能够实现多个接口(这也是为什么已经有了抽象类的概念,还要弄出个接口概念的原因)。

实际使用中这个问题还是须要我们针对系统的实际情况细致考虑一下的。

4、多态性的丧失和模式的退化

一个工厂方法模式的实现依赖于工厂角色和产品角色的多态性。在有些情况下,这个模式能够出现退化,其特点就是多态性的丧失。

工厂方法返还的应该是抽象类型而不是详细类型,仅仅有这样才干保证针对产品的多态性。

换言之,调用工厂方法的client总能够针对抽象编程,依赖于一个产品的抽象类型

而不是详细类型。

在特殊情况下,工厂方法仅返回一个详细产品类型,这个时候工厂方法就退化了,表现为针对产品角色的多态性的丧失。换言之。client知道了从工厂方法中获取的对象是

什么类型,这违背了工厂方法模式设计的原意,也就不是工厂方法模式了。

5、JAVA语言中工厂方法模式的样例

书中介绍的是Java集合类的迭代器。拿出来看一看

Collection接口中的一段代码:

    /**
     * Returns an iterator over the elements in this collection.  There are no
     * guarantees concerning the order in which the elements are returned
     * (unless this collection is an instance of some class that provides a
     * guarantee).
     *
     * @return an <tt>Iterator</tt> over the elements in this collection
     */
    Iterator<E> iterator();
继承Collction的List、Set等中有:

    /**
     * Returns an iterator over the elements in this list in proper sequence.
     *
     * @return an iterator over the elements in this list in proper sequence
     */
    Iterator<E> iterator();
接下来再看ArrayList中的代码:

    /**
     * Returns an iterator over the elements in this list in proper sequence.
     *
     * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
     *
     * @return an iterator over the elements in this list in proper sequence
     */
    public Iterator<E> iterator() {
        return new Itr();
    }

    /**
     * An optimized version of AbstractList.Itr
     */
    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }
Itr类实现了Interator接口

public interface Iterator<E> {
    /**
     * Returns {@code true} if the iteration has more elements.
     * (In other words, returns {@code true} if {@link #next} would
     * return an element rather than throwing an exception.)
     *
     * @return {@code true} if the iteration has more elements
     */
    boolean hasNext();

    /**
     * Returns the next element in the iteration.
     *
     * @return the next element in the iteration
     * @throws NoSuchElementException if the iteration has no more elements
     */
    E next();

    /**
     * Removes from the underlying collection the last element returned
     * by this iterator (optional operation).  This method can be called
     * only once per call to {@link #next}.  The behavior of an iterator
     * is unspecified if the underlying collection is modified while the
     * iteration is in progress in any way other than by calling this
     * method.
     *
     * @throws UnsupportedOperationException if the {@code remove}
     *         operation is not supported by this iterator
     *
     * @throws IllegalStateException if the {@code next} method has not
     *         yet been called, or the {@code remove} method has already
     *         been called after the last call to the {@code next}
     *         method
     */
    void remove();
}
看全了代码我们就会明确这里是怎么应用的工厂模式了

当中Iterator是抽象产品角色。Itr是Iterator以下的一个详细产品角色。List类应该是抽象工厂角色,ArrayList应该是详细工厂角色。假设我们须要在List下自

定义一个集合类并给出对应的迭代方式,那么我们仅仅须要加入一个实现List接口的集合类,然后在添加一个迭代类实现Iterator接口就能够了。并不需要去改动

JDK源代码的内容,满足了开-闭原则。






本文转自mfrbuaa博客园博客,原文链接http://www.cnblogs.com/mfrbuaa/p/5218082.html,如需转载请自行联系原作者

相关文章
|
2天前
|
设计模式 Java
【JAVA基础篇教学】第十四篇:Java中设计模式
【JAVA基础篇教学】第十四篇:Java中设计模式
|
3天前
|
设计模式 算法 Java
设计模式在Java开发中的应用
设计模式在Java开发中的应用
15 0
|
5天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
47 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
10天前
|
设计模式 前端开发 Java
19:Web开发模式与MVC设计模式-Java Web
19:Web开发模式与MVC设计模式-Java Web
20 4
|
10天前
|
设计模式 存储 前端开发
18:JavaBean简介及其在表单处理与DAO设计模式中的应用-Java Web
18:JavaBean简介及其在表单处理与DAO设计模式中的应用-Java Web
25 4
|
10天前
|
设计模式 缓存 监控
JAVA设计模式之结构型模式
结构模型:适配器模型、桥接模型、过滤器模型、组合模型、装饰器模型、外观模型、享受元模型和代理模型。
21 3
|
14天前
|
设计模式 算法 Java
Java基础教程(19)-设计模式简述
【4月更文挑战第19天】设计模式是软件设计中反复使用的代码设计经验,旨在提升代码的可重用性、可扩展性和可维护性。23种模式分为创建型、结构型和行为型三类。创建型模式如工厂方法、抽象工厂、建造者、原型和单例,关注对象创建与使用的分离。结构型模式涉及对象组合,如适配器、装饰器、外观等,增强结构灵活性。行为型模式专注于对象间职责分配和算法合作,包括责任链、命令、观察者等。设计模式提供标准化解决方案,促进代码交流和复用。
|
14天前
|
Java 开发者 UED
Java 异步和事件驱动编程:探索响应式模式
【4月更文挑战第27天】在现代软件开发中,异步和事件驱动编程是提高应用性能和响应性的关键策略。Java 提供了多种机制来支持这些编程模式,使开发者能够构建高效、可扩展的应用程序。
29 4
|
14天前
|
设计模式 Java
Java 设计模式:混合、装饰器与组合的编程实践
【4月更文挑战第27天】在面向对象编程中,混合(Mixins)、装饰器(Decorators)和组合(Composition)是三种强大的设计模式,用于增强和扩展类的功能。
21 1
|
14天前
|
设计模式 消息中间件 Java
Java 设计模式:探索发布-订阅模式的原理与应用
【4月更文挑战第27天】发布-订阅模式是一种消息传递范式,被广泛用于构建松散耦合的系统。在 Java 中,这种模式允许多个对象监听和响应感兴趣的事件。
35 2