Swift-工厂方法(Factory Method)

来源:互联网 发布:软件设计师考试解析 编辑:程序博客网 时间:2024/06/05 03:47
工厂方法模式是抽象工厂模式的组成部分。各种具体工厂重载其抽象工厂父类中定义的工厂方法,并且用这个重载的工程方法创建自己的产品(对象).

生产者自身不必是抽象工厂,它可以是任何类,要点在于不是直接创建对象,而是使用类或者对象的工厂方法创建具体产品,并以抽象类型返回。

工厂方法

工厂方法(英语:Factory method)是一种实现了工厂概念的面向对象设计模式。就像其他创建型模式一样,它也是处理在不指定对象具体类型的情况下创建对象的问题。工厂方法模式的实质是定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行"。

工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好地符合了开放封闭原则。工厂方法也叫做虚构造器(Virtual Constructor).又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

为何是创建对象的安全方法

与直接创建新的对象相比,使用工厂方法创建对象可算作一种最佳做法。工厂方法模式让客户程序可以要求由工厂方法创建的对象拥有一组共同的行为。所以往类层次结构中引入新的具体产品并不需要修改客户端代码,因为返回的任何具体对象的接口都跟客户端一直在用的从前的接口相同。

工厂方法分析

1
:将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。
2
:在调用工厂类的工厂方法时,由于工厂方法是静态方法,使用起来很方便,可通过类名直接调用,而且只需要传入一个简单的参数即可,在实际开发中,还可以在调用时将所传入的参数保存在XML等格式的配置文件中,修改参数时无须修改任何源代码。
3
:简单工厂模式最大的问题在于工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背的。
4:简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。

工厂方法的使用场景
   
1
:编译时无法准确预期要创建的对象的类;
2
:类想让子类决定在运行时创建什么;
3:类有若干辅助类为其子类,而你想将返回哪个子类这一信息局部话;

工厂方法在CocoaTouch中的应用

工厂方法在CocoaTouch中几乎随处可见。Objective-C中常见的两步对象创建法[[SomeClass alloc] init].但是还有一些便利的创建方法。例如,NSNumber有很多numberWith*方法;其中有两个是numberWithBool:numberWithChar:。它们是类方法,也就是说我们向NSNumber发送[[NSNumber numberWithBool:bool]][[NSNumber numberWithChar:char]],以获得与传入参数同类型的各种NSNumber实例。与如何创建NSNumber的具体子类型的实例有关的所有细节,都有NSNumber的类工厂方法负责。[[NSNumber numberWithBool:bool]]的情况是,方法接受值bool,并把NSNumber的内部子类的一个实例初始化,让它能够反应传入的值。

优点
 
1:一个调用者想创建一个对象,只要知道其名称就可以了。
2:扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3:屏蔽产品的具体实现,调用者只关心产品的接口。

缺点

每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

应用实例
 
1:您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
2:Hibernate 换数据库只需换方言和驱动就可以。

具体Demo,例子很简单,根据类型绘制对应类型的图片

protocol DrawShape{    func draw()}//长方形class Rectangle:DrawShape{    func draw() {        print("draw a rectangle!")    }}//圆形class Circle:DrawShape{    func draw() {        print("draw a circle!")    }}//正方形class Square:DrawShape{    func draw() {        print("draw a square!")    }}//图形类型enum ShapeType{     case rectangle,circle,square}//绘制图形工厂class ShapeFactory{  static func getShapeWithType(type: ShapeType) -> DrawShape?{        switch type {        case .rectangle:            return Rectangle()        case .circle:            return Circle()        case .square:            return Square()        default:            return  nil        }    }}
使用如下:

override func viewDidLoad() {        super.viewDidLoad()                //获取对应类型的实例并执行绘制        let shape1 = ShapeFactory.getShapeWithType(type: ShapeType.rectangle)        shape1?.draw()                let shape2 = ShapeFactory.getShapeWithType(type: ShapeType.circle)        shape2?.draw()                let shape3 = ShapeFactory.getShapeWithType(type: ShapeType.square)        shape3?.draw()                /*         打印结果如下:         draw a rectangle!         draw a circle!         draw a square!         */    }




0 0