We're going to see now how types and factories are created and used in Obix. This will be illustrated by the example of a bank account. To keep the exercise simple, the objects we will create will be a bit simplified compared to objects in a real-world application. The goal is to quickly get a general insight and discover important concepts that are necessary to write more reliable code in less time.
![]() | Note |
|---|---|
In the following paragraphs there will be a number of links to Obix's programming manual. These links are provided for the reader who immediately wants more information about the treated subject. However, it is not necessary to visit each link before continuing reading. You can skip the links if you just want to quickly get an overview about how to program in Obix. |
Our example will be based on the following specifications:
Every bank account is assigned to one customer with attributes identifier, name and city.
A bank account allows two operations: pay_in and withdraw.
Amounts are expressed in cents and stored as integers.
A negative account balance is not allowed. A customer cannot withdraw more money than available. No credits!
The initial balance of a new account is 0.
Types, factories and services are stored in logically organized libraries (similar to packages in Java, or namespaces in C#). Obix uses the file system for storing libraries and there components. The physical structure of the directories reflects the logical structure of the libraries. A new library is created by simply creating a new directory whose name must be equal to the library's prefixed identifier. For more information on libraries, see the section called “Libraries” in the programming manual.
Let's create a new library for our purpose and choose li_bank as its identifier.
Create directory li_bank as a sub-directory of the existing directory programming/source_code/li_explore under the root directory of Obix (e.g. /usr/local/obix/programming/source_code/li_explore/li_bank on Linux and Unix, or
c:\program files\obix\programming\source_code\li_explore\li_bank on Windows). The structure should look like this:

Let's now create type bank_customer. Select Source code / Create new ... from the menu and enter the following code:
type bank_customer default_factory:yes attribute identifier type:positive32 end attribute name type:string end attribute city type:string end end type
Save the text into file ty_customer.osc in directory li_bank. That's all for the type.
![]() | Note |
|---|---|
| For more information on types, see the section called “Type” in the programming manual. |
You may now want to compile the code to be sure there is no syntax error. Select Compiler / Compile all from the menu.
How would a new customer be created? In Obix, objects are always created with factories. However, in our case we don't need to explicitly define a factory for creating bank_customer objects. The default_factory:yes clause in the type instructs the compiler to automatically create factory fa_bank_customer.
![]() | Note |
|---|---|
For more information on the default_factory:yes clause, see Table 5.1, “Type” in the programming manual. |
A new customer could now be created and stored in a variable like this:
var bank_customer customer_giovanni=
fa_bank_customer.co_create
( &
identifier = 28
& name = "Giovanni Spiridigliotzky"
& city = "Rome"
)
| declare variable |
| assignment operator |
| use creator command |
|
|
| assign the value |
| assign |
| assign |
| In Obix, instructions must not be terminated with an |
We can now proceed with the bank account. First enter the following code and save it in file ty_bank_account.osc of directory li_bank:
type bank_account end type
Each account is assigned to one customer. Hence we add attribute customer:
type bank_account attribute customer type:bank_customer end end type
Another attribute of type bank_account is the account's balance.
The initial balance of an account is 0. This is coded by setting property default to 0.
The value of balance can change over time; therefore property kind must be set to variable.
Attribute balance must be protected against setting it directly with and instruction such as account.balance = 1000. Only the factory is allowed to change the balance, whenever a pay_in or withdraw operation is executed. Therefore property setable is set to factory
This leads to the following code for attribute balance:
attribute balance type:zero_positive32 default:0 kind:variable setable:factory end
![]() | Note |
|---|---|
| For more information on the properties of attributes, see the section called “Attribute” in the programming manual. |
Finally we have to add commands pay_in and withdraw. Both commands take an amount as input argument. Command pay_in can be defined as:
command pay_in
in amount type:positive32 end
end commandwithdraw is similar to pay_in. Thus, the complete code for type bank_account becomes:
type bank_account
attribute customer type:bank_customer end
attribute balance type:zero_positive32 default:0 kind:variable setable:factory end
command pay_in
in amount type:positive32 end
end command
command withdraw
in amount type:positive32 end
end command
end typeWhenever a type has at least one command, Obix cannot provide a default implementation for the factory. So we have to create factory bank_account ourselves.
Create the following code and save it into file fa_bank_account.osc in directory li_bank:
factory bank_account type:bank_account end factory
As we can easily see, we are creating factory bank_account that implements type bank_account.
Obix always provides a default implementation for attributes in factories. This default implementation is based on how the attributes are defined in the type. In our case the default implementation is suitable, so we don't have to code anything for the attributes in the factory.
Command pay_in is easy to implement. The account's balance is simply incremented by the amount paid in. Hence, the code looks like this:
command pay_in
script
a_balance = a_balance + i_amount
end script
end commandCommand withdraw is similar:
command withdraw
script
a_balance = a_balance - i_amount
end script
end commandWhat remains to be done is to define the following creator for factory bank_account:
creator create
in customer type:bank_customer end
out result type:bank_account end
script
o_result.a_customer = i_customer
o_result.a_balance = 0
end script
end creatorThe creator takes a bank_customer as input argument, and returns a bank_account as result.
The creator's script simply assigns input argument customer to attribute customer and sets attribute balance to 0.
Nothing needs to be done for attribute balance. Type bank_account specifies a default value of 0 for balance, therefore the compiler automatically initializes balance with 0.
The complete code for factory bank_account is as follows:
factory bank_account type:bank_account
command pay_in
script
a_balance = a_balance + i_amount
end script
end command
command withdraw
script
a_balance = a_balance - i_amount
end script
end command
creator create
in customer type:bank_customer end
out result type:bank_account end
script
o_result.a_customer = i_customer
o_result.a_balance = 0
end script
end creator
end factoryEnter the above code and save it in file fa_bank_account.osc. Then compile again to see if there are no errors.
![]() | Note |
|---|---|
| For more information on factories, see the section called “Factory” in the programming manual. |
We now have a first working solution. There are still some improvements neglected for the moment, but that will be fixed in a subsequent chapter. It's time now to test the code we have written so far. The next chapter introduces Obix's integrated facilities to test code.