What’s an Object Oriented method of writing an item Database?

As of recent, I’ve been experimenting with OOP on ROBLOX, and I’ve been trying to find an OO method of writing an item database. However, I’ve come to no avail. I’ll give an example, since many of you may not know what I’m talking about.

Typical Item Database (Example):

-- Module
local ItemDatabase = {
	-- Stored as keys and tables in order to be displayed by a client.
	Bat = {
		Name = "Bat";
		Price = 0;
		Image = "rbxassetid://0";
	}
}

-- Returning just like a typical ModuleScript
return ItemDatabase;

My attempt at an OOP Version (Another Example):

-- Item Class
local Item = {}
Item.__index = Item

function Item.new(Name)
	local self = {}
	setmetatable(self, Item)

	self.Name = Name

	-- add to item
	DatabaseModule:Set(Name, self)

	return self;
end

return Item;

-- subclass
local Bat = {}
Bat.__index = Bat
setmetatable(Bat, Item)

function Bat.new()
	local self = Item.new("Bat")
	
	setmetatable(self, Bat)

	return self
end

-- Database Module
local Module = {}
local Database = {}

function Module:Set(Key, Value)
	Database[Key] = Value
end

function Module:Get(Key)
	return Database[Key] or Database
end

return Module;

If anyone has any better solutions or ideas to add to this please tell me! :slight_smile:

You basically need a high-level serialization/deserialization implementation for your objects.

When it comes to OOP, objects have state and behavior. Typically, the “state” is stored as fields or properties, and behavior is defined via methods/functions. Of course, there might also be constants thrown in the mix too, as well as static members or whatever.

The important piece here is state. If you design your object correctly, you should be able to reconstruct the object given its state alone. In other words, an object’s state should be the only difference between itself and other objects of its own type. If two objects have the same state, they should be considered identical.

With that in mind, we can transform an object into a piece of data that can later be reused to recreate the object. Turning an object into a piece of flat data is called serialization. The process of transforming the data back into the object is called deserialization.

Thus, in order to save an object, we need to write a method to serialize the object. In the same manner, in order to load the object, we will need to write a method to deserialize the data.

From there, we can create a data module that utilizes the serialize/deserialize methods to properly save and load our objects. Here’s an example using the bat:

local Bat = {}
Bat.__index = Bat
setmetatable(Bat, Item)

function Bat.new()
	local self = Item.new("Bat")
	
	setmetatable(self, Bat)

	-- State:
	self.Age = 5
	self.Health = 100

	return self
end

function Bat:Serialize()
	return {
		Age = self.Age;
		Health = self.Health;
	}
end

-- NOTE: This is a 'static' method
function Bat.Deserialize(data)
	local bat = Bat.new()
	bat.Age = data.Age
	bat.Health = data.Health
	return bat
end

Notice that we added three things:

  1. We gave some ‘state’ to the bat (health and age, just as examples)
  2. We added a Serialize method to serialize the object
  3. We added a static Deserialize method to deserialize the data back into a bat

Now, in our data module, we could save and load the bats like this:

local Module = {}
local Database = {}

function Module:SetBat(key, bat)
	local data = bat:Serialize() -- Serialize the bat
	Database[key] = data
end

function Module:GetBat(key)
	local data = Database[key]
	if (data) then
		return Bat.Deserialize(data) -- Deserialize
	end
end
13 Likes