Understanding the Design Patterns Used in The Leola Programming Language
class DatabaseConnection
{
private static instance: DatabaseConnection;
private constructor() { }
public static getInstance(): DatabaseConnection
{
if (!DatabaseConnection.instance)
{
DatabaseConnection.instance = new DatabaseConnection();
}
return DatabaseConnection.instance;
}
// Other methods and properties...
}
abstract class Animal
{
public abstract makeSound(): void;
}
class Dog extends Animal
{
public makeSound(): void
{
console.log("Woof!");
}
}
class Cat extends Animal
{
public makeSound(): void
{
console.log("Meow!");
}
}
class AnimalFactory
{
public static createAnimal(type: string): Animal
{
switch (type)
{
case "dog":
return new Dog();
case "cat":
return new Cat();
default:
throw new Error("Invalid animal type.");
}
}
}
// Usage
let dog: Animal = AnimalFactory.createAnimal("dog");
let cat: Animal = AnimalFactory.createAnimal("cat");
dog.makeSound(); // Output: Woof!
cat.makeSound(); // Output: Meow!
interface Observer
{
notify(data: any): void;
}
class Subject
{
private observers: Observer[] = [];
public addObserver(observer: Observer): void
{
this.observers.push(observer);
}
public removeObserver(observer: Observer): void
{
const index = this.observers.indexOf(observer);
if (index !== -1)
{
this.observers.splice(index, 1);
}
}
public notifyObservers(data: any): void
{
for (const observer of this.observers)
{
observer.notify(data);
}
}
}
class ConcreteObserver implements Observer
{
public notify(data: any): void
{
console.log("Received data:", data);
}
}
// Usage
const subject = new Subject();
const observer1 = new ConcreteObserver();
const observer2 = new ConcreteObserver();
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notifyObservers("Hello, observers!"); // Output:
// Received data: Hello, observers!
// Received data: Hello, observers!