How to Quickly Generate Simple Examples for Immersing Beginners in a Complex Product

Hello! I am Nikita Shcherbo, a developer at Bitrix24.

Today I will share a small case with you — I will tell you how we used AI to generate simple examples for training employees on how to work with Service Locator.

This idea might be useful for those who conduct onboarding for newcomers, train them to use new tools, or immerse them in a particular product.

So, we all know that AI can generate code, tests, and documentation. We had the reverse task — given the code, documentation, and tests, create simple and understandable examples of how to use the tool.

I have 30 people on my team — many newcomers who joined us from "Bitrix24 // University," and there are those who have been working with Service Locator for a long time but were not interested in how the mechanism works. We decided to organize a general meetup for the team and show how this solution can be used in our tasks.

However, it turned out that we did not have simple and understandable examples. Extracting them from the internal product code was unrealistic — without context, they made no sense.

The tests for Service Locator, which we also wrote with AI a year ago, were not intended for human reading, so they were of no use to newcomers.

There was only one option left — to feed the AI everything we had and ask it to generate examples using simple and understandable entities, like in programming textbooks — little cars, animals, etc.

Here’s how it went:

1. We fed the neural network the existing information and explained the task.

What we provided to the AI:

  • A folder with the codes of the Service Locator itself

  • Internal documentation on it, essentially — a user manual, a superficial description of what needs to be written in the code to use the tool.

  • A set of tests that covered all the technical functionality of the Service Locator.

Then, literally after a few iterations, we created 9 files with clear educational examples for each use case of the Service Locator. In the first example, the AI learned to produce the desired result with my prompts, and all the others were generated independently.

As a result, we obtained simple examples, at the level of a primer, on abstract but quite understandable entities — those little machines and creatures.

2. Using AI agents, we collected real examples for a number of cases

This required my knowledge — as a developer, I know how Service Locator is applied within our products. I also used our internal tools based on AI agents. The agents know where each piece of code is located and can utilize that context. They helped find the necessary examples in the source codes of our product.

I did not add real examples for all cases — in some instances it was redundant or impossible.

3. Result: we obtained 9 files with clear examples that illustrate all variations of the use of Service Locator.

I will provide a few examples to show how well the neural network handled the task.

Example with sending SMS

This is almost a standard example, a typical task that any developer would understand. This example was completely devised by the neural network; it clearly explains how to write code that sends an SMS using Service Locator.

We implement this task differently in our product, but I left this example for training newcomers.

// --- 1. Class declarations ---

/**
 * Configuration class (Dependency).
 * Stores the API key needed for operation.
 */
class ApiKeyConfig
{
	public string $key = 'SECRET_KEY_999';
}

/**
 * Implementation of the service (SmsSender).
 * Depends on ApiKeyConfig, which must be passed to the constructor.
 */
class SmsSender
{
	private ApiKeyConfig $config;

	public function __construct(ApiKeyConfig $config)
	{
		$this->config = $config;
	}

	public function send(string $msg): void
	{
		echo "SMS: '{$msg}' (using key {$this->config->key})" . PHP_EOL;
	}
}

// --- 2. ServiceLocator configuration ---

$serviceLocator = ServiceLocator::getInstance();

// Registering the sending service
// In 'constructorParams', we explicitly indicate what needs to be passed to the SmsSender constructor.
$serviceLocator->addInstanceLazy(SmsSender::class, [
	'className' => SmsSender::class,
	'constructorParams' => [
		new ApiKeyConfig(),
	],
]);

// --- 3. Usage ---

// Requesting the service by interface.
$service = $serviceLocator->get(SmsSender::class);

$service->send('Hello, Bitrix!');

Mixed dependencies

This is one of the strongest examples — the neural network described in it the most important capability of Service Locator, the implementation of mixed dependencies. If I had to come up with such an example, I would have to write a large amount of code and come up with classes, but the AI did everything for me.

// --- 1. Different types of dependencies ---

// A. Concrete class (Locator will create it itself)
class HttpClient
{
	public function getName(): string
	{
		return 'CurlClient';
	}
}

// B. Abstract class (Registration needed)
abstract class AbstractCache
{
	abstract public function getName(): string;
}

// Can be used
class RedisCache extends AbstractCache
{
	public function getName(): string
	{
		return 'Redis';
	}
}

class MemcacheCache extends AbstractCache
{
	public function getName(): string
	{
		return 'Memcache';
	}
}

// C. Interface (Registration needed)
interface LoggerInterface
{
	public function getName(): string;
}

class FileLogger implements LoggerInterface
{
	public function getName(): string
	{
		return 'FileLog';
	}
}

// D. Main class (Locator will create it by pulling dependencies)
class AppManager
{
	public function __construct(
		public HttpClient $http, // Will find it
		public AbstractCache $cache, // Will take from config
		public LoggerInterface $log // Will take from config
	)
	{
	}
}

// --- 2. Configuration ---

$serviceLocator = ServiceLocator::getInstance();

// Register ONLY abstractions and interfaces
$serviceLocator->addInstanceLazy(AbstractCache::class, ['className' => MemcacheCache::class]);
$serviceLocator->addInstanceLazy(LoggerInterface::class, ['className' => FileLogger::class]);

// AppManager and HttpClient do NOT need to be registered.

// --- 3. Usage ---

$app = $serviceLocator->get(AppManager::class);

echo "HTTP: {$app->http->getName()}, Cache: {$app->cache->getName()}, Log: {$app->log->getName()}" . PHP_EOL;

Circular Dependencies

This is a common problem, but it is also important to demonstrate with a clear example. Here, the AI honestly surprised me — it brought up not just anything, but the philosophical problem of the egg and the chicken! It explained the issue of circular dependency in a way that is quite understandable for anyone.

// --- 1. Classes with a cycle ---

class Chicken
{
	// Chicken depends on Egg
	public function __construct(public Egg $egg) {}
}

class Egg
{
	// Egg depends on Chicken
	public function __construct(public Chicken $chicken) {}
}

// --- 2. Usage ---

$serviceLocator = ServiceLocator::getInstance();

try {
	echo "Trying to get Chicken...\n";

	// We do not register the classes as they are concrete.
	// The locator will start creating Chicken -> see Egg -> start creating Egg -> see Chicken...
	// And here it will understand that Chicken is already in the process of being created.
	$chicken = $serviceLocator->get(Chicken::class);

} catch (CircularDependencyException $e) {
	echo "\nCaught an exception!\n";
	echo "Error type: " . get_class($e) . "\n";
	echo "Message: " . $e->getMessage() . "\n";

	// Usually the message looks like this:
	// "Cyclic dependency detected for service: Chicken -> Egg -> Chicken"
}

What did we achieve in the end

First of all, the AI helped generate examples faster — that's a fact.

I could come up with them in about an hour and a half, but the question is about quality — they probably wouldn't be as simple and relevant as the example with SMS or the chicken and the egg. I have long been hopelessly professional deformed; for me, simple things are no longer obvious, and obvious things are not simple). I would spend more effort looking for truly understandable examples at the textbook level.

But it’s much more interesting how much time, and more importantly — nerves, we saved for our newcomers. Of course, one could study the product code line by line and figure out how the service works over several days. But it's better to act systematically and start with the simple. Speaking of onboarding the guys who came to us after our own Bitrix24//University, we saved them several days by showing simple examples of using the Service Locator.

I would be glad if our idea of generating examples using AI turns out to be useful and helps you train new specialists faster!

Comments