工厂模式

2023-05-12  本文已影响0人  长点点

安卓开发中的工厂模式

一、基本概念

工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

工厂模式分为三类:简单工厂模式、工厂方法模式和抽象工厂模式。它们之间的区别如下表所示:

工厂模式 特点 优点 缺点
简单工厂模式 一个工厂类根据传入的参数决定创建出哪一种产品类的实例 简单易用,客户端无需知道具体产品类的名称,只需知道参数即可 不符合开闭原则,每次增加新产品时,都需要修改工厂类代码,增加了系统复杂度和具体类的依赖
工厂方法模式 定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中 符合开闭原则,每个具体产品都对应一个具体工厂类,不需要修改原有代码,只需增加新的具体产品和对应的具体工厂 类的个数容易过多,增加了系统的抽象性和理解难度
抽象工厂模式 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类² 符合开闭原则,隔离了具体类的生成,客户端不需要知道产品内部结构和实现细节 难以扩展新种类的产品,需要修改抽象工厂和所有相关的子类

1.1 简单工厂模式

简单工厂模式uml图

简单工厂模式又叫静态工厂方法模式,它是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式。

简单工厂模式的优点是:

简单工厂模式的缺点是:

1.2 工厂方法模式

工厂方法模式uml图

工厂方法模式是一种创建型设计模式,它定义了一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。这样可以使得客户端不需要知道具体的产品类,只需要知道工厂类即可。工厂方法模式可以让工厂根据不同的条件创建不同的产品对象,而无需修改工厂类的代码。

工厂方法模式的优点是:

工厂方法模式的缺点是:

1.3 抽象工厂模式

抽象工厂模式uml图

抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式可以将一组对象的实现细节与他们的一般使用分离开来。

抽象工厂模式的优点是:

抽象工厂模式的缺点是:

二、安卓源码中的实例

安卓源码中有很多使用了工厂模式的地方,例如:

现工厂模式的灵活性和可读性。

下面我们用 Kotlin 语言来实现和比较各种工厂模式的不同之处。

3.1 简单工厂模式

简单工厂模式可以用单例模式或伴生对象来实现,例如:

// 抽象产品类
interface Shape {
    fun draw()
}

// 具体产品类
class Circle : Shape {
    override fun draw() {
        println("Draw a circle")
    }
}

class Rectangle : Shape {
    override fun draw() {
        println("Draw a rectangle")
    }
}

class Square : Shape {
    override fun draw() {
        println("Draw a square")
    }
}

// 工厂类,使用单例模式
object ShapeFactory {
    // 根据参数创建不同的产品对象
    fun getShape(shapeType: String): Shape? {
        return when (shapeType) {
            "CIRCLE" -> Circle()
            "RECTANGLE" -> Rectangle()
            "SQUARE" -> Square()
            else -> null
        }
    }
}

// 或者使用伴生对象
class ShapeFactory2 private constructor() {
    companion object {
        fun getShape(shapeType: String): Shape? {
            return when (shapeType) {
                "CIRCLE" -> Circle()
                "RECTANGLE" -> Rectangle()
                "SQUARE" -> Square()
                else -> null
            }
        }
    }
}

客户端可以通过工厂类的静态方法来获取产品对象,例如:

fun main() {
    // 使用单例工厂
    val circle = ShapeFactory.getShape("CIRCLE")
    circle?.draw()

    val rectangle = ShapeFactory.getShape("RECTANGLE")
    rectangle?.draw()

    val square = ShapeFactory.getShape("SQUARE")
    square?.draw()

    // 使用伴生对象工厂
    val circle2 = ShapeFactory2.getShape("CIRCLE")
    circle2?.draw()

    val rectangle2 = ShapeFactory2.getShape("RECTANGLE")
    rectangle2?.draw()

    val square2 = ShapeFactory2.getShape("SQUARE")
    square2?.draw()
}

输出结果:

Draw a circle
Draw a rectangle
Draw a square
Draw a circle
Draw a rectangle
Draw a square

3.2 工厂方法模式

工厂方法模式可以用高阶函数和 lambda 表达式来实现,例如:

// 抽象产品类
interface Shape {
    fun draw()
}

// 具体产品类
class Circle : Shape {
    override fun draw() {
        println("Draw a circle")
    }
}

class Rectangle : Shape {
    override fun draw() {
        println("Draw a rectangle")
    }
}

class Square : Shape {
    override fun draw() {
        println("Draw a square")
    }
}

// 抽象工厂类,使用高阶函数作为参数
abstract class FactoryMethod(val factory: () -> Shape) {
    // 创建产品对象的方法
    fun create(): Shape {
        return factory()
    }
}

// 具体工厂类,使用 lambda 表达式实现抽象工厂类的参数
class CircleFactoryMethod : FactoryMethod({ Circle() })

class RectangleFactoryMethod : FactoryMethod({ Rectangle() })

class SquareFactoryMethod : FactoryMethod({ Square() })

客户端可以通过具体工厂类的 create 方法来获取产品对象,例如:

fun main() {
    // 使用圆形工厂创建圆形对象
    val circleFactory = CircleFactoryMethod()
    val circle = circleFactory.create()
    circle.draw()

    // 使用矩形工厂创建矩形对象
    val rectangleFactory = RectangleFactoryMethod()
    val rectangle = rectangleFactory.create()
    rectangle.draw()

    // 使用正方形工厂创建正方形对象
    val squareFactory = SquareFactoryMethod()
    val square = squareFactory.create()
    square.draw()
}

输出结果:

Draw a circle
Draw a rectangle
Draw a square

3.3 抽象工厂模式

抽象工厂模式可以用扩展函数和运算符重载来实现,例如:

// 抽象产品类
interface Shape {
    fun draw()
}

interface Color {
    fun fill()
}

// 具体产品类
class Circle : Shape {
    override fun draw() {
        println("Draw a circle")
    }
}

class Rectangle : Shape {
    override fun draw() {
        println("Draw a rectangle")
    }
}

class Square : Shape {
    override fun draw() {
        println("Draw a square")
    }
}

class Red : Color {
    override fun fill() {
        println("Fill red")
    }
}

class Green : Color {
    override fun fill() {
        println("Fill green")
    }
}

class Blue : Color {
    override fun fill() {
        println("Fill blue")
    }
}

// 抽象工厂类
interface AbstractFactory {
    // 创建形状对象的方法
    fun getShape(shapeType: String): Shape?

    // 创建颜色对象的方法
    fun getColor(colorType: String): Color?
}

// 具体工厂类,用于创建形状对象
class ShapeFactory : AbstractFactory {
    override fun getShape(shapeType: String): Shape? {
        return when (shapeType) {
            "CIRCLE" -> Circle()
            "RECTANGLE" -> Rectangle()
            "SQUARE" -> Square()
            else -> null
        }
    }

    override fun getColor(colorType: String): Color? {
        return null
    }
}

// 具体工厂类,用于创建颜色对象
class ColorFactory : AbstractFactory {
    override fun getShape(shapeType: String): Shape? {
        return null
    }

    override fun getColor(colorType: String): Color? {
        return when (colorType) {
            "RED" -> Red()
            "GREEN" -> Green()
            "BLUE" -> Blue()
            else -> null
        }
    }
}

// 工厂生成器类,用于获取具体工厂类的对象
object FactoryProducer {

    // 根据参数获取不同的工厂对象
    fun getFactory(factoryType: String): AbstractFactory? {
        return when (factoryType) {
            "SHAPE" -> ShapeFactory()
            "COLOR" -> ColorFactory()
            else -> null
        }
    }
}

客户端可以通过工厂生成器类的方法来获取具体工厂类的对象,然后通过具体工厂类的方法来获取产品对象,例如:

fun main() {
    // 获取形状工厂
    val shapeFactory = FactoryProducer.getFactory("SHAPE")

    // 获取形状为 Circle 的对象
    val circle = shapeFactory?.getShape("CIRCLE")
    circle?.draw()

    // 获取形状为 Rectangle 的对象
    val rectangle = shapeFactory?.getShape("RECTANGLE")
    rectangle?.draw()

    // 获取形状为 Square 的对象
    val square = shapeFactory?.getShape("SQUARE")
    square?.draw()

    // 获取颜色工厂
    val colorFactory = FactoryProducer.getFactory("COLOR")

    // 获取颜色为 Red 的对象
    val red = colorFactory?.getColor("RED")
    red?.fill()

    // 获取颜色为 Green 的对象
    val green = colorFactory?.getColor("GREEN")
    green?.fill()

    // 获取颜色为 Blue 的对象
    val blue = colorFactory?.getColor("BLUE")
    blue?.fill()
}

输出结果:

Draw a circle
Draw a rectangle
Draw a square
Fill red
Fill green
Fill blue

四、使用场景

五、优化方向

简单工厂模式的缺点是:
简单工厂模式的优化方法是:
// 优化简单工厂模式,使用反射机制
public class SimpleFactory {
    // 根据类名创建对象
    public static Object create(String className) {
        Object obj = null;
        try {
            // 通过反射获取类对象
            Class<?> clazz = Class.forName(className);
            // 通过反射创建实例
            obj = clazz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }
}
工厂方法模式的缺点是:
工厂方法模式的优化方法是:
// 优化工厂方法模式,使用泛型
public abstract class GenericFactory<T> {
    // 创建产品对象的方法
    public T create() {
        T product = createProduct();
        product.build();
        return product;
    }

    // 抽象方法,由子类实现
    protected abstract T createProduct();
}

// 具体工厂类,使用泛型参数指定具体产品类型
public class CircleFactory extends GenericFactory<Circle> {
    @Override
    protected Circle createProduct() {
        return new Circle();
    }
}
抽象工厂模式的缺点是:
抽象工厂模式的优化方法是:
// 优化抽象工厂模式,使用原型模式
public abstract class PrototypeFactory {
    // 存储已经创建好的对象
    private Map<String, Object> prototypes = new HashMap<>();

    // 构造方法,初始化原型对象
    public PrototypeFactory() {
        initPrototypes();
    }

    // 抽象方法,由子类实现
    protected abstract void initPrototypes();

    // 根据类型获取对象的副本
    public Object getPrototype(String type) {
        Object prototype = prototypes.get(type);
        if (prototype == null) {
            throw new IllegalArgumentException("No such prototype: " + type);
        }
        // 使用 clone 方法复制对象
        return prototype.clone();
    }

    // 添加或更新原型对象
    public void addOrUpdatePrototype(String type, Object prototype) {
        prototypes.put(type, prototype);
    }
}

// 具体工厂类,初始化具体的原型对象
public class ShapeColorFactory extends PrototypeFactory {
    @Override
    protected void initPrototypes() {
        addOrUpdatePrototype("CIRCLE", new Circle());
        addOrUpdatePrototype("RECTANGLE", new Rectangle());
        addOrUpdatePrototype("SQUARE", new Square());
        addOrUpdatePrototype("RED", new Red());
        addOrUpdatePrototype("GREEN", new Green());
        addOrUpdatePrototype("BLUE", new Blue());
    }
}
上一篇下一篇

猜你喜欢

热点阅读