I have an architectural pattern that I use to accomplish the only two
objectives that matter:
1) Speed of execution
2) Ease of maintenance

In my opinion absolutely everything else is, with one exception,
irrelevant.  You can evaluate whether or not software is crap with
this simple formula:
x = initial cost of development
y = minimal required lifespan
z = cost of maintenance during the length of y + costs of all
associated penalties and harms during the length of y

if x < z then your software is either a business failure or a costly
hobby

It is important to understand that this formula takes into account
some minor level of risk management.  It does not take into account
definitions of what are acceptable initial costs, because that is
presumed to be understood during planning before any code is written.
Good programs are not written so that the programmer can give
themselves a warm fuzzy to show off with unnecessary complexity or use
frameworks to avoid addressing necessary concerns.  Good programs work
as intended and require as little maintenance as possible.  The only
other value worthy of consideration is detailed error reporting that
describes what failed, what it was doing when it failed, and where it
failed at.  In my opinion, that is the opposite of error suppression,
which is why I cannot stand most of the JS frameworks out there.



Here is what I did for the Pretty Diff tool.  If you want you can
following along by passing the Pretty Diff code through the tool.
tool: http://prettydiff.com/
code: http://prettydiff.com/prettydiff.js

1) I ALWAYS avoid use of object literals with only one exception.
Object literals are the slowest containers in JavaScript, so therefore
fast programs do not use them.  The only one exception is that it is
generally a good idea to use object literals to feed input into
functions to avoid a massive list of arguments.  For more information
about this exception please read through the active thread here:
Parameters vs. Objects as Parameters

2) I ALWAYS use a single var keyword per function and put it near the
top of the function.  The one var keyword is absolutely necessary for
ease of maintenance and putting near the top is a good idea, because
its going to be moved to the top of the function at execution time
anyways.  I say it is a requirement for ease of maintenance, because
in complex applications there could be scope interference when a
variable is re-scoped in an ancestor function and sometimes there may
be no control to prevent such name collisions if different parties are
writing different functions are different levels.  It is nice to know
where to look for variable as part of standard troubleshooting to
quickly test for and/or identify the presence of such problems.

The only code I put before the var keyword are return conditions.  If,
for example, a function is entered and the execution supplied by that
function is either harmful or unnecessary it is convenient to supply
an escape sequence before any other conditions are evaluated.

3) I ALWAYS use anonymous functions assigned to variables.  There was
some quote that went around from Brendan Eich that the "function" is
too long and makes functional coding diffecult to read, but because I
use assigned anonymous functions I do not encounter this problem.
There are some rare cases where I use an unassigned anonymous function
as an otherwise shallow container, but these rare cases are only used
for condition encapsulation to ease readability and are not used to
supply variable scope.

4) I ALWAYS separate DOM methods and all other code that must
interface with the DOM from the application code.  In the Pretty Diff
example the DOM code is available for examination at http://prettydiff.com/pd.js
This has three benefits:
4a) This helps to eliminate troubleshooting complexity associated with
the DOM from the application.  Those two pieces of code have
completely separate objectives, and so their bugs should like wise be
separated as necessary to reduce maintenance effort from enhancements.
4b) Code is much easier to read and understand when it is logically
reduced into as many separated pieces as possible.
4c) This makes the application code platform neutral.  The DOM code
can be added for execution in a browser or eliminated for command line
execution.  Once the DOM code is isolated you only have to maintain a
single piece of application code to enhance the application equally in
all environments.

5) I ALWAYS seek to limit access to the DOM as much as possible, such
as requesting nothing more than I absolutely need and never supplying
such requests inside loops.  Accessing the DOM in XML is great, but is
a horrible bottleneck in HTML.  This is because HTML standards and
browsers have a legacy of supporting HTML code that is sloppy crap,
and since the DOM is an abstract model of markup structure then
therefore interpretation of the DOM is sloppy crap.  I prefer to limit
access only to the getElementById method and read element contents as
string literals from the innerHTML property.  If I have to write to
the DOM I prefer to build content as an array and return it in an
innerHTML property with a join method containing an empty string.  In
my opinion this is the fastest possible way to access the DOM, and so
I structure my code accordingly.

6) I seek to avoid fanciness.  I have nothing to prove to anybody else
with my brilliant coding abilities in how elaborate my fantastic code
is.  If I want to be perceived as a decent programmer then I will use
simple and predictable practices so that my application performs
quickly and predictably.  For loops I prefer a standard "for" loop,
because in my opinion it is the most predictable.  For conditions I
prefer to use only "if/else if/else" conditions because while they are
not as fast to execute as switch conditions they are more expressive
and more predictable in their behavior.  I never use empty conditions
because condition fall through and condition trapping should always be
predictable and intentional with known and testable alterations.  I
try to avoid multidimensional arrays, because they tend to be
unnecessarily complicated, but this rule is not absolute.

7) Since I cannot stand error suppression I use the "use strict"
statement to trigger strict mode.  I want to know when I am screwing
up so that I can fix the problem before it hits production.  Sometimes
errors slip out into production anyways, so is it more important to
lie to suppress necessary all indications of the error to the users or
expose your incompetence to your users.  I would say the later is
better.  In my opinion it is better to have a minor showing of
incompetence than a massive hidden failure, because a minor
embarrassment costs less and is repaired more quickly than a massive
unreported technology failure.

If you follow those steps you will reveal a pattern of code that is
easy to reproduce, easy to extend, and easy to maintain.  The pattern
that is revealed is the architecture I use in my own code.

Austin Cheney, CISSP
http://prettydiff.com/

-- 
To view archived discussions from the original JSMentors Mailman list: 
http://www.mail-archive.com/[email protected]/

To search via a non-Google archive, visit here: 
http://www.mail-archive.com/[email protected]/

To unsubscribe from this group, send email to
[email protected]

Reply via email to