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();
}
}