function checkType(value, expectedType, propName) {
if (typeof value !== expectedType) {
throw new Error(`Invalid ${propName} type. Expected ${expectedType}.`);
}
}
function checkInstance(value, expectedInstance) {
if (!(value instanceof expectedInstance)) {
const expectedName = expectedInstance.constructor.name;
throw new Error(`Invalid type. Expected ${expectedName} instance.`);
}
}
class Person {
constructor(id, name, age, isActive, hobbies, address) {
checkType(id, 'number', "id");
checkType(name, 'string', "name");
checkType(age, 'number', "age");
checkType(isActive, 'boolean', "isActive");
checkType(hobbies, 'object', "hobbies");
checkInstance(address, Address);
this.id = id;
this.name = name;
this.age = age;
this.isActive = isActive;
this.hobbies = hobbies;
this.address = address;
}
}
class Address {
constructor(city, country, street) {
checkType(city, 'string', "city");
checkType(country, 'string', "country");
checkInstance(street, Street);
this.city = city;
this.country = country;
this.street = street;
}
}
class Street {
constructor(name, number, apartment) {
checkType(name, 'string', "name");
checkType(number, 'number', "number");
checkInstance(apartment, Apartment);
this.name = name;
this.number = number;
this.apartment = apartment;
}
}
class Apartment {
constructor(floor, number) {
checkType(floor, 'number', "floor");
checkType(number, 'number', "number");
this.floor = floor;
this.number = number;
}
}
class PersonBuilder {
constructor(personData) {
const person = this.#buildPerson(personData);
Object.assign(this, person);
}
#buildApartment(apartmentData) {
const { floor, number } = apartmentData;
return new Apartment(floor, number);
}
#buildStreet(streetData) {
const { name, number, apartment } = streetData;
const apartmentObj = this.#buildApartment(apartment);
return new Street(name, number, apartmentObj);
}
#buildAddress(addressData) {
const { city, country, street } = addressData;
const streetObj = this.#buildStreet(street);
return new Address(city, country, streetObj);
}
#buildPerson(personData) {
const { id, name, age, isActive, hobbies, address } = personData;
const addressObj = this.#buildAddress(address);
return new Person(id, name, age, isActive, hobbies, addressObj);
}
}
const personData = {
id: 1,
name: 'John Doe',
age: 30,
isActive: true,
hobbies:{},
address: {
city: 'Cityville',
country: 'Countryland',
street: {
name: 'Main Street',
number: 123,
apartment: {
floor: 2,
number: 201
}
}
}
};
const personBuilder = new PersonBuilder(personData);
console.log(personBuilder);
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter