I am reading this article about how you can organize JavaScript code for large projects.
I am attempting to write a simple events calendar as a way to play with some of these design patterns.
Using the module pattern I started to create a calendar module, but I have some questions:
var calendarModule = (function() {
var daysLabels = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
var monthsLabels = ['January','February','March','April','May',
'June','July','August','September','October','November','December'];
var daysInMonths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var dateObj = new Date();
var dayRangeArr = [];
return {
setDate: function(year,month,day) {dateObj = new Date(year,month,day);},
getDaysLabels: function() {return daysLabels;},
getMonthsLabels: function() {return monthsLabels;},
getDaysInMonths : function() {return daysInMonths ;},
getDateObj: function() {return dateObj;},
getDay: function() {return dateObj.getDate();},
getYear: function() {return dateObj.getFullYear();},
getDayOfWeek: function() {return dateObj.getDay();},
getMonth: function() {return dateObj.getMonth();},
getPreviousMonth: function() {return dateObj.getMonth() - 1;},
getNextMonth: function() {return dateObj.getMonth() + 1;},
getStartingDayOfWeek: function() {
return new Date(this.getYear(), this.getMonth(), 1).getDay();
},
getIsLeapYear: function(month, year) {
if (month === 1) { //Feb only month effected by leap years
if ( !((year % 4) || (!(year % 100) && (year % 400))) ) {
return 29;
} else {
return 28;
}
} else {
return daysInMonths[month];
}
},
getDaysInCurrentMonth: function() {
return this.getIsLeapYear(this.getMonth(),this.getYear());
},
getDaysInPreviousMonth: function() {
return this.getIsLeapYear(this.getPreviousMonth(),this.getYear());
}, ...
My question is about my getter "methods". For example, I have this method:
getPreviousMonth: function() {return dateObj.getMonth() - 1;},
I have created no setter or even previousMonth
var\private property. Is this a no-no?
I was thinking I could create vars corresponding to each getter method and have setDate()
be like a constructor which would set their initial values. Am I heading in the right direction? I want to be sure I not falling into an anti-pattern.
EDIT:
I realized I should be making most of the methods private because as of right now, I can't think of a reason why they would be used outside of the module itself- except for the getIsLeapYear()
.
Here is what my code looks like now:
var calendarModule = (function() {
var daysLabels = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
var monthsLabels = ['January','February','March','April','May',
'June','July','August','September','October','November','December'];
var daysInMonths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var dateObj = new Date();
var dayRangeArr = [];
function getDaysLabels() {return daysLabels;}
function getMonthsLabels() {return monthsLabels;}
function getDaysInMonthsn() {return daysInMonths ;}
function getDateObj() {return dateObj;}
function getDay() {return dateObj.getDate();}
function getYear() {return dateObj.getFullYear();}
function getDayOfWeek() {return dateObj.getDay();}
function getMonth() {return dateObj.getMonth();}
function getPreviousMonth() {return dateObj.getMonth() - 1;}
function getNextMonth() {return dateObj.getMonth() + 1;}
function getStartingDayOfWeek() {
return new Date(getYear(), getMonth(), 1).getDay();
}
function getDaysInCurrentMonth() {
return getIsLeapYear(getMonth(),getYear());
}
function getDaysInPreviousMonth() {
return getIsLeapYear(getPreviousMonth(),getYear());
}
//The days of the previous month that will appear on current month's page
function getVisibleDaysInPreviousMonth() {
//todo must add condition for when startingDayOfWeek is 0
return getDaysInPreviousMonth() - (getStartingDayOfWeek() - 1);
}
function getIsLeapYear(month, year) {
if (month === 1) { //Feb only month effected by leap years
if ( !((year % 4) || (!(year % 100) && (year % 400))) ) {
return 29;
} else {
return 28;
}
} else {
return daysInMonths[month];
}
}
return {
setDate: function(year,month,day) {dateObj = new Date(year,month,day);},
getIsLeapYear: getIsLeapYear, ...
I return getIsLeapYear
so I can use it to check against arbitrary dates.
-
\$\begingroup\$ how are you planning on using this module? do you plan to use many instances of it in one application? \$\endgroup\$nrw– nrw2014年06月02日 19:03:29 +00:00Commented Jun 2, 2014 at 19:03
-
\$\begingroup\$ I think so. I may ultimately find I do not need many instances of it, but for the time being I think I will. I'm mostly concerned about whether I'm using this pattern correctly. I'm writing this application for the sole purpose of learning various js techniques for organizing code. \$\endgroup\$user1028270– user10282702014年06月02日 19:09:58 +00:00Commented Jun 2, 2014 at 19:09
1 Answer 1
In terms of the module pattern as used in JavaScript-
There are plenty of times that a getter is used to access a variable that is otherwise managed internally. This would mean that you would have no need for a setter; in fact a setter in that case would be a no-no.
Using a getter for a concept that is not clearly defined within the calendarModule itself could be a little confusing to someone that needs to help you later, or modify your code. But I can't speak to whether it breaks the pattern.
Have you considered using the revealing module pattern? I only ask because I think it would be less likely for you to question "am I doing it wrong" because the getter is itself a defined part of the module. I could be grossly misinterpreting that however, but it is how I have interpreted it and practiced it for some time.
-
\$\begingroup\$ Updated the code to make those methods "private" \$\endgroup\$user1028270– user10282702014年06月02日 21:32:38 +00:00Commented Jun 2, 2014 at 21:32
Explore related questions
See similar questions with these tags.