在软件开发中,对象的创建是一个常见且基础的操作。然而,直接在代码中硬编码对象的创建过程会导致代码的耦合度增加,可维护性和可扩展性变差。工厂模式作为一种创建型设计模式,能够很好地解决这些问题。它将对象的创建和使用分离,使得代码更加灵活、易于维护。本文将详细介绍 Lua 中工厂模式的概念、实现方式以及应用场景,并给出相应的演示代码。
工厂模式是一种创建对象的设计模式,它提供了一种创建对象的方式,将对象的创建逻辑封装在一个工厂类(或函数)中,而不是在使用对象的地方直接创建。这样做的好处是:
工厂模式主要分为三种类型:简单工厂模式、工厂方法模式和抽象工厂模式。下面我们将分别介绍这三种模式在 Lua 中的实现。
简单工厂模式是工厂模式的最简单形式,它定义了一个工厂函数,根据传入的参数来创建不同类型的对象。
-- 定义不同类型的对象类
local Circle = {}
function Circle:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end
function Circle:draw()
print("Drawing a circle.")
end
local Rectangle = {}
function Rectangle:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end
function Rectangle:draw()
print("Drawing a rectangle.")
end
-- 简单工厂函数
local ShapeFactory = {}
function ShapeFactory.createShape(shapeType)
if shapeType == "circle" then
return Circle:new()
elseif shapeType == "rectangle" then
return Rectangle:new()
else
return nil
end
end
-- 使用简单工厂创建对象
local circle = ShapeFactory.createShape("circle")
circle:draw()
local rectangle = ShapeFactory.createShape("rectangle")
rectangle:draw()
Circle
和 Rectangle
,它们都有一个 draw
方法用于绘制图形。ShapeFactory.createShape
,根据传入的 shapeType
参数来创建不同类型的对象。draw
方法。工厂方法模式将对象的创建延迟到子类中进行,每个具体的子类负责创建特定类型的对象。这样,当需要添加新的对象类型时,只需要创建一个新的子类即可,不需要修改原有的工厂类。
-- 定义抽象工厂类
local ShapeFactory = {}
function ShapeFactory:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end
function ShapeFactory:createShape()
error("This method must be overridden!")
end
-- 定义具体的工厂子类
local CircleFactory = ShapeFactory:new()
function CircleFactory:createShape()
local Circle = {}
function Circle:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end
function Circle:draw()
print("Drawing a circle.")
end
return Circle:new()
end
local RectangleFactory = ShapeFactory:new()
function RectangleFactory:createShape()
local Rectangle = {}
function Rectangle:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end
function Rectangle:draw()
print("Drawing a rectangle.")
end
return Rectangle:new()
end
-- 使用工厂方法创建对象
local circleFactory = CircleFactory:new()
local circle = circleFactory:createShape()
circle:draw()
local rectangleFactory = RectangleFactory:new()
local rectangle = rectangleFactory:createShape()
rectangle:draw()
ShapeFactory
,其中的 createShape
方法是一个抽象方法,需要在子类中实现。CircleFactory
和 RectangleFactory
,分别负责创建圆形和矩形对象。draw
方法。抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。它可以创建多个不同类型的对象,这些对象通常属于同一个产品族。
-- 定义抽象产品类
local Shape = {}
function Shape:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end
function Shape:draw()
error("This method must be overridden!")
end
local Color = {}
function Color:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end
function Color:fill()
error("This method must be overridden!")
end
-- 定义具体产品类
local Red = Color:new()
function Red:fill()
print("Filling with red color.")
end
local Blue = Color:new()
function Blue:fill()
print("Filling with blue color.")
end
local Circle = Shape:new()
function Circle:draw()
print("Drawing a circle.")
end
local Rectangle = Shape:new()
function Rectangle:draw()
print("Drawing a rectangle.")
end
-- 定义抽象工厂类
local AbstractFactory = {}
function AbstractFactory:new()
local obj = {}
setmetatable(obj, self)
self.__index = self
return obj
end
function AbstractFactory:createShape()
error("This method must be overridden!")
end
function AbstractFactory:createColor()
error("This method must be overridden!")
end
-- 定义具体工厂类
local RedCircleFactory = AbstractFactory:new()
function RedCircleFactory:createShape()
return Circle:new()
end
function RedCircleFactory:createColor()
return Red:new()
end
local BlueRectangleFactory = AbstractFactory:new()
function BlueRectangleFactory:createShape()
return Rectangle:new()
end
function BlueRectangleFactory:createColor()
return Blue:new()
end
-- 使用抽象工厂创建对象
local redCircleFactory = RedCircleFactory:new()
local redCircle = redCircleFactory:createShape()
local red = redCircleFactory:createColor()
redCircle:draw()
red:fill()
local blueRectangleFactory = BlueRectangleFactory:new()
local blueRectangle = blueRectangleFactory:createShape()
local blue = blueRectangleFactory:createColor()
blueRectangle:draw()
blue:fill()
Shape
和 Color
,以及它们的具体产品类 Circle
、Rectangle
、Red
和 Blue
。AbstractFactory
,其中包含两个抽象方法 createShape
和 createColor
。RedCircleFactory
和 BlueRectangleFactory
,分别负责创建红色圆形和蓝色矩形的产品组合。模式名称 | 特点 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
简单工厂模式 | 一个工厂函数根据参数创建不同类型的对象 | 实现简单,降低耦合度 | 工厂函数职责过重,不符合开闭原则 | 对象类型较少,创建逻辑简单的场景 |
工厂方法模式 | 将对象的创建延迟到子类中进行 | 符合开闭原则,易于扩展 | 类的数量增加,代码复杂度提高 | 需要频繁添加新对象类型的场景 |
抽象工厂模式 | 提供创建一系列相关对象的接口 | 可以创建一系列相关对象,保证兼容性,符合开闭原则 | 类的数量大幅增加,代码复杂度高 | 需要创建多个相关对象,且这些对象属于同一个产品族的场景 |
通过本文的介绍,我们了解了 Lua 中工厂模式的三种类型:简单工厂模式、工厂方法模式和抽象工厂模式。每种模式都有其适用的场景,我们可以根据实际需求选择合适的模式来提高代码的可维护性和可扩展性。