How to write maintainable JavaScript for web applications: covering everything from syntax and style, to hot loop performance, to application structure.
It has been said that one should code as if the person maintaining the code is a violent psychopath who knows where you live. But why do we work with psychopaths? That question unfortunately cannot be answered in this presentation. However, we can shed some light on how to code for readability hopefully avoiding the problem altogether.
Readable code is about a lot more than producing beautiful code. In fact, it has nothing really to do with the beauty of the code and everything to do with the ability to quickly understand what the code does.
In this presentation we will discuss why readable code is so important. We will cover six commonly reoccurring patterns that made code hard to read, why they occur, and how they can easily be avoided:
* Deep Nesting
* Unnecessary Generalization
* Ambiguous Naming
* Hard to Follow Flow of Execution
* Code Style vs. Individualism
* Code Comments
These concepts may be applied to any programming language.
We want code that is easy to understand, re-usable, and flexible. But we are always up against deadlines, so we rush, and end up with code that is messy, buggy, hard to maintain, and makes us go slower even though we’re trying to go faster.
What is clean code? In this talk I’ll provide some answers to this question, and introduce you to 10 good habits that will help keep your code clean, such as the use of meaningful names for your variables and functions, and following the “Boy Scout Rule” (leave the code cleaner than you found it). I will even try to persuade you that using a lot of code comments is a sign that there are problems with your code.
Better Swift from the Foundation up #tryswiftnyc17 09-06Carl Brown
Highlights of some useful Swift coding patterns and ways to avoid common sources of bugs and performance issues. These lessons learned are based on examination of Swift CoreLibs Foundation and other Open Source Swift libraries and projects, as he has contributed to helping bring Swift to the Server.
Stay alert and try to solve these "simple" JavaScript puzzles, designed to demonstrate some of the more obscure "features" of the language. Try your best to answer them! But, be careful — the solutions aren't as easy as they look.
*Presented at the Adobe MAX Conference, 2013
https://speakerdeck.com/matenadasdi/frontend-automation-and-stability
We all know that after a certain amount of code complexity it’s impossible to maintain everything with simple manual processes. Frontend development is in a new era and we all have to focus on stability and scalability in our huge JavaScript architecture. I will present you our plans at Ustream to keep up with continuous feature development, our testing layers and solutions for workflow automation.
Overview of Groovy language features and lead to Functional Programming in Groovy. As this is a code along session backed by this presentation, code examples are not include here as I code them live.
It has been said that one should code as if the person maintaining the code is a violent psychopath who knows where you live. But why do we work with psychopaths? That question unfortunately cannot be answered in this presentation. However, we can shed some light on how to code for readability hopefully avoiding the problem altogether.
Readable code is about a lot more than producing beautiful code. In fact, it has nothing really to do with the beauty of the code and everything to do with the ability to quickly understand what the code does.
In this presentation we will discuss why readable code is so important. We will cover six commonly reoccurring patterns that made code hard to read, why they occur, and how they can easily be avoided:
* Deep Nesting
* Unnecessary Generalization
* Ambiguous Naming
* Hard to Follow Flow of Execution
* Code Style vs. Individualism
* Code Comments
These concepts may be applied to any programming language.
We want code that is easy to understand, re-usable, and flexible. But we are always up against deadlines, so we rush, and end up with code that is messy, buggy, hard to maintain, and makes us go slower even though we’re trying to go faster.
What is clean code? In this talk I’ll provide some answers to this question, and introduce you to 10 good habits that will help keep your code clean, such as the use of meaningful names for your variables and functions, and following the “Boy Scout Rule” (leave the code cleaner than you found it). I will even try to persuade you that using a lot of code comments is a sign that there are problems with your code.
Better Swift from the Foundation up #tryswiftnyc17 09-06Carl Brown
Highlights of some useful Swift coding patterns and ways to avoid common sources of bugs and performance issues. These lessons learned are based on examination of Swift CoreLibs Foundation and other Open Source Swift libraries and projects, as he has contributed to helping bring Swift to the Server.
Stay alert and try to solve these "simple" JavaScript puzzles, designed to demonstrate some of the more obscure "features" of the language. Try your best to answer them! But, be careful — the solutions aren't as easy as they look.
*Presented at the Adobe MAX Conference, 2013
https://speakerdeck.com/matenadasdi/frontend-automation-and-stability
We all know that after a certain amount of code complexity it’s impossible to maintain everything with simple manual processes. Frontend development is in a new era and we all have to focus on stability and scalability in our huge JavaScript architecture. I will present you our plans at Ustream to keep up with continuous feature development, our testing layers and solutions for workflow automation.
Overview of Groovy language features and lead to Functional Programming in Groovy. As this is a code along session backed by this presentation, code examples are not include here as I code them live.
Lessons I Learned While Scaling to 5000 Puppet AgentsPuppet
Russ Johnson of StubHub talks about "Learning Lessons Scaling to 5000 Puppet Agents" at Puppet Camp San Francisco 2013. Find a Puppet Camp near you: puppetlabs.com/community/puppet-camp/
List of few AngularJS recommended/best practices that can help to write clean, robust and maintainable SPA applications. It was presented at JUG Stockholm Sweden.
Agenda:
1. AngularJS Best Practice # 1: File Organization
2. AngularJS Best Practice # 2: Cross Component Communication
3. AngularJS Best Practice # 3: Scopes
4. AngularJS Best Practice # 4: Named Functions
5. AngularJS Best Practice # 5: Keep Controllers Focused
Presented by Rasheed (http://se.linkedin.com/pub/rasheed-waraich/46/113/72/) Co-founder Aurora Solutions (http://home.aurorasolutions.org/) & FixTelligent (www.fixtelligent.com)
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLEGavin Pickin
We’ve all had those projects, the salvage project, the legacy project that we picked up, and wished we never had.
Was it written 5 years ago by that young dev with lots of passion but no big picture vision.
Was it written 6 months ago by another team, by a top gun developer who knows all the design patterns, and tried to future proof the app, only succeeding in making it impossible for anyone else to understand.
Or was it you, 2 years ago, before you joined the community and learned more about best (better) practices and you almost cannot comprehend how you used to code.
Long story short, we have all been there, but the past is history, how do we proceed from here, that’s the key. We’ll look at some of the ways you can clean up your code, and walk through some examples, and walk the journey to software craftsmanship
5 main points
What is clean code
Reading vs Writing Code
Don’t suffocate your code, let it breathe
Simple & Self Documenting Code
Lower the Cognitive Load
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE - CFObjective() 2017Ortus Solutions, Corp
We’ve all had those projects, the salvage project, the legacy project that we picked up, and wished we never had.
Was it written 5 years ago by that young dev with lots of passion but no big picture vision.
Was it written 6 months ago by another team, by a top gun developer who knows all the design patterns, and tried to future proof the app, only succeeding in making it impossible for anyone else to understand.
Or was it you, 2 years ago, before you joined the community and learned more about best (better) practices and you almost cannot comprehend how you used to code.
Long story short, we have all been there, but the past is history, how do we proceed from here, that’s the key. We’ll look at some of the ways you can clean up your code, and walk through some examples, and walk the journey to software craftsmanship
5 main points
What is clean code
Reading vs Writing Code
Don’t suffocate your code, let it breathe
Simple & Self Documenting Code
Lower the Cognitive Load
Infrastructure as code might be literally impossible / Joe Domato (packageclo...Ontico
HighLoad++ 2017
Зал «Мумбай», 7 ноября, 12:00
Тезисы:
http://www.highload.ru/2017/abstracts/2918.html
This talk will begin by briefly examining what it means for infrastructure to be represented as code. We'll examine some fundamental software components required for automating infrastructure such as GPG, package managers, SSL, and more. We'll examine some interesting failure cases for these tools and how these shortcomings might make infrastructure as code impossible, for now.
Day one of a two day seminar on object-oriented PHP. Designed to cover a basic level of familiarity with the concepts in general, and some PHP-specific implementation details and examples.
Test driven development for infrastructure as-a-code, the future trend_Gianfr...Katherine Golovinova
We stress our developers to write tests while they write the code. We set quality gates to avoid releasing code that didn’t pass tests, or doesn’t have enough coverage.
But then, when it’s about IaaC, we do exactly the opposite. The time has come for us to discuss the challenges of testing IaaC code, from the necessity of using different languages, to the problems of deploying expensive resources in real world – analyzing the current possibilities and common best practices and looking ahead at the most promising technologies and projects, to boldly go, where no man has gone before: TDD Infra as Code.
By making your site accessible, you'll get a better understanding of HTML semantics, an increased audience reach, Google will reward you... and you will become good looking, admired by your peers, and be the most interesting person in the room.
Lessons I Learned While Scaling to 5000 Puppet AgentsPuppet
Russ Johnson of StubHub talks about "Learning Lessons Scaling to 5000 Puppet Agents" at Puppet Camp San Francisco 2013. Find a Puppet Camp near you: puppetlabs.com/community/puppet-camp/
List of few AngularJS recommended/best practices that can help to write clean, robust and maintainable SPA applications. It was presented at JUG Stockholm Sweden.
Agenda:
1. AngularJS Best Practice # 1: File Organization
2. AngularJS Best Practice # 2: Cross Component Communication
3. AngularJS Best Practice # 3: Scopes
4. AngularJS Best Practice # 4: Named Functions
5. AngularJS Best Practice # 5: Keep Controllers Focused
Presented by Rasheed (http://se.linkedin.com/pub/rasheed-waraich/46/113/72/) Co-founder Aurora Solutions (http://home.aurorasolutions.org/) & FixTelligent (www.fixtelligent.com)
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLEGavin Pickin
We’ve all had those projects, the salvage project, the legacy project that we picked up, and wished we never had.
Was it written 5 years ago by that young dev with lots of passion but no big picture vision.
Was it written 6 months ago by another team, by a top gun developer who knows all the design patterns, and tried to future proof the app, only succeeding in making it impossible for anyone else to understand.
Or was it you, 2 years ago, before you joined the community and learned more about best (better) practices and you almost cannot comprehend how you used to code.
Long story short, we have all been there, but the past is history, how do we proceed from here, that’s the key. We’ll look at some of the ways you can clean up your code, and walk through some examples, and walk the journey to software craftsmanship
5 main points
What is clean code
Reading vs Writing Code
Don’t suffocate your code, let it breathe
Simple & Self Documenting Code
Lower the Cognitive Load
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE - CFObjective() 2017Ortus Solutions, Corp
We’ve all had those projects, the salvage project, the legacy project that we picked up, and wished we never had.
Was it written 5 years ago by that young dev with lots of passion but no big picture vision.
Was it written 6 months ago by another team, by a top gun developer who knows all the design patterns, and tried to future proof the app, only succeeding in making it impossible for anyone else to understand.
Or was it you, 2 years ago, before you joined the community and learned more about best (better) practices and you almost cannot comprehend how you used to code.
Long story short, we have all been there, but the past is history, how do we proceed from here, that’s the key. We’ll look at some of the ways you can clean up your code, and walk through some examples, and walk the journey to software craftsmanship
5 main points
What is clean code
Reading vs Writing Code
Don’t suffocate your code, let it breathe
Simple & Self Documenting Code
Lower the Cognitive Load
Infrastructure as code might be literally impossible / Joe Domato (packageclo...Ontico
HighLoad++ 2017
Зал «Мумбай», 7 ноября, 12:00
Тезисы:
http://www.highload.ru/2017/abstracts/2918.html
This talk will begin by briefly examining what it means for infrastructure to be represented as code. We'll examine some fundamental software components required for automating infrastructure such as GPG, package managers, SSL, and more. We'll examine some interesting failure cases for these tools and how these shortcomings might make infrastructure as code impossible, for now.
Day one of a two day seminar on object-oriented PHP. Designed to cover a basic level of familiarity with the concepts in general, and some PHP-specific implementation details and examples.
Test driven development for infrastructure as-a-code, the future trend_Gianfr...Katherine Golovinova
We stress our developers to write tests while they write the code. We set quality gates to avoid releasing code that didn’t pass tests, or doesn’t have enough coverage.
But then, when it’s about IaaC, we do exactly the opposite. The time has come for us to discuss the challenges of testing IaaC code, from the necessity of using different languages, to the problems of deploying expensive resources in real world – analyzing the current possibilities and common best practices and looking ahead at the most promising technologies and projects, to boldly go, where no man has gone before: TDD Infra as Code.
By making your site accessible, you'll get a better understanding of HTML semantics, an increased audience reach, Google will reward you... and you will become good looking, admired by your peers, and be the most interesting person in the room.
Like JavaScript, there is a tendency to learn CSS using the View Source technique. This high level overview will focus on what you should do and what you should not do - providing enough CSS knowledge to be dangerous!
This presentation will show the latest Web Components technologies and examples, and whether you should be using Web Components now. (spoiler alert: you should be!)
With great power, comes great responsive-ability web design.
Responsive web design (RWD) will be demystified. Believe it or not, it's more than just media queries, although those will be discussed. It starts with proper UI design and application architecture, and then the dive into CSS - but not too deep! You don't have to be an expert to do RWD, but it helps to have some idea of what you are doing.
Improperly architected applications may work, may perform well, and may meet the acceptance criteria, but the ability to maintain them degrades over time. This presentation will show some of the common mistakes made when building large web applications, how to be aware of them, correct them, and hopefully prevent them.
MVC JavaScript libraries are the hot trendiness right now, and this gives a brief overview of all of the most popular, as well as what exactly is MVC, MVVM, MVP, what they do, and why, or if, we need them.
Dojo has Video and Audio and GFX, so it must be HTML5 compliant, no? Not so fast! We'll look over some core pieces and grade Dojo on how well it holds up!
Especially in small companies, you're often expected to be the end-to-end developer and handle everything from the database to the user interface. This was easy enough in the old days when the UI was little more than a table-based-layout with some sliced graphics. But now with the latest technologies, the front end is becoming just as complex as the back end. In order to get the job done you need to rely more and more upon an ever growing, endless mountain of JavaScript libraries, plugins and boilerplates. Or maybe... you just need a front end developer.
A REST API involves more than just pushing data back and forth between endpoints. This presentation will explain what REST is and also present a variety of topics and questions you will certainly come across while implementing your API.
By Jeremy Brown @notmessenger http://notmessenger.com
A little insight into standards bodies bickering and politics. Is HTML5 is dead? What about that logo? Are we to refer to it as “HTML5″ as the WC3 says or “HTML” as the WHATWG says? When will it be ready? How can we work with no version number?
Are the rumors greatly exaggerated or is HTML5 is dead? What about that logo? Are we to refer to it as "HTML5" as the WC3 says or "HTML" as the WHATWG says? If it's HTML5, when will it be ready? If it's HTML, how can we work to a specification with no version number? A little insight into standards bodies bickering and politics.
How to get a Job as a Front End DeveloperMike Wilcox
For career changers or general job searchers who have experience, and developers in general. Skills and subsets needed to be hirable; How and where to learn FED Skills; Job Search Preparation; Where to find job openings; How to write a resume; How to be a good interview
An overview of DojoX GFX and DojoX Drawing, and the underlying technology that uses SVG and VML to provide vector-based graphics cross-browser without the use of Flash.
Communications Mining Series - Zero to Hero - Session 1DianaGray10
This session provides introduction to UiPath Communication Mining, importance and platform overview. You will acquire a good understand of the phases in Communication Mining as we go over the platform with you. Topics covered:
• Communication Mining Overview
• Why is it important?
• How can it help today’s business and the benefits
• Phases in Communication Mining
• Demo on Platform overview
• Q/A
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfPaige Cruz
Monitoring and observability aren’t traditionally found in software curriculums and many of us cobble this knowledge together from whatever vendor or ecosystem we were first introduced to and whatever is a part of your current company’s observability stack.
While the dev and ops silo continues to crumble….many organizations still relegate monitoring & observability as the purview of ops, infra and SRE teams. This is a mistake - achieving a highly observable system requires collaboration up and down the stack.
I, a former op, would like to extend an invitation to all application developers to join the observability party will share these foundational concepts to build on:
The Art of the Pitch: WordPress Relationships and SalesLaura Byrne
Clients don’t know what they don’t know. What web solutions are right for them? How does WordPress come into the picture? How do you make sure you understand scope and timeline? What do you do if sometime changes?
All these questions and more will be explored as we talk about matching clients’ needs with what your agency offers without pulling teeth or pulling your hair out. Practical tips, and strategies for successful relationship building that leads to closing the deal.
Sudheer Mechineni, Head of Application Frameworks, Standard Chartered Bank
Discover how Standard Chartered Bank harnessed the power of Neo4j to transform complex data access challenges into a dynamic, scalable graph database solution. This keynote will cover their journey from initial adoption to deploying a fully automated, enterprise-grade causal cluster, highlighting key strategies for modelling organisational changes and ensuring robust disaster recovery. Learn how these innovations have not only enhanced Standard Chartered Bank’s data infrastructure but also positioned them as pioneers in the banking sector’s adoption of graph technology.
How to Get CNIC Information System with Paksim Ga.pptxdanishmna97
Pakdata Cf is a groundbreaking system designed to streamline and facilitate access to CNIC information. This innovative platform leverages advanced technology to provide users with efficient and secure access to their CNIC details.
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIVladimir Iglovikov, Ph.D.
Presented by Vladimir Iglovikov:
- https://www.linkedin.com/in/iglovikov/
- https://x.com/viglovikov
- https://www.instagram.com/ternaus/
This presentation delves into the journey of Albumentations.ai, a highly successful open-source library for data augmentation.
Created out of a necessity for superior performance in Kaggle competitions, Albumentations has grown to become a widely used tool among data scientists and machine learning practitioners.
This case study covers various aspects, including:
People: The contributors and community that have supported Albumentations.
Metrics: The success indicators such as downloads, daily active users, GitHub stars, and financial contributions.
Challenges: The hurdles in monetizing open-source projects and measuring user engagement.
Development Practices: Best practices for creating, maintaining, and scaling open-source libraries, including code hygiene, CI/CD, and fast iteration.
Community Building: Strategies for making adoption easy, iterating quickly, and fostering a vibrant, engaged community.
Marketing: Both online and offline marketing tactics, focusing on real, impactful interactions and collaborations.
Mental Health: Maintaining balance and not feeling pressured by user demands.
Key insights include the importance of automation, making the adoption process seamless, and leveraging offline interactions for marketing. The presentation also emphasizes the need for continuous small improvements and building a friendly, inclusive community that contributes to the project's growth.
Vladimir Iglovikov brings his extensive experience as a Kaggle Grandmaster, ex-Staff ML Engineer at Lyft, sharing valuable lessons and practical advice for anyone looking to enhance the adoption of their open-source projects.
Explore more about Albumentations and join the community at:
GitHub: https://github.com/albumentations-team/albumentations
Website: https://albumentations.ai/
LinkedIn: https://www.linkedin.com/company/100504475
Twitter: https://x.com/albumentations
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofsAlex Pruden
This paper presents Reef, a system for generating publicly verifiable succinct non-interactive zero-knowledge proofs that a committed document matches or does not match a regular expression. We describe applications such as proving the strength of passwords, the provenance of email despite redactions, the validity of oblivious DNS queries, and the existence of mutations in DNA. Reef supports the Perl Compatible Regular Expression syntax, including wildcards, alternation, ranges, capture groups, Kleene star, negations, and lookarounds. Reef introduces a new type of automata, Skipping Alternating Finite Automata (SAFA), that skips irrelevant parts of a document when producing proofs without undermining soundness, and instantiates SAFA with a lookup argument. Our experimental evaluation confirms that Reef can generate proofs for documents with 32M characters; the proofs are small and cheap to verify (under a second).
Paper: https://eprint.iacr.org/2023/1886
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...James Anderson
Effective Application Security in Software Delivery lifecycle using Deployment Firewall and DBOM
The modern software delivery process (or the CI/CD process) includes many tools, distributed teams, open-source code, and cloud platforms. Constant focus on speed to release software to market, along with the traditional slow and manual security checks has caused gaps in continuous security as an important piece in the software supply chain. Today organizations feel more susceptible to external and internal cyber threats due to the vast attack surface in their applications supply chain and the lack of end-to-end governance and risk management.
The software team must secure its software delivery process to avoid vulnerability and security breaches. This needs to be achieved with existing tool chains and without extensive rework of the delivery processes. This talk will present strategies and techniques for providing visibility into the true risk of the existing vulnerabilities, preventing the introduction of security issues in the software, resolving vulnerabilities in production environments quickly, and capturing the deployment bill of materials (DBOM).
Speakers:
Bob Boule
Robert Boule is a technology enthusiast with PASSION for technology and making things work along with a knack for helping others understand how things work. He comes with around 20 years of solution engineering experience in application security, software continuous delivery, and SaaS platforms. He is known for his dynamic presentations in CI/CD and application security integrated in software delivery lifecycle.
Gopinath Rebala
Gopinath Rebala is the CTO of OpsMx, where he has overall responsibility for the machine learning and data processing architectures for Secure Software Delivery. Gopi also has a strong connection with our customers, leading design and architecture for strategic implementations. Gopi is a frequent speaker and well-known leader in continuous delivery and integrating security into software delivery.
UiPath Test Automation using UiPath Test Suite series, part 5DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 5. In this session, we will cover CI/CD with devops.
Topics covered:
CI/CD with in UiPath
End-to-end overview of CI/CD pipeline with Azure devops
Speaker:
Lyndsey Byblow, Test Suite Sales Engineer @ UiPath, Inc.
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...Neo4j
Leonard Jayamohan, Partner & Generative AI Lead, Deloitte
This keynote will reveal how Deloitte leverages Neo4j’s graph power for groundbreaking digital twin solutions, achieving a staggering 100x performance boost. Discover the essential role knowledge graphs play in successful generative AI implementations. Plus, get an exclusive look at an innovative Neo4j + Generative AI solution Deloitte is developing in-house.
Essentials of Automations: The Art of Triggers and Actions in FMESafe Software
In this second installment of our Essentials of Automations webinar series, we’ll explore the landscape of triggers and actions, guiding you through the nuances of authoring and adapting workspaces for seamless automations. Gain an understanding of the full spectrum of triggers and actions available in FME, empowering you to enhance your workspaces for efficient automation.
We’ll kick things off by showcasing the most commonly used event-based triggers, introducing you to various automation workflows like manual triggers, schedules, directory watchers, and more. Plus, see how these elements play out in real scenarios.
Whether you’re tweaking your current setup or building from the ground up, this session will arm you with the tools and insights needed to transform your FME usage into a powerhouse of productivity. Join us to discover effective strategies that simplify complex processes, enhancing your productivity and transforming your data management practices with FME. Let’s turn complexity into clarity and make your workspaces work wonders!
Climate Impact of Software Testing at Nordic Testing DaysKari Kakkonen
My slides at Nordic Testing Days 6.6.2024
Climate impact / sustainability of software testing discussed on the talk. ICT and testing must carry their part of global responsibility to help with the climat warming. We can minimize the carbon footprint but we can also have a carbon handprint, a positive impact on the climate. Quality characteristics can be added with sustainability, and then measured continuously. Test environments can be used less, and in smaller scale and on demand. Test techniques can be used in optimizing or minimizing number of tests. Test automation can be used to speed up testing.
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...SOFTTECHHUB
The choice of an operating system plays a pivotal role in shaping our computing experience. For decades, Microsoft's Windows has dominated the market, offering a familiar and widely adopted platform for personal and professional use. However, as technological advancements continue to push the boundaries of innovation, alternative operating systems have emerged, challenging the status quo and offering users a fresh perspective on computing.
One such alternative that has garnered significant attention and acclaim is Nitrux Linux 3.5.0, a sleek, powerful, and user-friendly Linux distribution that promises to redefine the way we interact with our devices. With its focus on performance, security, and customization, Nitrux Linux presents a compelling case for those seeking to break free from the constraints of proprietary software and embrace the freedom and flexibility of open-source computing.
Maruthi Prithivirajan, Head of ASEAN & IN Solution Architecture, Neo4j
Get an inside look at the latest Neo4j innovations that enable relationship-driven intelligence at scale. Learn more about the newest cloud integrations and product enhancements that make Neo4j an essential choice for developers building apps with interconnected data and generative AI.
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
Hardcore JavaScript – Write it Right
1. Hardcore
JavaScript
Write it Right
By Mike Wilcox
February 2013
Wednesday, February 6, 2013
2. Readable Code
here(will make that book very
|resistånt to pressure| to read.)
there(isn’t explained properly)
!bad Code is. like-a-book THATis badly formatted no
indentation. incorrect punctuation misspelled words
improper capitalizedation-ed. Or uneven.
?LINE HEIGHTS here() If “the” names of the char.acters
start. Chang'ing, you dunno. where they are. && you+re
not sure – WHAT they... are do-ing because it there(), the
book w'ill bee pretty-difficult to [comprehend].
Wednesday, February 6, 2013
3. What do I know??
me
s Cro ckford
D o ug la
Wednesday, February 6, 2013
4. What do I know??
Brend me
an Eic
h
Wednesday, February 6, 2013
5. What do I know??
Seriously…
Being a Dojo Committer means not only having
your code and style scrutinized by know-it-all
prima donnas, open source experts, but your
results also get used by thousands of hacks
that expect magic developers who
expect quality code.
Wednesday, February 6, 2013
6. This code sucks!
onPlayerParams = function(dfd){
! dfd = dfd || new this.Deferred();
! var o, p;
! if(scriptNode && scriptNode.getAttribute("config")){
! ! p = this.fixParams(scriptNode.getAttribute("config"));
! ! p.swf = this.root + "player.swf";
! }else if(this.embed()){
! ! var parts = this.embed().getAttribute("src").split("?");
! ! o = this.strToObj(parts[1]);
! ! o.swf = parts[0];
! ! p = this.fixParams(o);
! }else if(!this.domReady){
! ! this.ready(this, function(){
! ! ! this.onPlayerParams(dfd);
! ! }, true);
! ! if(!p) return dfd;
!}
! if(p && p.vast){b.vast.parser.getXml(p.vast);}
! return dfd;
}
Wednesday, February 6, 2013
7. Our Excuses
We
The
can always go
project manager
back and fix it later
needs this now
*I*
can read it
No
time for
comments
It My
was like that sloppy code
when I started. means job
security!
Wednesday, February 6, 2013
8. JavaScript
guide
Style
Wednesday, February 6, 2013
9. Formatting
Formatting must be consistent. Otherwise little
distractions make the code noisy and that much harder
to read.
var foo=”bar”+‘beer’+”bob”;
for(var i=0;i<arguments.length;i++){}
if(a&&b&&c&&d)return a;
Wednesday, February 6, 2013
10. Formatting
Use single quotes, use spaces liberally, don’t use tiny,
cryptic variable names and declare all variables at the
beginning of the block.
var foo = ‘bar’ + ‘beer’ + ‘bob’;
var i;
for( i = 0; i < arguments.length; i++ ){}
var
apples = true,
bananas = true,
coconuts = true;
if( apples && bananas && coconuts ){
return true;
}
Wednesday, February 6, 2013
11. Typical Guides
Indentation tabs not spaces
Spacing / whitespace
Curly braces rules
variable naming conventions
Don’t be afraid of white space.
method naming conventions
No Dojo
Case: upper, lower, camel, Pascal
neces sar y!
Dojo Style Guide
http://dojotoolkit.org/community/styleGuide
Wednesday, February 6, 2013
12. JSLint / JSHint
Is it automated into your build?
It’s not just a suggestion - listen to it!
It’s more than to help you find errors
Helps promote consistency between devs
Prevents unintended consequences
If the linter thinks your code is ambiguous, so will
other devs
Helps you target JIT compilers, resulting in faster
code
Wednesday, February 6, 2013
14. Comments Why the hell did I
write that??
OS comments vs production
comments
short descriptions
Future
save the lazy crap Self
No comments is like a book
without chapters or page
numbers
They aren’t just for your boss
or your replacement
Wednesday, February 6, 2013
15. Levels of Documenting
1. Verbose comments on every method and module,
README and Wiki, instructions for setup and usage,
guides to the software and how to edit it
2.Comments on most methods and modules, README
with instructions for setup and a guide to what
modules do
3.Brief comments on most methods and modules,
README with instructions for setup
4.Unfinished code
Wednesday, February 6, 2013
16. The Myth
You think your code is self documenting, huh? This is not
self documenting:
setCommand = function(c){ this.cmds.push(c); }
run = function(){ … }
This looks more like self documenting:
setListItemsWithDescritionsButNoThumbnails = function( … ){
this.listItemDescriptions = listItemDescriptionsArgument;
}
renderItemsWhichIsCalledAfterEveryPageResize = function(){ … }
Wednesday, February 6, 2013
17. The Myth
What your self documenting code would look like:
setListItemsWithDescritionsButNoThumbnails = function( … ){
if(!this.itemsSetBoolenPreventSecondAttempt){
this.itemsSetBoolenPreventSecondAttempt = true;
this.listItemDescriptions = listItemDescriptionsArgument;
this.renderItemsWhichIsCalledAfterEveryPageResize();
this.onAfterRenderFunctionalStubEvent();
}
“Good clean code requires very consistent and good naming
conventions that are concise, and which don't attempt to
embody an extended purpose”
https://www.ibm.com/developerworks/mydeveloperworks/blogs/StylishGeek/entry/
bloated_names_and_the_myth_of_self_documenting_code11?lang=en
Wednesday, February 6, 2013
18. Don’t be that guy
When a dev writes crap
Comment quality matters like this, I want to
function setParams(params){ paint him with meat
paste and drop him on a
! // sets params
mound of fire ants
}
function setVideo(video){
! // set video
}
function setParams(params){
! // sets parameters based on config property
! // from script tag
}
function setVideo(videoPath){
! // Sets the path for the video object
}
Wednesday, February 6, 2013
20. Naming Conventions
Should be camel case
Upper case
Whole names, no abbreviations
This isn’t your father’s code. We have minifiers and gzip
now. Use names we understand!
Exceptions for long or often used names: err for error,
dfd for deferred, prop for property, app for application,
etc.
i, k, j, etc, okay for iterators
Wednesday, February 6, 2013
21. Property Bags
Multiple arguments (more than 3) are difficult to
manage
An single argument as an object of options allows any or
all properties to be passed without concern of method
signature
Mixins allow for simple setting
Works with super constructors
Wednesday, February 6, 2013
22. ARG-uments
function Widget(node, name, description, color, size){
this.node = node;
this.name = name || “Untitled”;
this. description = description || “”;
this.color = color || “#FF0000”;
this.size = size || 100;
this.code = “makes me sad”;
}
new Widget({});
Wednesday, February 6, 2013
23. Property Bag Example
function Widget( options ){
util.mixin( this, options ); // Done!
}
Even better is to set defaults and use a mixin that only
overwrites and does not add undefined properties
var Widget = declare{
name:‘Untitled’,
description:’’,
color:’#FF0000’,
size:100,
constructor: function( options ){
util.mixin(this, options); // Done!
}
}
Wednesday, February 6, 2013
24. getters & setters
Initialization
var object = {
! _x: 7,
! get x() { return this.x + 1; },
! set x( arg ) { this.x = arg / 2; }
};
After creation
object.__defineGetter__("b", function() { return this.a + 1; });
object.__defineSetter__("c", function(x) { this.a = x / 2; });
ES5 getters and setters are still not widely used due to IE8. There are
also issues as far as how inheritance would work. The super keyword is
still in proposal.
Wednesday, February 6, 2013
25. ES3 getters & setters
Initialization
var object = {
! x: 7,
! get: function( key ) { return this[ key ]; },
! set: function( key, value ) { this[ key ] = value; }
};
This is a very common and standardized pattern, even
used in Node.js (Mongoose). It works with most library
inheritance patterns.
Wednesday, February 6, 2013
26. Observers & Watchers
object.watch( 'x', function( value ){
! moveObject( x );
});
object.observe( 'x', function( value ){
! moveObject( x );
});
watch() is only available on Gecko with warnings of
performance penalties. observe() is still an ES6
proposal.
Common solution is to simply connect to widget.set
method with aspect.after.
Wednesday, February 6, 2013
27. Binding
<div class='Widget'>
! <span data-bind='name'></name>
</div>
Widget = declare({
! name:'Untitled',
! set: function( key, value ){
! ! this[ key ] = value;
! ! if( this.bindings[ key ] ){
! ! ! this.bindings[ key ].innerHTML = value;
!! }
!}
});
new Widget({ name: 'Bob' });
This common pattern is the key to all of these trendy MVC
frameworks.
Wednesday, February 6, 2013
29. Naming Conventions
Camel case
Pascal case for constructors (Classes)
Should be verbs
getItems, setName, build, Widget, etc
Wednesday, February 6, 2013
30. Ambivalence
function process(){}
function state(){}
function command(){}
function structure(){}
Those are not verbs.
process could be to perform operations or a series
of steps
state could be to state your name, or the current
application state
It’s not obvious what any of these do and they
should at least be commented
Wednesday, February 6, 2013
31. Side Effects
While side effects are not forbidden, you should
still consider the consequences
function setImageProperties(){
image.width = 320;
image.height = 240;
image.x = 100;
image.y = 10;
image.opacity = 0.9;
updateImage();
killPuppy();
}
Can you spot the side effect?
Wednesday, February 6, 2013
32. Monolithic Functions
1970 called and wants their
fixParams = function(o){
! var _vid = o.videoId || o.vid || o.siteId || "";
! if(/,/.test(_vid)){
! !
! !
o.media = [];
o.mediaParam = 'vid=' + _vid;
GOSUB back.
! ! _vid.split(',').forEach(function(id){
! ! ! o.media.push({videoId:id});
! !
! !
});
if(o.titles){
Requires extra cognition
! ! ! o.mediaParam += '&titles=' + o.titles;
! ! ! o.titles.split(',').forEach(function(title, i){
! !
! !
!
!
!
});
o.media[i].caption = unescape(title);
Limits reusability
! ! ! delete o.titles;
! ! }
! !
! !
delete o.videoId;
delete o.vid; Even if it means more bytes,
should be broken into smaller
! ! delete o.siteId;
! }else if(o.media){
! ! o.mediaParam = 'media=' + o.media;
! }
! var vid = o.videoId || o.vid || o.siteId || ""; functions
! var lid = o.locationId || o.lid;
! var cid = Number(o.clientId) || o.cid;
! if(lid === 1 || lid === "1" || !lid) lid = 0;
! for(var nm in this.params){
! ! if(o[nm] === undefined) o[nm] = this.params[nm];
! }
! if(!o.videoId && !o.siteId && !o.vid && o.media){
! ! if(/siteId/.test(o.media)){
! ! ! var pms = this.strToObj(unescape(o.media));
! ! ! this.settings.siteId = pms.siteId;
! ! }
! }
Actual Code! See the whole thing here!
Wednesday, February 6, 2013
33. Repetition
This ain’t Java. You shouldn’t have code like this.
function setListeners(){
! this.domNode.addEventListener('onmousedown', this.onMouseDown);
! this.domNode.addEventListener('onmouseup', this.onMouseUp);
! this.domNode.addEventListener('onmousemove', this.onMouseMove);
! this.domNode.addEventListener('onmouseover', this.onMouseOver);
! this.domNode.addEventListener('onmouseout', this.onMouseOut);
! this.domNode.addEventListener('onmouseenter', this.onMouseEnter);
! this.domNode.addEventListener('onmouseleave', this.onMouseLeave);
}
Wednesday, February 6, 2013
34. Repetition
JavaScript is a dynamic language and can
handle repetition in multiple ways.
['onmousedown', 'onmouseup', 'onmouseover'].forEach(function(event){
! this.domNode.addEventListener(event, this[event]);
}, this);
$(this.domNode).on('onmousedown, onmouseup, onmouseover', function
(event){
! handleMouseClick(event);!
});
Wednesday, February 6, 2013
35. Function in Functions
Functions inside of other functions are perfectly
legitimate, but still should be used with care
and consideration.
function parseDom(node){
! function parseText(){}
! function parseAttributes(){}
! function parseChildren(){}
! function getNodeType(){}
! getNodeType(node);
! parseText(node.innerHTML);
! parseAttributes(node.attributes);
! parseChildren(node.childNodes);
}
Wednesday, February 6, 2013
36. Function in Functions
Often slower, as each time the outer is invoked, the
inners are recreated
They are private and not accessible by other methods
If inners are not semantically tied very closely to
the outer, the intention may be confusing
The inners should never access anything outside of
the outer - aka, the application
Else what was the point?
Wednesday, February 6, 2013
37. Loops
Where the biggest performance boost (or hit) can
happen
Hot Loops
JIT compilers make assumptions, especially on loops
Not a good place for being tricky
Sparse arrays
Arrays with lots of “holes” will slow down the iteration
Some libraries, like Lo-Dash handle these holes and speed
performance
Wednesday, February 6, 2013
38. Loops - for vs forEach
for is much faster, used in context and can be easily
interrupted with a break or continue’d
for is a major chore to type - looks very “C”
forEach has the overhead of the function, and is
used out of context unless the this argument is
added which is an addition performance hit
forEach is much more finger friendly, and fine to
use in low performance situations
map, some, every, filter etc. have same issues
and should be used on small arrays
Wednesday, February 6, 2013
39. Functions in Loops
for( var i = 0; i < arguments.length; i++){
! var handler = (function(node){
! ! return node.addEventListener('click', blah);
! })( arguments[i] );
! handlers.push( handlers );
}
JSLint will complain. Listen to it!
Creates a new function on every iteration. Slow.
Fix this by moving the function outside of the loop
and calling it. This allows for JIT prediction.
Wednesday, February 6, 2013
40. for vs for-in
for-in is for objects, for is for arrays. If I see you do this
I will give you a
paper cut in the
NO EXCEPTIONS! corner of your
mouth and feed you
for( var key in array ){ lemons
doSomething( array[key] );
}
Could access unwanted properties
Not a guarantee of order
Intent is not clear
In fact, it’s more of a WTF
Wednesday, February 6, 2013
42. Don’t fight “this”
meth
var instance = {
od
t! doit: function(){ console.log('DOIT!'); },
c ! subobject:{
je
b ! ! submethod: function(){
o
b- calls
su
! ! ! doit(); // FAIL!
! ! ! this.doit(); // FAIL!
! ! ! parent.doit(); // No such thing!
metho d
!! }
!}
};
instance.subobject.submethod();
This is a simplified version of a much larger problem
Wednesday, February 6, 2013
43. Don’t fight “this”
You *could* bind the submethod to the parent object...
var instance = {
! doit: function(){ console.log('DOIT!'); },
! subobject:{
! ! submethod: function(){
! ! ! this.doit(); // works
!! }
!}
};
instance.subobject.submethod =
bind(instance, instance.subobject.submethod);
instance.subobject.submethod();
Of course, this begs the question of why you created
subobject in the first place.
Wednesday, February 6, 2013
44. Don’t cross the beams!!
One solution...
var instance = {
! constructor: function(){
! ! aop.after(this.subobject, 'submethod', this.doit.bind(this));
! },
! doit: function(){ console.log('DOIT!'); },
! subobject:{
! ! submethod: function(){}
!}
};
Understanding that communication only goes “down”, never “up”
will go a long way toward clear code and simplified execution
paths
Wednesday, February 6, 2013
45. Know thy self
self is the common variable name used to pass around
and change context (this)
var self = this;
props.forEach(function(prop){
! self[ prop.key ] = prop.value;
});
Because JavaScript is a closure based language, self can
actually be very efficient. Believe it or not, this is slower:
props.forEach(function(prop){
! this[ prop.key ] = prop.value;
}, this);
http://kriszyp.name/2012/09/14/closure-based-instance-binding/
Wednesday, February 6, 2013
46. Alternative to self
Context binding basically uses call or apply under the
hood
var bind = function(ctx, func){
! return function(){ func.apply(ctx, arguments); };
};
var instance = {
! constructor: function(props){
! ! var setProps = bind(this, this.setProps);
! ! props.forEach(setProps);
! },
! setProps: function(p){
! ! console.log(p);
!}
};
instance.constructor([{a:1}, {b:2}]);
Wednesday, February 6, 2013
47. ES5 bind()
All modern browsers have Function.bind which can
change context
var instance = {
! id:'binder',
! constructor: function(props){
! ! setTimeout(function(){
! ! ! console.log(this.id);!
! ! }.bind(this), 1);
!}
};
instance.constructor();
Note that even though it’s built into the language, it’s not faster
than self. It is for readability and convenience, not hot loops.
Wednesday, February 6, 2013
48. Hate thy self too much
self is like chocolate cake - some is good, too much will
make you sick
var self = this;
var onLoad = function(data){
! self.title = data.title;
! self.description = data.description;
! self.setClients( data.clients );
! self.on('finished', function(){
! ! self.render( self.items );
! ! setTimeout( function(){
! ! ! self.emit( 'afterrender' );!
! ! }, 1);
! });
};
Wednesday, February 6, 2013
49. Love thy self a little
On solution is to immediately redirect to a properly bound
method
var instance = {
! onDataLoaded: function(data){
! ! // now set stuff
! },
! constructor: function(props){
! ! var self = this;
! ! var onLoad = function(data){
! ! ! self.onDataLoaded(data);
! ! };
!}
};
Wednesday, February 6, 2013
50. Don’t abuse your self
this is specific; it can’t be changed so you always
know to which object it points
self is ambiguous; it can point to many objects from
any object, which obfuscates your intent
Don’t use self to shortcut better practices
Wednesday, February 6, 2013
52. Prototypal Inheritance
If you are using the prototype keyword… you’re doing it
wrong. HMO
Hot Mike Opinion
Widget = function(props){
! mixin(this, this.props);
};
Widget.prototype = {
! render: function(){},
! setItems: function(){}
}
Using prototype makes multiple inheritance difficult, and
without some kind of AOP help, the super constructors won’t
work.
Wednesday, February 6, 2013
53. dcl
A JavaScript package that implements OOP with mixins and
AOP at both “class” and object level.
var Base = dcl(null, { var Example1 = dcl([Base, Mixin1],{
! declaredClass: 'Base', ! constructor: function(params){
! constructor: function(params){ ! ! this.name = params.name;
! ! this.title = params.title; ! },
! } ! render: function(){
}); ! ! this.prepareProps();
! ! // call Widget.render
var Widget = dcl(null, { ! ! this.inherited();
! declaredClass: 'Widget', ! }
! constructor: function(params){ });
! ! this.className = params
! }, /*********************************/
! render: function(){ widget = new Example1({
! ! this.setTemplate(); ! title:'My Widget',
! } ! name:'widget',
}); ! className:'Widget'
});
http://www.dcljs.org/about/
Wednesday, February 6, 2013
54. dcl / Inheritance
Base classes can be reused, keeping code light -
extremely important in JavaScript
Constructors are chained and called in all bases,
which can’t be done in standard object creation, such
as Object.create
super methods can be called with inherited(), so
all base classes can use similar method names,
keeping code standardized and less complex
For ES5 strict mode there is AOP inheritance
Wednesday, February 6, 2013
56. Design Patterns
Design Patterns: Elements of Reusable Object-Oriented
Software is a book with solutions to common problems in
software design. The authors are often referred to as the Gang
of Four.
Functional (Imperative)
Declarative
Decorator
Composition
http://en.wikipedia.org/wiki/Design_Patterns
Wednesday, February 6, 2013
57. Over-Inherited
One reason for other solutions is to protect from over-
inheritance
Based on more
Base actual code from
! +! Item my Flash days!
! ! +! ServerItem
! ! ! +! ImageItem
! ! ! ! +! ImageListItem
! ! ! ! ! +! ImageListItemDescription
! ! ! ! ! ! +! ImageListItemDescriptionClickable
! ! ! ! ! ! ! +! ImageListItemDescriptionClickableDraggable
Note however, JavaScript does not have the same
inheritance restrictions as Java, C++, Flash, or others
Wednesday, February 6, 2013
58. Declarative
A problem faced by libraries is allowing the dev to choose
discrete segments of code instead of kitchen sink solutions
define([
! 'dojo/declare',
! 'dojo/store/Memory',
! 'dojo/store/Cache',
! 'dojo/store/JsonRest',
! 'dojo/store/Observable'
], function( declare, Memory, Cache, JsonRest, Observable ){!
! var Store = declare( Memory, Cache, JsonRest );
var store = new Store( webserviceUrl );
});
The dev can dynamically create their own constructor with the
mixins provided
Wednesday, February 6, 2013
59. Decorator
define([
], function( declare, Memory, Cache, JsonRest, Observable ){
!
! var Store = declare( Memory, Cache, JsonRest );
! var store = new Store( webserviceUrl );
observableStore = Observable( store );
cacheableStore = Cache( observableStore );
});
Decorators are not very common, but they do solve a few
problems like working with existing objects that you can’t
change, or creating two objects from the same base with
different functionality.
Wednesday, February 6, 2013
60. Composition
Composition often makes sense semantically. Here the model
encapsulates properties and functionality.
Widget = {
! constructor: function(model){
! ! this.model = model;!
! },
! get: function(key){
! ! return this.model.get(key);
!}
}
Wednesday, February 6, 2013
61. Functional HMO
Hot Mike Opinion
Don’t.
Just don’t.
Friends don’t let friends write functional.
Wednesday, February 6, 2013
63. require.js
You are using it, aren’t you?
Globals are SO 2011
Globals can clash with other code, and they do not
garbage collect
require.js provides a mini-framework, enforcing
packages, namespaces, and modules
Wednesday, February 6, 2013
64. Naming and Arranging
Don't expect to cram it all into preconceived model-
view-controller folders, it's too limiting, and the app
will grow out of it
Remember, the code path flows
down, not up, so the deeper modules
should not have access to root
modules
Wednesday, February 6, 2013
65. Module APIs
Modules can use private variables, but not to hide or protect
anybody - use them to help provide a clean API. And if you are
doing so - make it a clear intent!
define([], function(){
! var items = [];
! function setItem(item){
! ! items.push(item);
!}
! function getItem(idx){
! ! return items[idx];
!}
! return {
! ! setItem:setItem,
! ! getItem:getItem
! };
});
Wednesday, February 6, 2013
68. Tight Coupling
Pros:
The intent is quite clear
Requires no additional libraries of fancy code
Cons:
Over-use between modules can create a hairball
Can break encapsulation
define([
! './foo',
! '../../views/widgets/utils/thinger'
], function(foo, thinger){
! foo.doStuff();
! thinger.stopStuff();
});
require.js allows for clear paths to distant modules, but if you are
connecting to something this “far” away, you should probably do some
restructuring
Wednesday, February 6, 2013
69. AOP
Uses JavaScript’s dynamic, mutable language
Doesn’t overwrite method, so many connections can be made
Make sure to create names to indicate they are event-
methods
define([
! 'aop',
! './items'
], function(aop, items){
! function onLoaded(data){
! ! console.log(data);
! }!
! aop(items, 'onLoad', onLoaded);
});
Wednesday, February 6, 2013
70. Events
The new hotness
Multiple connections can be made
Intent is clear - obvious they are events and what they do
define(['dcl', 'Events'], function(dcl, Events){
! return new dcl(Events, {
! ! onDataLoaded: function(data){
! ! ! this.emit('dataloaded', data);
!! }
! });
});
define(['./dataLoader'], function(dataLoader){
! function onDataLoaded(data){
! ! console.log(data);
!}
! dataLoader.on('dataloaded', onDataLoaded);
});
Wednesday, February 6, 2013
71. pubsub
Pros:
Library code is very simple
Can access distant areas of app
Cons:
Not guaranteed - pub can fire before sub is ready
Can be hard to follow code paths between unrelated modules
Over-use can lead to race conditions
define(['pubsub'], function(pubsub){
! pubsub.publish('/module/loaded', {success:true});
});
define(['pubsub'], function(pubsub){
! pubsub.subscribe('/module/loaded', function(object){
! ! console.log('load success:', object.success);
! });
});
Wednesday, February 6, 2013
72. callbacks
Pros: Old-school, simple way of connecting async; clear code path
Cons: Only one connection, no propagation, multiple callback
nesting can cause “callback hell”
define([], function(){
! return {
! ! loadData: function(callback){
! ! ! xhr('/getdata', {
! ! ! ! load: function(data){
! ! ! ! ! callback(data);
! ! ! ! }});}};
});
define(['./instance'], function(instance){
! function onDataLoaded(data){
! ! console.log(data);
!}
! instance.loadData(onDataLoaded);
});
Wednesday, February 6, 2013
74. promises / deferreds
Pros:
Async
A when() library can handle both async and sync
Trendy (everybody is doing it!!)
Multiple connections can be made
Propagates, and can be stopped
Cons:
Libraries are somewhat complex
Requires (a lot) more code than a callback
Has a tendency to swallow errors unexpectedly
Can dominate the stacktrace and make it hard to debug
errors
Wednesday, February 6, 2013
76. Refactor!
Little projects always become big projects
You will never have all the information up front
Sales can turn your app into Frankenstein
Wednesday, February 6, 2013
77. Make
it small. People Committee Refactor! It
sure is tall. Can
like small. you make it LOOK
short?
But
make it big inside.
Oh!
And four doors.
Small with lots of
doors.
My
Don’t
son says it would
spend too much on
be cool if you could
the trim.
camp in it.
Don’t
spend too much on
the wheels.
Wednesday, February 6, 2013