Я создаю приложение для планирования / планирования с использованием объектов. Я только новичок в объектно-ориентированном программировании, поэтому любые советы о том, как лучше структурировать мои классы, были бы очень полезны.
Основы программы
Программа состоит из «целей» и «контрольных точек». По сути, цель — это цель, а контрольные точки — это более мелкие шаги, которые необходимо выполнить для достижения этой цели. Все цели и контрольные точки имеют «крайние сроки» (сроки выполнения) и являются частью объекта календаря. В конце концов, я хотел бы сделать отображение календаря, которое показывает цели и контрольные точки.
Код
// 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);
}
}
}
}
```