vendredi 11 juin 2021

Advice on inheritance / architecture in javascript

In order to access to my collections in mongodb, I don't use a third party framework, I use the nodejs mongodb package directly. To do so, for each of my collections in the db, I create a model file that look like this :

const Table = "Home";

let driverPromise;

module.exports = function(driver) {

    driverPromise = driver;

    this.getById = getByIdAsync;

    this.update = updateAsync;

    this.getByIdAsync = getByIdAsync;
    this.updateAsync = updateAsync;
    this.deleteAsync = deleteAsync;
    this.deleteAllAsync = deleteAllAsync;
    this.findAllAsync = findAllAsync;
    this.findOneAsync = findOneAsync;
    this.saveAsync = saveAsync;
};


function getByIdAsync(_id) {
    return driverPromise
        .then(driver =>  driver.getByIdAsync(Table, _id))
}

function updateAsync(value) {
    return driverPromise
        .then(driver =>  driver.updateAsync(Table, value, value._id));
}

function deleteAsync(_id) {
    return driverPromise
        .then(driver =>  driver.deleteAsync(Table, _id));
}

function deleteAllAsync(criteria) {
    return driverPromise
        .then(driver =>  driver.deleteAllAsync(Table, criteria));
}

function saveAsync(value) {
    return driverPromise
        .then(driver =>  driver.saveAsync(Table, value));
}

function findAllAsync(criteria) {
    return driverPromise
        .then(driver =>  driver.findAllAsync(Table, criteria));
}

function findOneAsync(criteria) {
    return driverPromise
        .then(driver =>  driver.findOneAsync(Table, criteria));
}

The name of the Collection, different for each file, is define in the cont Table, and then comes the classic CRUD functions, shared in all the model files. What is then exported is... well, I don't know exactly what is is, but it works o_O

To use those files, I would first create, at init time, an instance of it cont home = new Home(driver) and then use it in my app like const result = await home.findOneAsync({name : 'toto'}) That works fine....

The probleme is, I do this for each collection, meaning that I have a bunch of file that looks exactly the same only difference is the name of the collection! That's enought of a concern already, but also if I want to add a method like 'aggregateAsync' I have to update all the files :'( of course I still need some flexibility because some collection have extra methods, like the User that has bcryptjs capabilities, or Orders where I added a special aggregation pipeline for the reporting....

So my question is, how can I implement a better design pattern that would mutualise the base function (getById, findOneAsync...) and where I can create kind of subclasses that inherits those function but with each their own collection name and can possibly be extended with some extra functions?

Aucun commentaire:

Enregistrer un commentaire