Skip to main content

Composition Patterns

Zymba does not have classical inheritance (extends). Instead, use composition to build complex objects from simpler ones.

Delegation​

Embed one object inside another and delegate method calls:

ZYMBA
$Logger = new object() {
prefix;
construct($p) { $this.prefix = $p; }

log($msg) {
echo "[$this.prefix] $msg\n";
}
};

$UserService = new object() {
logger;
db;

construct($db) {
$this.logger = new $Logger("UserService");
$this.db = $db;
}

findUser($id) {
$this.logger.log("Finding user $id");
return $this.db.fetchOne(
@SQL.prepare("SELECT * FROM contacts WHERE ID = ?", $id),
true
);
}
};

Factory functions​

Create objects with a function instead of a class — useful when initialization requires complex logic:

ZYMBA
function $createApiClient($baseUrl, $apiKey) {
return new object() {
baseUrl = $baseUrl;
apiKey = $apiKey;

get($path) {
$headers = ["Authorization": "Bearer " . $this.apiKey];
$response = @HTTP.request($this.baseUrl . $path, "GET", null, $headers);
return @Var.fromJSON($response);
}

post($path, $data) {
$headers = [
"Authorization": "Bearer " . $this.apiKey,
"Content-Type": "application/json"
];
$body = @Var.toJSON($data);
$response = @HTTP.request($this.baseUrl . $path, "POST", $body, $headers);
return @Var.fromJSON($response);
}
};
}

$client = $createApiClient("https://api.example.com", "key123");

Mixin pattern​

Attach behaviors from multiple sources by augmenting an object's properties:

ZYMBA
function $withLogging($obj, $prefix) {
$obj.log = function($msg) use ($prefix) {
echo "[$prefix] $msg\n";
};
return $obj;
}

function $withValidation($obj) {
$obj.validateEmail = function($email) {
return $email ~= "/^[^@]+@[^@]+\\.[^@]+$/";
};
return $obj;
}

$service = new object() {
processUser($email) {
if (!$this.validateEmail($email)) {
$this.log("Invalid email: " . $email);
return false;
}
$this.log("Processing: " . $email);
return true;
}
};

$service = $withLogging($service, "UserSvc");
$service = $withValidation($service);
$service.processUser("[email protected]");

ZeyOS platform objects​

ZeyOS provides built-in object classes for entity management. These are covered in detail in Platform Integration.

@ZeyOS.Object​

Access database entities as objects:

ZYMBA
$item = new @ZeyOS.Object("items", $itemId);
$name = $item.getField("name");
$price = $item.getField("sellingprice");

@ZeyOS.ObjectTransaction​

Create and modify records with transactional safety:

ZYMBA
$tx = new @ZeyOS.ObjectTransaction();
$tx.setFields([
name: "New Product",
sellingprice: 29.99,
status: 1
]);
$tx.save();

@ZeyOS.TransactionContext​

Wrap multiple operations in an atomic transaction:

ZYMBA
with (new @ZeyOS.TransactionContext) {
$order = new @ZeyOS.ObjectTransaction(@orderId);
$order.book();

for ($lineItems as $item) {
$itemTx = new @ZeyOS.ObjectTransaction();
$itemTx.setFields($item);
$itemTx.save();
}
}