文档章节

设计模式2——Factory设计模式

小米米儿小
 小米米儿小
发布于 2013/12/05 23:00
字数 1209
阅读 164
收藏 9

Factory工厂设计模式为创建对象提供了一种抽象,而对使用者屏蔽了对象创建的具体细节过程,工厂模式有三种:简单工厂模式,抽象工厂模式和工厂方法模式。

1. 简单工厂模式:

又叫静态工厂模式,简单工厂只包括一个抽象产品类(该类可以是接口,也可以是具体的类),所有需要的产品类都是该抽象产品类的子类。简单工厂模式中工厂为具体产品工厂,产品为抽象产品,由工厂实例创建产品实例:

一个生成圆形和矩形的图形工厂,例子如下:

//图形接口
interface Shape(){
    public void draw();
}

//圆形
class Circle implements Shape{
    public void draw(){
        System.out.println(“Circle is drawing”);
    }
}

//矩形
class Rectangle implements Shape{
    public void draw(){
        System.out.println(“Rectangle is drawing”);
    }
}

//图形工厂
class ShapeFactory{
    public static Shape createShape(String name) throws InstantiationException, 
                                      IllegalAccessException, 
                                      ClassNotFoundException {
        //使用java的反射机制来产生对象实例
        return (Shape)class.forName(name).newInstance();
    }
} 

public class ShapeDemo{
    public static void draw(Shape shape){
        shape.draw();
    }
    public static void main(String[] args){
        draw(ShapeFactory.createShape(“Circle”));
        draw(ShapeFactory.createShape(“Rectangle”));
    }
}

图形工厂负责具体图形的对象实例化工作,图形使用者使用时不需要关心图形对象的具体产生过程。

2. 抽象工厂模式:

抽象工厂模式中可以包括多个抽象产品类,每个抽象产品类可以产生出多个具体产品类,一个抽象工厂用于定义所需产品的组合形式,抽象工厂派生具体工厂类,这些具体工厂类就是简单工厂模式中的工厂类,具体工厂类负责具体产品实例的创建:


以软件皮肤为例,软件皮肤由样式style和颜色color组成,实现一套IOS风格的软件皮肤,一套Android风格的软件皮肤,通过抽象工厂实现软件皮肤自由切换例子如下:

//软件皮肤类 
class Skin{
    private SkinFactory skinFactory;
    public Skin(SkinFactory factory){
        setSkinFactory(factory);
    }
    public void setSkinFactory(SkinFactory factory){
        this.skinFactory = factory
    }
    public void showSkin(){
        System.out.println(“Style=” + factory.getStyle().showStyle() + “, color=” + factory.getColor().showColor());
    }
}

//软件Style
interface Style(){
    public void showStyle();
}

//IOS style
class IOSStyle implements Style{
    public void showStyle(){
        System.out.println(“This is IOS style”);
    }
}

//Android style
class AndroidStyle implements Style{
    public void showStyle(){
        System.out.println(“This is Android style”);
    }
}

//软件Color
interface Color(){
    public void showColor();
}

//IOS color
class IOSColor implements Color{
    public void showColor(){
        System.out.println(“This is IOS color”);
    }
}

//Android color
class AndroidColor implements Color{
    public void showColor(){
        System.out.println(“This is Android color”);
    }
}

//抽象皮肤工厂
interface SkinFactory{
    public Style getStyle();
    public Color getColor();
}

//IOS皮肤工厂
class IOSSkinFactory implements SkinFactory{
    public Style getStyle(){
        return new IOSStyle();
    }
    public Color getColor(){
        return new IOSColor();
    }
}

//Android皮肤工厂
class AndroidSkinFactory implements SkinFactory{
    public Style getStyle(){
        return new AndroidStyle();
    }
    public Color getColor(){
        return new AndroidColor();
    }
}

public class SkinDemo{
    public static void main(String[] args){
        //显示一套IOS皮肤
        Skin skin = new Skin(new IOSSkinFactory());
        skin.showSkin();
        //换一套Android的皮肤
        skin.setSkinFactory(new AndroidSkinFactory());
        skin.showSkin();
    }
}
抽象工厂指定了产品组合形式,具体的工厂产生具体的产品,抽象工厂适用于多个产品相互组合的情况。

3. 工厂方法模式:

工厂方法中也只包含一个抽象产品类,抽象产品类可以派生出多个具体产品类。工厂方法定义一个用于创建产品的接口,让子类决定实例化哪一个类,使得类的实例化延迟到子类。


工厂方法模式例子如下:

//汽车接口
interface ICar{
    public void run();
}

//奔驰车
class BenzCar implements ICar{
    public void run(){
        System.out.println(“Benz car run”);
    }
}

//宝马车
class BMWCar implements ICar{
    public void run(){
        System.out.println(“BMW car run”);
    }
}

//抽象汽车工厂
abstract class CarFactory{
    public abstract ICar createCar();
}

//奔驰车工厂
class BenzCarFactory extends CarFactory{
    public ICar createCar(){
        return new BenzCar();
    }
}

//宝马车工厂
class BMWCarFactory extends CarFactory{
    public ICar createCar(){
        return new BMWCar();
    }
}

public class FactoryMethodDemo{
    public static void main(String[] args){
        CarFactory factory = new BenzCarFactory();
        ICar car = factory.createCar();
        car.run();
        factory = new BMWCarFactory();
        car = factory.createCar();
        car.run();
    }
}

工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。

使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。工厂模式返回的实例可以不是新创建的,返回由工厂创建好的实例也是可以的。

三种工厂模式的区别:

简单工厂 : 用来生产同一等级结构中的任意产品,对于增加新的产品,无能为力。

抽象工厂 :用来生产不同产品族(由不同产品组合成的一套产品)的全部产品,对于增加新的产品,无能为力;支持增加产品族。

工厂方法 :用来生产同一等级结构中的固定产品,支持增加任意产品。

本文转载自:http://blog.csdn.net/chjttony/article/details/7458673

共有 人打赏支持
小米米儿小
粉丝 40
博文 114
码字总数 83921
作品 0
成都
程序员
私信 提问
《JavaScript设计模式与开发实践》原则篇(2)—— 最少知识原则

最少知识原则(LKP)说的是一个软件实体应当尽可能少地与其他实体发生相互作用。这 里的软件实体是一个广义的概念,不仅包括对象,还包括系统、类、模块、函数、变量等。 单一职责原则指导我们...

嗨呀豆豆呢
2018/12/30
0
0
《JavaScript设计模式与开发实践》最全知识点汇总大全

系列文章: 《JavaScript设计模式与开发实践》基础篇(1)—— this、call 和 apply 《JavaScript设计模式与开发实践》基础篇(2)—— 闭包和高阶函数 《JavaScript设计模式与开发实践》模式...

嗨呀豆豆呢
01/04
0
0
编程中的那些套路——关于工厂模式

该文章属于《编程中的那些经典套路——设计模式汇总》系列,并且以下内容基于语言PHP 前面我们写了简单工厂模式,《编程中的那些套路——关于简单工厂模式》,但简单工厂模式有一些不足(违反...

gzchen
2018/08/27
0
0
设计模式已经陨落了?

你现在是坐在一个程序员旁边吗?如果是的话,那么在你读下面的段落之前,有一个简单的实验。让他们到一边去,问问他们两个问题并记录下答案。首先问他们“什么是设计模式?”然后再问“说出你...

oschina
2014/03/11
9.1K
69
23种设计模式(3):抽象工厂模式

定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。 类型:创建类模式 类图: 抽象工厂模式与工厂方法模式的区别 抽象工厂模式是工厂方法模式的升级版本,他用来...

LCZ777
2014/07/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Nginx 配置 root目录、虚拟目录alias

Nginx是通过 alias 设置虚拟目录,在Nginx的配置中,alias目录和root目录是有区别的。 alias指定的目录是准确的,即location匹配访问的path目录下的文件直接是在alias目录下查找的; root指定...

Yue_Chen
24分钟前
1
0
Nginx的SSL

Nginx的SSL 当我们访问站点时,网址的前缀是https的就是启用了ssl SSL介绍:SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供...

李超小牛子
30分钟前
3
0
matlab-自控原理 roots 传递函数 零极点

  matlab : R2018a 64bit     OS : Windows 10 x64 typesetting : Markdown    blog : my.oschina.net/zhichengjiu    gitee : gitee.com/zhichengjiu   code clearclc% s^4+5*......

志成就
32分钟前
1
0
spring官网上下载历史版本的spring插件,springsource-tool-suite

spring官网下载地址(https://spring.io/tools/sts/all),历史版本地址(https://spring.io/tools/sts/legacy)。 注:历史版本下载的都是装好插件的eclipse,而非我们需要的插件 目前官网上提...

开源oschina
32分钟前
2
0
同一台服务器,mysql登录不了指定端口的问题

一台服务器上启动了两个mysql服务,端口分别是3306,3307 mysql -P3307 -uroot -p,输入密码,登录失败 输入3306的密码,登录成功,结果登到3306数据库上去了 查资料发现,不指定主机-h 的话,...

chdahuzi
32分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部