java设计模式——创建型之工厂三兄弟(3)

来源:互联网 发布:知豆汽车销量 编辑:程序博客网 时间:2024/05/22 18:55
自大学课程初识设计模式以来,就越发觉得有必要系统学习一下设计模式。刚好在实习前准备期间课比较少,抽出一点时间整理一下记一些笔记,复制粘贴比较多。笔记比较适合学习过设计模式的同学。

Abstract Factory Pattern(抽象工厂模式)

学习链接:极客学院Wiki_Java设计模式之创造型模式

另外感谢刘伟博士,学习设计模式可以看刘伟博士的博客,很详尽。

刘伟技术博客


抽象工厂模式的适用范围

(1) 用户无须关心对象的创建过程,将对象的创建和使用解耦。

(2) 系统中有多于一个的产品族,而每次只使用其中某一产品族。

(3) 属于同一个产品族的产品将在一起使用。

这一约束必须在系统的设计中体现出来。

(4) 产品等级结构稳定。

设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。


应用实例

在javaAPI中的应用实例最具代表性的是AWT在不同操作系统下表现的不同样式。

在不同操作系统中,使用同样的AWT代码(即使用相同的接口)创建出的窗体、按钮等控件的样式会随操作系统的改变而改变。


抽象工厂模式如何实现

新概念:产品等级结构与产品族

(1) 产品等级结构

产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL 电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。

(2) 产品族

在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海尔电冰箱构成了一个产品族。
这里写图片描述
上图比较好理解

角色

AbstractFactory(抽象工厂)

它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。

ConcreteFactory(具体工厂)

它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。

AbstractProduct(抽象产品)

它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。

ConcreteProduct(具体产品)

它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

类图

这里写图片描述
抽象工厂模式在工厂方法模式上的优化就是将需要赋予同等属性的产品放在一个工厂中一起创建,可以复用原始产品;扩展工厂(产品族)方便,当然缺点就是若有新产品(产品等级结构)进入时就要修改工厂的代码了,违反了开闭原则。这里有开闭原则的倾斜性。


抽象工厂模式的优缺点

主要优点

(1) 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。

(2) 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。

(3) 增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。

主要缺点

增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。


练习

题目

在简单工厂模式和工厂方法模式的问题的基础上进行修改。
当我们需要建造不同颜色的图形集时需要使用抽象工厂模式。

代码实现

抽象产品:Circle.java

package com.joy;public interface Circle {    public void display();}

抽象产品:Rectangle.java

package com.joy;public interface Rectangle {    public void display();}

具体产品:RedCircle.java

package com.joy;public class RedCircle implements Circle{    @Override    public void display() {        System.out.println("显示红色的圆~");         }}

具体产品:GreenCircle.java

package com.joy;public class GreenCircle implements Circle{    @Override    public void display() {        System.out.println("显示绿色的圆~");         }}

具体产品:RedRectangle.java

package com.joy;public class RedRectangle implements Rectangle{    @Override    public void display() {        System.out.println("显示红色的长方形~");           }}

具体产品:GreenRectangle.java

package com.joy;public class GreenRectangle implements Rectangle{    @Override    public void display() {        System.out.println("显示绿色的长方形~");           }}

抽象工厂:Factory.java

package com.joy;public interface Factory {    public Circle getCircle();    public Rectangle getRectangle();}

具体工厂:RedFactory.java

package com.joy;public class RedFactory implements Factory {    @Override    public Circle getCircle() {        return new RedCircle();    }    @Override    public Rectangle getRectangle() {        return new RedRectangle();    }}

具体工厂:GreenFactory.java

package com.joy;public class GreenFactory implements Factory {    @Override    public Circle getCircle() {        return new GreenCircle();    }    @Override    public Rectangle getRectangle() {        return new GreenRectangle();    }}

客户端:AbstractFactoryDemo.java

package com.joy;public class AbstractFactoryDemo {    public static void main(String[] args) {        Circle c;        Rectangle r;        Factory f;        System.out.println("客户端:需要红色");        f = new RedFactory();        f.getCircle().display();        f.getRectangle().display();        System.out.println("客户端:需要绿色");        f = new GreenFactory();        f.getCircle().display();        f.getRectangle().display();    }}

运行结果

这里写图片描述

总结

工厂模式主要都是为了实现客户端和产品之间的解耦,这样客户端就能灵活获取产品。抽象工厂模式会用到大系统中,主要是对相同样式的不同产品进行一起管理,因此广泛运用于样式,其他例子我还没有遇见。但是在写代码理解的过程中发现其与装饰模式有异曲同工的感觉,但是实现起来是不同的,可以进一步讨论。

0 0
原创粉丝点击