工厂模式
工厂模式分为
- 简单(静态)工厂
- 工厂方法
- 抽象工厂
下面分别介绍这几总工厂模式
简单工厂 (静态工厂)
简单工厂模式其实并不算是一种设计模式,更多的时候是一种编程习惯。
定义
定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例具有共同的父类或接口。
适用场景
首先由于只有一个工厂类,所以工厂类中创建的对象不能太多,否则工厂类的业务逻辑就太复杂了,其次由于工厂类封装了对象的创建过程,所以客户端应该不关心对象的创建。总结一下适用场景:
- 需要创建的对象较少。
- 客户端不关心对象的创建过程。
以上就是简单工厂模式简单工厂模式的适用场景,下面看一个具体的实例。对于需要新增的类,我们就需要改变代码,这是简单工厂的一个不足之处。
实例
创建一个可以绘制不同形状的绘图工具,可以绘制圆形,正方形,三角形,每个图形都会有一个draw()方法用于绘图,不看代码先考虑一下如何通过该模式设计完成此功能。
圆形,正方形,三角形都属于一种图形,并且都具有draw方法,所以首先可以定义一个接口或者抽象类,作为这三个图像的公共父类,并在其中声明一个公共的draw方法
public interface Shape {
void draw();
}
圆形:
public class CircleShape implements Shape {
public CircleShape() {
System.out.println( "CircleShape: created");
}
@Override
public void draw() {
System.out.println( "draw: CircleShape");
}
}
正方形:
public class RectShape implements Shape {
public RectShape() {
System.out.println( "RectShape: created");
}
@Override
public void draw() {
System.out.println( "draw: RectShape");
}
}
三角形:
public class TriangleShape implements Shape {
public TriangleShape() {
System.out.println( "TriangleShape: created");
}
@Override
public void draw() {
System.out.println( "draw: TriangleShape");
}
}
工厂类实现:
public class ShapeFactory {
public static final String TAG = "ShapeFactory";
public static Shape getShape(String type) {
Shape shape = null;
if (type.equalsIgnoreCase("circle")) {
shape = new CircleShape();
} else if (type.equalsIgnoreCase("rect")) {
shape = new RectShape();
} else if (type.equalsIgnoreCase("triangle")) {
shape = new TriangleShape();
}
return shape;
}
}
如何使用工厂类:
//画圆形
Shape shape= ShapeFactory.getShape("circle");
shape.draw();
//画方形
Shape shape= ShapeFactory.getShape("rect");
shape.draw();
//画三角形
Shape shape= ShapeFactory.getShape("triangle");
shape.draw();
工厂方法
工厂方法模式是简单工厂的仅一步深化, 在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂。也就是说每个对象都有一个与之对应的工厂。
定义
定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。
适用场景
- 客户端不需要知道它所创建的对象的类。例子中我们不知道每个宠物具体叫什么名,只知道创建它的工厂名就完成了创建过程。
- 客户端可以通过子类来指定创建对应的对象。
以上场景使用于采用工厂方法模式。
比如在一家宠物店,里面有各种各样的宠物,构建宠物的工厂:
// 号称什么宠物都有
public interface AnimalFactory {
// 可以获取任何的宠物
Animal createAnimal();
}
主流的宠物,构建猫和狗的工厂(继承着所有宠物的工厂),
猫工厂:
// 继承着宠物工厂
public class CatFactory implements AnimalFactory {
@Override
// 创建猫
public Animal createAnimal() {
return new Cat();
}
}
狗工厂:
// 继承着宠物工厂
public class DogFactory implements AnimalFactory {
// 创建狗
@Override
public Animal createAnimal() {
return new Dog();
}
}
嗯,还有我们的实体类:猫、狗、动物(多态:猫和狗都是动物,可以直接用动物来表示了)
动物实体类:
public abstract class Animal {
// 所有的动物都会吃东西
public abstract void eat();
}
猫实体类:
public class Cat extends Animal {
// 猫喜欢吃鱼
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
狗实体类:
public class Dog extends Animal {
// 狗喜欢吃肉
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
跟宠物店老板说想要一只狗,宠物店老板就去找狗回来了:
// 去找狗工厂拿一只狗过来
AnimalFactory f = new DogFactory();
Animal a = f.createAnimal();
a.eat();
想要猫:
// 去找猫工厂拿一只猫过来
AnimalFactory ff = new CatFactory();
Animal aa = ff.createAnimal();
aa.eat();
如果想要一只蜥蜴呢?那就需要创建蜥蜴类和蜥蜴工厂类了:
// 要买蜥蜴..
AnimalFactory fff = new LizardFactory();
Animal aaa = ff.createAnimal();
aaa.eat();
综上,工厂方法的优缺点
优点:
- 客户端不需要在负责对象的创建,明确了各个类的职责
- 如果有新的对象增加,只需要增加一个具体的类和具体的工厂类即可
- 不会影响已有的代码,后期维护容易,增强系统的扩展性
缺点:
- 需要额外的编写代码,增加了工作量
抽象工厂
这个模式最不好理解,而且在实际应用中局限性也蛮大的,因为这个模式并不符合开闭原则。实际开发还需要做好权衡。
抽象工厂模式是工厂方法的仅一步深化,在这个模式中的工厂类不单单可以创建一个对象,而是可以创建一组对象。这是和工厂方法最大的不同点。
定义
提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。( 在抽象工厂模式中,每一个具体工厂都提供了多个工厂方法用于产生多种不同类型的对象)
抽象工厂和工厂方法一样可以划分为4大部分:
- AbstractFactory(抽象工厂)声明了一组用于创建对象的方法,注意是一组。
- ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建对象的方法,生成一组具体对象。
- AbstractProduct(抽象产品):它为每种对象声明接口,在其中声明了对象所具有的业务方法。
- ConcreteProduct(具体产品):它定义具体工厂生产的具体对象。下面还是先看一个具体实例。
现在需要做一款跨平台的游戏,需要兼容Android,Ios,Wp三个移动操作系统,该游戏针对每个系统都设计了一套操作控制器(OperationController)和界面控制器(UIController),下面通过抽闲工厂方式完成这款游戏的架构设计。
由题可知,游戏里边的各个平台的UIController和OperationController应该是我们最终生产的具体产品。所以新建两个抽象产品接口。
操作控制器:
public interface OperationController {
void control();
}
界面控制器
public interface UIController {
void display();
}
然后完成各个系统平台的具体操作控制器和界面控制器
Android:
public class AndroidOperationController implements OperationController {
@Override
public void control() {
System.out.println("AndroidOperationController");
}
}
public class AndroidUIController implements UIController {
@Override
public void display() {
System.out.println("AndroidInterfaceController");
}
}
IOS:
public class IosOperationController implements OperationController {
@Override
public void control() {
System.out.println("IosOperationController");
}
}
public class IosUIController implements UIController {
@Override
public void display() {
System.out.println("IosInterfaceController");
}
}
Wp:
public class WpOperationController implements OperationController {
@Override
public void control() {
System.out.println("WpOperationController");
}
}
public class WpUIController implements UIController {
@Override
public void display() {
System.out.println("WpInterfaceController");
}
}
下面定义一个抽象工厂,该工厂需要可以创建OperationController和UIController
public interface SystemFactory {
public OperationController createOperationController();
public UIController createInterfaceController();
}
在各平台具体的工厂类中完成操作控制器和界面控制器的创建过程
Android:
public class AndroidFactory implements SystemFactory {
@Override
public OperationController createOperationController() {
return new AndroidOperationController();
}
@Override
public UIController createInterfaceController() {
return new AndroidUIController();
}
}
IOS:
public class IosFactory implements SystemFactory {
@Override
public OperationController createOperationController() {
return new IosOperationController();
}
@Override
public UIController createInterfaceController() {
return new IosUIController();
}
}
Wp:
public class WpFactory implements SystemFactory {
@Override
public OperationController createOperationController() {
return new WpOperationController();
}
@Override
public UIController createInterfaceController() {
return new WpUIController();
}
}
客户端调用:
SystemFactory mFactory;
UIController interfaceController;
OperationController operationController;
//Android
mFactory=new AndroidFactory();
//Ios
mFactory=new IosFactory();
//Wp
mFactory=new WpFactory();
interfaceController=mFactory.createInterfaceController();
operationController=mFactory.createOperationController();
interfaceController.display();
operationController.control();
针对不同平台只通过创建不同的工厂对象就完成了操作和UI控制器的创建。小伙伴们可以对比一下,如果这个游戏使用工厂方法模式搭建需要创建多少个工厂类呢?下面总结一下抽象工厂的适用场景。
适用场景
- 和工厂方法一样客户端不需要知道它所创建的对象的类。
- 需要一组对象共同完成某种功能时。并且可能存在多组对象完成不同功能的情况。
- 系统结构稳定,不会频繁的增加对象。(因为一旦增加就需要修改原有代码,不符合开闭原则)
以上就是三种工厂模式的总结,如有不对之处还希望各位留言指正,以免误导他人。
网友评论