Android设计模式—工厂模式

1.工厂模式
工厂模式是一种创建型设计模式,多用于需要生成复杂对象的地方(工厂模式就是用来创造对象的)。

工厂模式的意图:定义一个接口来创建对象,但是让子类来决定哪些类需要被实例化,即工厂方法把实例化的工作推迟到子类中去实现。工厂模式降低了对象之间的耦合,由于工厂模式依赖抽象的架构,实例化的任务交由子类去完成,所以有很好的扩展性。

工厂模式分为三类:简单工厂模式、工厂方法模式、抽象工厂模式。
①简单工厂模式只有一个工厂类、一个抽象产品类和多个具体产品类,在工厂类中生成各个具体产品。即一家工厂根据给定的(传入的)不同的材料(参数)生产出具体不同种类的产品。
②工厂方法模式有一个抽象工厂类,派生出可以生产多种产品的工厂类;有一个抽象产品类,派生出多种具体的产品;一个工厂负责生产一种具体的产品。
③工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。

2.简单工厂模式
简单工厂模式又称为静态工厂模式,就是通过一个工厂类来创建其他类的实例。但是具体创建过程对用户是不可见的。

简单工厂模式的类图:
简单工厂模式的uml图
Factory : 工厂类,负责实现创建所有产品实例的内部逻辑,即负责生产具体的产品。工厂类可以被外界直接调用,创建所需的产品对象。
Product: 抽象产品类,是工厂类创建的所有对象的父类,封装了各种产品对象的公共方法,即负责描述所有实例所共有的公共接口。抽象产品的引入提高了系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品都是其子类对象。
P1、P2: 具体产品类,它是简单工厂模式的创建目标,所有被创建的对象都是某个具体类的实例。每个具体产品类都继承了抽象产品类,需要实现抽象产品中声明的抽象方法。

简单工厂模式的基本流程是:
①将需要创建各种不同对象的相关代码封装到不同的类中,这些类称为具体的产品类。
②将它们公共的代码进行抽象和提取后封装在一个抽象产品类中,每一个具体的产品类都是这个抽象产品类的子类。
③提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的方法,该方法可以根据传入的参数创建出不同的具体产品对象。
④客户端只需要调用工厂类的方法并传入相应的参数即可得到一个具体的产品对象。

简单工厂模式主要用来解决创建实例的问题。它通过不同的参数来创建不同的对象,并隐藏了对象的创建逻辑,避免暴露给调用方。

举个例子来说明:
有一个形状(Shape)接口,包含一个方法sayHello()用来输出自己的信息,现在有3种形状:圆、三角形、矩形。
抽象产品 Shape.java:
public interface Shape {
void sayHello();
}
具体产品类:
Circle.java:
public class Circle implements Shape {
@Override
public void sayHello() {
System.out.println(“I am circle”);
}
}
Triangle.java:
public class Triangle implements Shape {
@Override
public void sayHello() {
System.out.println(“I am triangle”);
}
}
Rectangle.java:
public class Rectangle implements Shape {
@Override
public void sayHello() {
System.out.println(“I am rectangle”);
}
}
如果不使用工厂模式,像下面这样,每种形状直接用new生成,会造成客户端与具体的产品类耦合:
Shape circle = new Circle();
circle.sayHello();
Shape rectangle = new Rectangle();
rectangle.sayHello();

现在看看使用简单工厂模式的写法:
工厂类 ShapeFactory.java:
public class ShapeFactory {
public static final String CIRCLE = “circle”;
public static final String RECTANGLE = “rectangle”;
public static final String TRIANGLE = “triangle”;

public static Shape createShape(String name) {
Shape shape = null;
if (name == null)
throw new NullPointerException();
if (name.equals(CIRCLE)) {
shape = new Circle();
} else if (name.equals(RECTANGLE)) {
shape = new Rectangle();
} else if (name.equals(TRIANGLE)) {
shape = new Triangle();
}
return shape;
}
}
简单工厂类通过静态方法createShape创建抽象产品Shape,通过name指定创建哪种形状。
client端可以这样使用工厂类:
Shape shape = ShapeFactory.createShape( ShapeFactory.CIRCLE);
shape.sayHello();
这样client端都看不到Circle类,只是传入circle就可以得到一个圆形(由于client中看不到Circle类,这就是在解耦)。

由于ShapeFactory是根据字符串来创建所需要的类,如果和Java的反射机制相结合,可以设计出更加解耦的系统。例如在ShapeFactory中直接使用反射构造类,那么name就需要传入具体的包名+类名。
public class ShapeFactory {
public Shape createShape(Class <? extends Shape> clazz){
Shape shape = null;
try {
shape = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return shape;
}
}

简单工厂模式优点:
①工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,避免客户端直接创建产品对象。 这样就实现了对责任的分割,它提供了专门的工厂类用于创建对象。
②客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可; 对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
③通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

简单工厂模式的缺点:
①由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
②违背开闭原则,扩展困难。一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
③简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

3.工厂方法模式
为了解决简单工厂模式的缺点,工厂方法模式把具体产品的创建推迟到工厂类的子类(具体工厂)中,此时工厂类不再负责所有产品的创建,而只是给出具体工厂必须实现的接口。

工厂方法模式的重点在于,产品和工厂是同级的,一类具体的产品对应一个工厂。
①一个抽象产品,派生出多种具体的产品
②一个抽象工厂,派生出多种生产产品的工厂类
③一个具体的工厂负责生产一种具体的产品

工厂方法模式的uml图
AbstractProduct:抽象的产品类
ProductA:具体的A产品
ProductB:具体的B产品
AbstractFactory:抽象工厂类
FactoryA:具体的生产A产品的工厂类
FactoryB:具体的生产B产品的工厂类
Client: 客户端类

还是上面的例子:
抽象工厂类 ShapeFactory.java:
public interface ShapeFactory {
Shape createShape();
}

具体工厂类 CircleFactory.java:
public class CircleFactory implements ShapeFactory {
@Override
public Shape createShape() {
return new Circle();
}
}

具体工厂类 RectangleFactory.java:
public class RectangleFactory implements ShapeFactory {
@Override
public Shape createShape() {
return new Rectangle();
}
}

具体工厂类 TriangleFactory.java:
public class TriangleFactory implements ShapeFactory {
@Override
public Shape createShape() {
return new Triangle();
}
}

client调用时,首先创建具体的工厂,然后由具体的工厂去创建对应的具体产品:
ShapeFactory factory = new CircleFactory();
Circle circle = factory.createShape();
circle.sayHello();

工厂方法模式的扩展性很强,例如现在还要添加一种新的形状,只需添加对应的形状和工厂类即可。例如增加五角星类:
Star.java:
public class Star implements Shape {
@Override
public void sayHello() {
System.out.println(“I am Star”);
}
}
StarFactory.java:
public class StarFactory implements ShapeFactory {
@Override
public Shape create() {
return new Star();
}
}
如果现在要添加的不是全新的形状呢?比如正三角形、直角三角形?这时就需要添加新的工厂了,直接继承三角形Triangle就行,因为它们是属于三角形这个大类的,如果再添加工厂,不仅类太多,也损失了它们本来就是三角形的一种的特性。

工厂方法模式的优点:
①更符合开闭原则,扩展性好。新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可,而简单工厂模式需要修改工厂类的判断逻辑。
②符合单一职责原则。每个具体工厂只负责创建对应的产品,而简单工厂模式的工厂类中存在复杂的switch判断。
③不使用静态工厂方法,可以形成基于继承的等级结构,而简单工厂模式的工厂类使用了静态工厂方法。

工厂方法模式的缺点:
①类的个数较多。增加新产品类时,要提供对应的具体工厂类和具体产品类。

4.抽象工厂模式
抽象工厂模式在工厂方法模式的基础上添加了产品族的概念。
抽象工厂模式用于生产多个产品的组合对象:多个抽象产品分别派生出多个具体的产品,一个抽象工厂派生成多个具体的工厂,一个工厂对应生成多个具体的产品,这些多个抽象产品之间存在着联系。
①多个抽象产品类,每个抽象产品类可以派生出多个具体产品类
②一个抽象工厂类,派生出多个具体工厂类
③每个具体工厂类可以创建多个具体产品类的实例
抽象工厂uml图
AbstractFactory:抽象工厂类
ConcreteFactoryA:具体工厂1,负责生产A和B的
ConcreteFactoryB:具体工厂2,负责生产A和B的
AbstractProductA,AbstractProductB:抽象的产品类
ConcreteProductA1,ConcreteProductA2:具体产品A
ConcreteProductB1,ConcreteProductB1:具体产品B
Client:客户端

还是上面的例子:
现在ShapeFactory是一个制造带颜色的形状的工厂类,它是一个抽象工厂,提供了一个产品族(形状、颜色)的创建接口。具体的实现交给子类去实现,例如创建红色的圆、白色的圆、红色三角形、白色三角形等。其实可以发现工厂方法模式蕴含其中,把颜色和形状拆开,就是工厂方法模式。
抽象工厂模式的优点就在于,提供了一个更加抽象的产品构造,即产品是由产品族组成的,至于怎么组成,需要自己去实现,而它只定义这类抽象产品族到底有哪些。
抽象产品1— Shape.java:
public interface Shape {
void sayHello();
}
Circle.java:
public class Circle implements Shape {
@Override
public void sayHello() {
System.out.println(“I am circle”);
}
}
Triangle.java:
public class Triangle implements Shape {
@Override
public void sayHello() {
System.out.println(“I am triangle”);
}
}
Rectangle.java:
public class Rectangle implements Shape {
@Override
public void sayHello() {
System.out.println(“I am rectangle”);
}
}

抽象产品2—Color.java:
public interface Color {
void sayHello();
}
Red.java:
public class Red implements Color{
@Override
public void sayHello() {
System.out.println(“in Red”);
}
}
White.java:
public class White implements Color{
@Override
public void sayHello() {
System.out.println(“in White”);
}
}

抽象工厂 ShapeFactory.java:
public interface ShapeFactory {
Shape createShape();
Color createColor();
}
具体工厂 RedCircleFactory .java:
public class RedCircleFactory implements ShapeFactory {
@Override
public Shape createShape() {
return new Circle();
}
@Override
public Color createColor() {
return new Red();
}
}

WhiteCircleFactory.java:
public class WhiteCircleFactory implements ShapeFactory {
@Override
public Shape createShape() {
return new Circle();
}
@Override
public Color createColor() {
return new White();
}
}

client调用:
RedCircleFactory redCircleFactory = new RedCircleFactory();
Shape circle = redCircleFactory.createShape();
Color red = redCircleFactory.createColor();
Log.e("", circle +red);

现在系统已经很健全了,不再只是图形,只要与图形相关的事宜的对象,由不同的工厂具体去实现就可以。

工厂方法模式和抽象工厂模式的对比:
①工厂方法模式是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂方法模式的推广;
②工厂方法模式用来创建一个产品的等级结构,而抽象工厂模式是用来创建多个产品的等级结构;
③工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。

5.总结
简单工厂模式注重具体生成的产品;
工厂方法模式注重同一个产品下的不同产品族的产品;
抽象工厂模式更多是在与整体产品的架构上,不再是单一一个抽象产品类。

单一产品对象并且不涉及到扩展的话,用简单工厂模式。
单一产品对象并且涉及到扩展的话,用工厂方法模式。
多个产品对象用抽象工厂模式。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值