2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ how are you planning on using this module? do you plan to use many instances of it in one application? \$\endgroup\$ – nrw Jun 2 '14 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 Jun 2 '14 at 19:09
1
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Updated the code to make those methods "private" \$\endgroup\$ – user1028270 Jun 2 '14 at 21:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.