Объектно-ориентированное приложение-планировщик Javascript

Я создаю приложение для планирования / планирования с использованием объектов. Я только новичок в объектно-ориентированном программировании, поэтому любые советы о том, как лучше структурировать мои классы, были бы очень полезны.


Основы программы

Программа состоит из «целей» и «контрольных точек». По сути, цель — это цель, а контрольные точки — это более мелкие шаги, которые необходимо выполнить для достижения этой цели. Все цели и контрольные точки имеют «крайние сроки» (сроки выполнения) и являются частью объекта календаря. В конце концов, я хотел бы сделать отображение календаря, которое показывает цели и контрольные точки.


Код

// GUID generator
function uuidv4() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

// Adds add day feature to Date prototype
Date.prototype.addDays = function(days) {
    var date = new Date(this.valueOf());
    date.setDate(date.getDate() + days);
    return date;
}

// Parent object for all data
var calendar = {
    // Contains all objectives
    objectives: new Array(),
    // Checkpoints must be completed in order?
    strict: true,
    // Create objective, add to list, and sort list by deadline
    addObjective: function(name, deadline, description) {
        this.objectives.push(new Objective(name, deadline, description));
        this.sortObjectives();
    },
    getObjectives: function() {
        return this.objectives;
    },
    setStrict: function(strict) {
        this.strict = strict;
    },
    // Sort objectives by deadline, most recent last
    sortObjectives() {
        this.objectives.sort((a, b) => (a.deadline > b.deadline) ? 1 : -1);
    }
}

class Objective {
    constructor(name, deadline, description) {
        this.name = name;
        this.deadline = new Date(deadline);
        this.description = description;
        this.checkpoints = new Array();
        this.status = false;
        this.id = uuidv4();
    }
    // Push back deadline
    moveDeadline(days=0, moveAll=false) {
        this.deadline = this.deadline.addDays(days)
        // Move all checkpoints after current date unless incomplete
        if (moveAll) {
            let today = new Date();
            for (let i = 0; i < this.checkpoints.length; i++) {
                if (this.checkpoints[i].deadline < today || !this.checkpoints[i].status) {
                    this.checkpoints[i].deadline.addDays(days);
                }
            }
        }
    }
    // Remove objective from calendar object
    delete() {
        calendar.objectives.splice(calendar.objectives.indexOf(this), 1);
    }
    // Create checkpoint, add to list, sort order by deadline
    addCheckpoint(name, deadline, description) {
        this.checkpoints.push(new Checkpoint(name, deadline, description, this.id));
        this.sortCheckpoints();
    }
    getName() {
        return this.name;
    }
    setName(name) {
        this.name = name;
    }
    getDeadline() {
        return this.deadline.toDateString();
    }
    setDeadline(deadline) {
        this.deadline = new Date(deadline);
    }
    getDescription() {
        return this.description;
    }
    setDescription(description) {
        this.description = description;
    }
    getStatus() {
        return this.status;
    }
    // Checks whether all checkpoints are complete and determines status, invoked by Checkpoint.prototype.setStatus()
    setStatus() {
        let checkpoints = this.getCheckpoints();
        let allComplete = true;
        // Iterates through checkpoints
        for (let i = 0; i < checkpoints.length; i++) {
            // If at least one checkpoint is incomplete, objective status is false
            if (!checkpoints[i].status) {
                allComplete = false;
                break;
            }
        }
        if (allComplete) {
            this.status = true;
        }
        else {
            this.status = false;
        }
    }
    getCheckpoints() {
        return this.checkpoints;
    }
    getid() {
        return this.id;
    }
    // Sort checkpoints by deadline, most recent last
    sortCheckpoints() {
        this.checkpoints.sort((a, b) => (a.deadline > b.deadline) ? 1 : -1);
    }
}

class Checkpoint {
    constructor(name, deadline, description, id) {
        this.name = name;
        this.deadline = new Date(deadline);
        this.description = description;
        this.status = false;
        this.id = uuidv4();
        this.objectiveid = id;
    }
    // Push back deadline
    moveDeadline(days=0, moveAll=false) {
        this.deadline = this.deadline.addDays(days)
        // Move all checkpoints after this checkpoint deadline
        if (moveAll) {
            for (let i = 0; i < this.getObjective().getCheckpoints().length; i++) {
                if (this.getObjective().getCheckpoints()[i].deadline <= this.deadline && this.getObjective().getCheckpoints()[i] != this) {
                    this.getObjective().getCheckpoints()[i].deadline.addDays(days);
                }
            }
        }
    }
    // Remove checkpoint from objective object
    delete() {
        let objective = this.getObjective();
        objective.checkpoints.splice(objective.checkpoints.indexOf(this), 1);
    }
    getName() {
        return this.name;
    }
    setName(name) {
        this.name = name;
    }
    getDeadline() {
        return this.deadline.toDateString();
    }
    setDeadline(deadline) {
        this.deadline = new Date(deadline);
    }
    getDescription() {
        return this.description;
    }
    setDescription(description) {
        this.description = description;
    }
    getStatus() {
        return this.status;
    }
    // Update checkpoint status
    setStatus(status) {
        if (status == true) {
            if (calendar.strict) {
                let previousCheckpoints = this.getObjective().getCheckpoints().slice(0, this.getObjective().getCheckpoints().indexOf(this));
                let strictCondition = true;
                // Checks if all preceding checkpoints are completed if "strict" progress is enabled
                for (let i = 0; i < previousCheckpoints.length; i++) {
                    if (!previousCheckpoints[i].status) {
                        strictCondition = false;
                        break;
                    }
                }
                if (strictCondition) {
                    this.status = true;
                }
                else {
                    console.log('must complete preceding checkpoints');
                }
            }
            else {
                this.status = true;
            }
        }
        // No conditions for reverting checkpoint to incomplete
        else if (status == false) {
            this.status = false;
        }
        // Check objective status
        this.getObjective().setStatus();
    }
    getid() {
        return this.id;
    }
    getObjectiveid() {
        return this.objectiveid;
    }
    // Return reference to parent objective object
    getObjective() {
        for (let i = 0; i < calendar.objectives.length; i++) {
            let objective = calendar.objectives[i]
            if (objective.getid() == this.objectiveid) {
                return(objective);
            }
        }
    }
}
```

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *