<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>consultingchronicles &#8211; Software, Fitness, and Gaming &#8211; Jesse Warden</title>
	<atom:link href="https://jessewarden.com/tag/consultingchronicles/feed" rel="self" type="application/rss+xml" />
	<link>https://jessewarden.com</link>
	<description>Software &#124; Fitness &#124; Gaming</description>
	<lastBuildDate>Sat, 06 Jul 2013 02:56:13 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://jessewarden.com/wp-content/uploads/2016/08/cropped-Lambda2-32x32.png</url>
	<title>consultingchronicles &#8211; Software, Fitness, and Gaming &#8211; Jesse Warden</title>
	<link>https://jessewarden.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Consulting Chronicles #7: The Priority Pyramid</title>
		<link>https://jessewarden.com/2012/04/consulting-chronicles-7-the-priority-pyramid.html</link>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Wed, 04 Apr 2012 14:09:37 +0000</pubDate>
				<category><![CDATA[Consulting Chronicles]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[consulting]]></category>
		<category><![CDATA[consultingchronicles]]></category>
		<category><![CDATA[leadership]]></category>
		<category><![CDATA[priority]]></category>
		<category><![CDATA[prioritypyramid]]></category>
		<category><![CDATA[pyramid]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[software]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=3099</guid>

					<description><![CDATA[Introduction The Priority Pyramid is a tool I use to stay on track with new consulting clients. It prioritizes how, who, and what I engage in at any given time. It can be overwhelming when thrust into a challenging situation, a code base in dire straits, and a frustrated team. You need a strong pillar [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img fetchpriority="high" decoding="async" style="padding-right: 8px;" src="http://jessewarden.com/archives/blogentryimages/priority-pyramid-4.4.2012.jpg" alt="The Priority Pyramid - The 8 Tiers of Software Consulting" width="320" height="483" align="left" /><strong>Introduction</strong></p>
<p>The Priority Pyramid is a tool I use to stay on track with new consulting clients. It prioritizes how, who, and what I engage in at any given time. It can be overwhelming when thrust into a challenging situation, a code base in dire straits, and a frustrated team. You need a strong pillar of guidance.</p>
<p>This article goes over what parts make up the Priority Pyramid from a high level. I&#8217;ll talk about what milestones make up each section and how you navigate back and forward between the priorities.</p>
<p>When done, you should know how to engage your client&#8217;s team and tackle working on a large code base at a frustrated client site with 99 problems.</p>
<p><span id="more-3099"></span><strong>Why?</strong></p>
<p>Over the years, I&#8217;ve prioritized what I need to be doing when working my consulting clients. There are countless things I need beyond &#8220;coding&#8221;, and all have to do with &#8220;people&#8221;. Code in its own right is challenging enough. Add people to the mix and it gets more complicated than it already is.</p>
<p>Every engagement is different, even with repeat clients. This is why I like consulting. Meet new people, travel new places, learn new things.</p>
<p>While I enjoy and thrive on improv, what I didn&#8217;t like was not having a set of guidelines to deal with each new client. The business blogs &amp; books I&#8217;ve read are pretty dry, and don&#8217;t really focus on the people issues coders encounter and have to deal with. Most also assume YOU are the one creating &amp; maintaing the app, not fixing/modifying a large one extremely behind schedule. It&#8217;s either sales, management, or product management. This includes the consulting books. Some approach it from a larger consulting perspective, where you come in, listen to the client&#8217;s problems, write up a plan, and pass it off to India. If you are involved, it&#8217;s just to either head off major disaster and/or provide face time for the client.</p>
<p>This is NOT what I, and my colleagues I&#8217;ve worked with over the years do. We&#8217;re in the trenches, working alongside our clients, playing the politics games whilst coding.</p>
<p>So, I made my own rules for engagement, prioritized based on importance, with verification points to ensure I&#8217;m on the right track. If I cannot work towards getting through all tiers of the pyramid, I will not be working for the client long, whether by my choice or theirs. It&#8217;s important I flush out these red flags early and tackle them full bore.</p>
<p>That&#8230; and it has D&amp;DÂ connotations.</p>
<p><strong>Quantitative vs.Â Qualitative Foundations</strong></p>
<p>I&#8217;ve used both quantitative and qualitative results from case studies, white papers, and my own experience to base this set of priorities on.</p>
<p><a href="http://en.wikipedia.org/wiki/Brooks%27_law">Mythical Man Month/Brooks&#8217; Law</a>: &#8220;Adding manpower to a late software project makes it later&#8221;. Some of the bad projects I&#8217;ve been on had too many people on them. Your goal at that point is to delegate refactoring to the team to compensate, lead with good architecture, and leverage your trust currency to guide the various teams into a direction you need them to go. Also known as software chaos management. This requires you be at a high enough level to be in charge of various teams. If you&#8217;re not, God help you.</p>
<p>Code Review: One person, reading code for up to but not exceeding 1 hour finds more code defects than unit testing. This is not peer review, but that is also effective. Citations: <a href="http://support.smartbear.com/resources/cc/book/code-review-cisco-case-study.pdf">Code Review at Cisco Systems</a>, <a href="http://www.cnx-software.com/pdf/klocwork-research-code-review-study.pdf">Klocwork/Forrester &#8220;The Value and Importance of Code Reviews&#8221;</a>, and some other <a href="http://www.codinghorror.com/blog/2006/01/code-reviews-just-do-it.html">stats</a> from <a href="http://www.amazon.com/exec/obidos/ASIN/0735619670/codihorr-20">Code Complete</a>. Keep in mind while most of the studies mention that defects do notÂ significantlyÂ decrease after 1 person, the ability to learn from your peers and getting architecture suggestions are very well documented in the blogosphere.</p>
<p>Cheaper to Find Defects Early: Whether you are ruthless about upfront requirements gathering and/orÂ initialÂ architecture, or are adamant about short development iterations that includes scope reduction, both allow the ability to find more defects early. It&#8217;s easier to both find, and fix problems earlier than later for a variety of reasons (code size, feature acceptance, contractual obligations, etc). Beyond the IBM studies back in the 70&#8217;s here&#8217;s an <a href="http://www.methodsandtools.com/archive/archive.php?id=29">excerpt</a> from <a href="http://www.methodsandtools.com/archive/archive.php?id=29">High Quality Low Cost Software Inspections</a>. Also, crazy charts from <a href="http://sqgne.org/presentations/2011-12/Jones-Sep-2011.pdf">Capers Jones</a> (they have some other good studies). This is why I&#8217;m so adamant about getting the visual design (wireframes/design comps/ux/information architecture, etc.) right from the get go, even if 6 months into the project. Lowest hanging fruit and saves tons of time/money.</p>
<p><a href="http://dl.acm.org/citation.cfm?id=1536639">DistributedÂ Development</a> (<a href="http://cs.queensu.ca/~ahmed/home/teaching/CISC880/F10/papers/DistributedDevelopment_CACM2009.pdf">PDF</a>): The result that physical distance between developers doesn&#8217;t matter. Different room/building/country&#8230; not a big deal at all. What matters is how far the software developer(s) are from the stakeholder(s) in the organization management hierarchy. This is extremely important. I am firm believer in both telecommuting as well as on-site visits with clients for communication &amp; leadership reasons. This is central to identifying the power structure of the organization in Tier #2 and garnering trust with those who can help you talk to who you need to talk to in Tier #3. I&#8217;ve been ineffective at more than one consulting engagement because I wasn&#8217;t Â high enough to affect the required positive change.</p>
<p><a href="http://en.wikipedia.org/wiki/Toyota_Production_System">Toyota Production System</a>: Their continuousÂ improvementÂ philosophyÂ and respect for people are what really ring true to me. While <a href="http://blog.digitalbackcountry.com/2007/01/a-look-at-the-rich-internet-application-consulting-landscape/">It Takes a Village</a>Â to build great software, sometimes you have a crowded, drama filled city that you have to work within. Doing your best to get the team motivated to constantly improve, and SEE the improvement occur over time for motivation reinforcement, is just a small way to continually improve. You can only do this if you do in fact respect the people you work with. Empowering leaders amongst those who actually do the work can lead to effective production. You can use these <a href="http://www.fastcompany.com/magazine/111/open_no-satisfaction.html">Toyota Process strategies</a> in your own team delegation.</p>
<p><strong>The Priority Pyramid</strong></p>
<p>The 8 steps are in order of importance:</p>
<ol>
<li>Report</li>
<li>Understanding</li>
<li>Trust</li>
<li>Lead</li>
<li>Build</li>
<li>Explosions</li>
<li>Diagnostics</li>
<li>Architecture</li>
</ol>
<p>While it implies 4 are about coding, make no mistake: The Priority Pyramid is all about people. It&#8217;s built on your relationships with them and those relationships ensure you can do your job.</p>
<p>Lets break down the tiers the following way: What milestones do you need to complete, how to do you move on to the next tier, and when should you move back? I make the assumption if you&#8217;re on a team, you&#8217;ll divide tasks appropriately.</p>
<p><strong>A Note on Tier Foundations</strong></p>
<p>Each tier works on top of the foundation of the former. If the foundation is weak, it won&#8217;t strongly support the one on top. If you don&#8217;t have the trust of management and your co-workers, it&#8217;sÂ difficultÂ to lead them. If you don&#8217;t have a good understanding of the company andÂ peopleÂ who work within it, it becomes veryÂ difficultÂ to affect positive visual design changes to make architecture easier. It&#8217;s ok to be in Tier #8 and realize you need more understanding of how the application will be deployed from Tier #2; just like refactoring code over time, you can continue to strengthen the foundation tiers over time as well.</p>
<h2><strong>Tier #1: Report</strong></h2>
<p><strong>Milestones Before Arriving</strong></p>
<ol>
<li>You&#8217;ve talked to stakeholder(s) on the project to have an idea of what you&#8217;re getting into.</li>
<li>Verify you actually want to get into it. Some consulting gigs are hard to get out of. Some can reflect poorly on your firm/you even if you do a good job. Make sure you&#8217;re willing to make the plunge. We&#8217;re looking for red flags here to save you tons of money and stress. I&#8217;m not saying be choosy, I&#8217;m saying be careful.</li>
<li>Where you&#8217;re going, who you&#8217;re supposed to see, and when.</li>
</ol>
<p><strong>Milestones</strong></p>
<p>You/your firm has scored a client, you&#8217;ve booked your airfare + hotel, and you&#8217;re 1st day on-site has arrived. You look sharp, are excited, and looking forward to making a good first impression.</p>
<ol>
<li>First question out of your mouth after small talk should be &#8220;Who&#8217;s do I report to?&#8221;. Yes, it&#8217;s ok to follow up this question once you&#8217;ve scored more rapport with &#8220;Great, so&#8230; who&#8217;s my boss?&#8221;. This ensures you don&#8217;t do good things that get you in bad trouble.</li>
<li>Second question: &#8220;What will make you happy when I leave?&#8221;. This helps verify why you&#8217;re really here, and what they&#8217;re really paying you for. Sometimes this takes alcohol to get the true answer. Sometimes just a neutral setting outside of the office/building.</li>
</ol>
<p><strong>Successful Exit</strong></p>
<p>Know who you work for and your true goal in life for the next 8 months.</p>
<h2><strong>Tier #2: Understanding</strong></h2>
<p>The best communicators are good listeners. Your task now is to look people in the eye, lean forward, and listen well.</p>
<p><strong>Milestones</strong></p>
<ol>
<li><strong>Listen</strong>: Get people talking, asking questions, and listen to what they say. This is the most important step in the entire pyramid.</li>
<li><strong>Goals</strong>: You need to understand what the goals are for the project, both stated and real. What are you and the client really trying to accomplish? Answering &amp; documenting this will guide your actions for the rest of the project,Â overriddenÂ only by &#8220;Who do you report to?&#8221;.</li>
<li><strong>Problems</strong>: What are the problems and challenges the company has run into? Do any relate to why you&#8217;re here? Do they have a thorough list or are there more? Solving problems earns trust, and helps in the next tier. It also validates your paycheck. Why does the client have those problems? Where do you fit in? Who&#8217;s accountable for identifying solution(s) for and solving those problem(s)? These are your first challenges in the game.</li>
<li><strong>Dissect People</strong>: This is also an opportunity for you to start learning who the players are in the game. You need to understand what makes someone tick to best interact with them. Do they like business first, small later or the opposite? Do they have ulterior motives? Can they be trusted? Can they give you valuable intel on the project others won&#8217;t? What will it take to make them comfortable enough to tell you more? How can you possibly help them? You&#8217;re going to be spending the next 3 to 18 months with these people. Get to know them, make a good first impression, and understand them. These are the people you want on your team, who you want to do certain things for you, who you want to trust you. Once you understand them, you can effectively engage them. Sometimes this is done simply by watching how they interact with others. Ask questions to get them talking; their personality whilst reveal itself. Finally, figure out who reports to whom for real? What is the power structure? You&#8217;ll need to play within this framework; best to know how it works for real vs. what the label says on their door.</li>
<li><strong>Explore</strong>: Finally, code stuff. Time for initial reconnaissance. Taken what you&#8217;ve learned, it&#8217;s time to verify what you heard is recent, relevant, and can be corroborated with the code. This should still be framed from a &#8220;learning the company&#8221; perspective. You need to:</li>
<ol>
<li><strong>Learn the Data Model</strong>: The VO&#8217;s, the Services it calls, and what those business objects actually mean to the organization.</li>
<li><strong>Learn The Framework</strong>: How is the codeÂ architected; what framework did they use?</li>
<li><strong>Understand The Story</strong>: With another developer, preferably one who worked on the code base and/or your client, ask the developer questions to learn the story. Even the worst code base has a reason how it got there. Like an archeologist, you want to understand this history, the pivotal decisions, or lack thereof, that made it the way it is. You&#8217;ll learn the to respect, and pity, even the worst code base once you&#8217;re armed with this knowledge.</li>
<li><strong>Look For Red Flags</strong>: Both the currentlyÂ benign, and the &#8220;holy eff we&#8217;re eff&#8217;d&#8221;. Whether that&#8217;s everything being a hashmap in Java, Angular &amp; Backbone both being used in the same code base, or ActionScript 2. You don&#8217;t want surprises, you want to frame your perspective of the code base with your client&#8217;s. This is a VERY important step. Don&#8217;t say it, but talk about it internally in my mind. Find out why there is aÂ disparityÂ in perception.</li>
<li><strong>Look For Mines</strong>: Like red flags, these are things that down the line of a project, based on what you learned above could go boom. They aren&#8217;t aÂ priorityÂ but need to be documented.</li>
<li><strong>Look For Validation</strong>: Did everything you learned in Steps 1 &#8211; 4 get validated or where you completely off? If so, continue to dig, and redo steps 1 &#8211; 4 to re-verify.</li>
</ol>
</ol>
<p><strong>Successful Exit</strong></p>
<p>When you firmly understand the client&#8217;s reality, the reality the code reflects, and the real reality once you&#8217;ve resolved the two, you&#8217;re ready to move on. If they still don&#8217;t mesh, keep asking questions &amp; researching.</p>
<h2><strong>Tier #3: Trust</strong></h2>
<p>Assuming you&#8217;ve made good first impressions with those you&#8217;ve met, it&#8217;s now time to validate those initial impressions in those you&#8217;ve met. It&#8217;s time to start building trust.</p>
<p><strong>Milestones</strong></p>
<ol>
<li><strong>Provide Immediate Value</strong>: Check in code into the company&#8217;s source control your 1st week there. Preferably the code fixes a bug. Do NOT try to save the world in the code base. Pick some litter instead. If you clean the entire thing in a day, great, but get your feet wet and see what happens. A lot of drama and things you couldn&#8217;t predict happen AFTER you&#8217;ve checked in code and it goes into production. Start small and work your way up. Just ensure it&#8217;s immediate.</li>
<li><strong>Make Professional Friends</strong>: Respect those you work with and get to know them. Whether this is small talk that&#8217;s sincere orÂ genuineÂ interest, whatever works to build a positive relationship. People trust those they like. Trust is a currency you&#8217;ll sometimes have to spend in buckets to make positive headway so start investing in earning some now.</li>
<li><strong>Visible Logger</strong>: Invest in a visible logger. Even if the code doesn&#8217;t currently have problems, when it does, you want it to talk to you. Not only you, but the company. You want to corroborate this communication with your boss. When production explodes, and you know within seconds because your little secret keyboard shortcut debug window shows the error, that inspires confidence. It also provides a kind of transparency to your client when others start using it proactively to find problems. You just empowered a company to work together; well done, that&#8217;ll earn some trust. Make the code talk to you so you can trust what it&#8217;s saying, then expose this communication channel to your client.</li>
<li><strong>Provide Transparency</strong>: As you start getting your feet wet, whether this is struggling to get your environment setup so you can compile, or are deep in the bowels of fixing your first bug, let your boss know. Keep them appraised of what you&#8217;re doing on regular intervals, even if she doesn&#8217;t ask. Come across with confidence; you KNOW what you need to be working on, and you&#8217;re informing your boss as such. Additionally, she has a chance toÂ re-prioritizeÂ if you need to be working on something more pressing. No communication, and neither of these things happen. If they know and have confidence in you doing what you say you&#8217;re going to do, they can play defense and keep their boss off your, and your team&#8217;s back.</li>
</ol>
<p><strong>Successful Exit</strong></p>
<p>Do you think people trust you? Have you checked in working code that fixes a problem and your boss has verified this? Can you even compile? Do you know the names of those you&#8217;re working with/near? If yes to all, you&#8217;re ready to move on.</p>
<p><strong>NOTE</strong>: If you ever lose trust, fall back to continually adding immediate value. Trust isn&#8217;t given, it&#8217;s earned. If you lose it, the only way to get it back to is re-earn it from scratch.</p>
<h2><strong>Tier #4: Lead</strong></h2>
<p>At this point you know enough about the goals of the project to start formulating plans on moving forward, whether this is how to implement new features or how to fix/refactor existing ones. You&#8217;ve provided enough value to earn a modicum of trust. It&#8217;s time to lead people forward.</p>
<blockquote><p>A manager puts people in a line, puts the guy with the machete at the front, and leads people through the jungle effectively. A leader climbs the tree, and tells everyone they need to go left instead.</p></blockquote>
<p><strong>Milestones</strong></p>
<ol>
<li><strong>Short Term Goals</strong>: You&#8217;ve assessed the situation and identified priorities that need to be refactored (using my previous article). You need the team to agree on a common logging interface, both in code and visually. Finally, you need the team to agree on an architecture.</li>
<li><strong>Long Term Goals</strong>: You&#8217;ve identified architecture holes that need to be plugged. Sometimes there are design problems that if changed could save months of work and hardship. You need to start work and documentation on it now. Solidify the long term goal into something defendable, and get the teams input. <span><span style="color: #000000;">Be careful how you go about talking about it. While you need client feedback (remember transparency), it must be attainable to company-relevant, short term steps. You can spend trust currency for longer term refactoring/re-architectureÂ endeavors, but I recommend against it.</span></span></li>
<li><strong style="color: #000000;">Resources</strong><span style="color: #000000;">: Sometimes you need to hire additional people, whether from internal client teams, additional consultants/contractors from your firm, or hiring on behalf of your client. This could be staff augmentation or hiring a specificÂ </span>skill set<span style="color: #000000;">Â you need/want. Identify these early and ask your boss.</span></li>
<li><strong>Divide, Delegate, and Conquer</strong>: Whether the client&#8217;s employee&#8217;s or your firms, you need to divide up the massive amount of work amongst people. Offer up tasks first, and then assign to those you deem appropriate if no volunteers materialize. Building upon Tier 2 and 3, you should have a gut feeling for who&#8217;s best for what task. You cannot save the world by yourself. It may seem that you spend more time aiming people in the same direction then actually walking that direction yourself. Don&#8217;t fret; you&#8217;re on the right track.</li>
<li><strong>Be Positive</strong>: While misery loves company, peopleÂ like and follow positive people. In talking &amp; delegating all of your goals, plans, do so positively. You&#8217;re not &#8220;fixing a pile of rubbish&#8221;, you&#8217;re &#8220;building an awesome application&#8221; or &#8220;improving an important machine&#8221; or whatever you can say and actually believe when you say it. Eat right,Â exercise, and/or surround yourself with positive influences. Make this the year you <a href="http://www.menshealth.com/best-life/make-life-worth-living">commit suicide</a>, reorganize &amp; clean your working environment/home office, or just accomplish a small goal that&#8217;s not work related that you use asÂ positivityÂ fuel. Mentor &amp; encourage your team but don&#8217;t come off as a know-it-all/holier-than-thou. Play to win.</li>
</ol>
<p><strong>Successful Exit</strong></p>
<p>If you know what you/your team needs to be working on today, next month, you&#8217;ve approved the hiring you need, and the team is all tasked up, then it&#8217;s time to move on.</p>
<p><strong>Notes on Tier #5 &#8211; 8</strong></p>
<p>The latter teirs are development specific, but rely on a strong firm foundation from the first 4. Remember, the human component is your weakest link, not your Factories. Strengthen them; do not enter these 4 latter tiers of first 4 are weak.</p>
<h2><strong>Tier #5: Build</strong></h2>
<p>You need to easily build the software. This is the most common, and frequent, option you&#8217;ll do many times a day, every day. The longer this takes, the longer it takes you to develop. This can also kill your team&#8217;s momentum. If something goes wrong, such as someone checking in a bug that breaks the build into source control, or a feature needing be implemented for a presentation by some date, a slow buildÂ exacerbatesÂ time to resolution.</p>
<p>Worse, some developers will start making their own build setup, leading to code that works on some developers machines and not on others. Validation of working code suddenly becomes meaningless which can adversely affect project schedule metrics. Even worse, you can think your code works, but it doesn&#8217;t for others. Who&#8217;s right?</p>
<p><strong>Milestones</strong></p>
<ol>
<li><strong>Quick</strong>: The build needs to run quickly. This obviously anÂ arbitraryÂ metric based on code size, libraries,Â continuousÂ integration setup, etc. If developers say &#8220;the build is slow&#8221;, then it&#8217;s slow. Utilize libraries so the entire thing doesn&#8217;t have to compile, inject dependencies at runtime, utilize modules&#8230; whatever it takes.</li>
<li><strong>Easy</strong>: If the build is complicated to do, you&#8217;ll get developers making a lot of mistakes during code validation time before they check in. They&#8217;ll either check in bad code, or make their own setup that allows the code to work on only their machine. They should be able to just click 1 button, run an Ant/Maven script, or do a 1 line command line execution.</li>
<li><strong>Duplicated</strong>: The build should be able to be duplicated on a new developers machine. It&#8217;s completely fine to have company standards, such as only Windows 7 PC w/admin rights, Flex SDK 4.6, running Rake 0.8.2. It&#8217;s also ok if that takes some time with another developer to setup. What&#8217;s not ok is once they do that, it doesn&#8217;t work. If there are 3rd party dependencies that cannot effectively be deployed x-machine, find a way to remove them. Solutions include, again, using libraries, modules, development servers vs. local server setup, etc.</li>
</ol>
<p><strong>Successful Exit</strong></p>
<p>If you can run the build multiple times a day without pulling your hair out, it can be run multiple times on the same code base and not break, and anyone on the team can explain to a new developer 90% of the setup, you&#8217;re good to go. Another validation includes Developer A checking in code, then Developer B updating to latest and running the build and it works on their machine as well.</p>
<h2><strong>Tier #6: Explosions</strong></h2>
<p>When things go awry, you need to immediately know where and why. More than aÂ euphemismÂ for errors/exceptions, explosions also include errors in the application that constantly cause fire drills in the company.</p>
<p><strong>Milestones</strong></p>
<ol>
<li><strong>Exceptions Handled</strong>: Handle all errors save null pointers. If you have global exception handling capabilities, implement it/them. This doesn&#8217;t mean just wrapping something in a try/catch; it means not only logging the catch, but putting something meaningful in the catch so you&#8217;ll understand what it means when it happens.</li>
<li><strong>Logging</strong>: You need to centralize all long into a single library. It&#8217;s ok if this library is your own that builds on top of the built-in provided one, such as Flex&#8217; ILogger. As long as anyone, anywhere on the team wants to log something, they use that vs. print/trace.</li>
<li><strong>Visual Log</strong>: Optional: A visual window, built into the application itself (SWF/JS, etc), that prints out the log levels. This is done to allow logs to be seen by developers, not users. It also allows non-developers,Â especiallyÂ QA, to proactively find problems and talk directly with thoseÂ responsibleÂ vs. the 1st developer they can find. The value this provides inÂ empowermentÂ and time saved should not be underestimated.</li>
<li><strong>No More Fire Drills</strong>: Wrangling in challenging errors to help prevent fire drills can do 3 things. First, you score a lot of trust in &#8220;knowing&#8221; why something is wrong vs. 10Â peopleÂ running around aimlessly trying to figure out why. Second, you can clearly cite accountability; is it the server-side team, your team, or the database team? Instead of yelling &#8220;I think your stuff broke&#8221; you can confidently say it did with helpful data for them to test against. That kind of attitude is much easier to solve problems with. Third, fire drills no longer sabotage your productivity.</li>
</ol>
<p><strong>Successful Exit</strong></p>
<p>If an error occurs and you know where it happened, a general reason of why, and who&#8217;s potentially accountable, you&#8217;re in insanely good shape. Users don&#8217;t see these errors, just null pointers, or those you&#8217;ve built a GUI for (ie Alert error dialogue). Bonus points if fire drills happen on other teams that aren&#8217;t related to yours&#8230; but you have a way of helping through logging to make testing easier.</p>
<h2><strong>Tier #7: Diagnostics</strong></h2>
<p>Diagnostics form a range of tools, not just code. They are anything that helps provide insight into code issues or runtime errors without costing more overhead inÂ maintenanceÂ than the value they provide. The reason diagnostics is before architecture is that in larger applications,Â especiallyÂ in a consulting context, adding simple diagnostics has a ton of value with little effort whereas architecture takes a ton of effort but tends to have low perceived value (yes, it&#8217;s valuable, just harder to sell).</p>
<p><strong>Milestones</strong></p>
<ol>
<li><strong>Unit Test Coverage</strong>: Even if you&#8217;re not doing TDD, unit tests along help find &amp; prevent bugs as well as improve API&#8217;s. Unlike code reviews, they don&#8217;t get tired, benefit the entire team, and if written well only slightly add to codeÂ maintenance. Finally, they can be automated. These are also great things to work on in down times such as when JIRA is cleared, you&#8217;ve hit a brick wall with another bug, or are waiting on dependencies for a feature.</li>
<li><strong>Integration Tests</strong>: These are my favorite on service layers, more so than unit tests. The reason being is most of the Flex projects that I&#8217;ve worked on in a consulting context had some form of service layerÂ problem; ie how they talk to the back-end. Both refactoring the service code and writing unit tests that allowed me to automate the testing. It&#8217;s also nice to quickly know what part broke with confidence; client, server, or database. Automating these also makes you feel better when the server guys test new code, you can quickly help them test. There are more to integration tests, but these are the low-hanging fruit of &#8217;em.</li>
<li><strong>Automated Builds</strong>: Expanding upon Tier #5,Â streamliningÂ your build process to be more inline withÂ continuousÂ integration practices. This means designating a resource to setup, and maintain, aÂ continuosÂ build tool like CruiseControl/Hudson/TeamCity, etc. You should know who checked in bad code and when.</li>
<li><strong>Custom Diagnostics</strong>: Some applications have challenging domains of complexity. For example, video; there are TON of things that can go wrong at runtime even if the code compiles just fine. There are also a sequence of events that can cause video to fail, and knowing this sequence is paramount in debugging it, or shrugging it off since there&#8217;s nothing you can do (i.e. CDN is down). More importantly, though, sometimes you need a way to glimpse this in a more visual way than a logging window can provide. Conversely, sometimes you need to see environment variables in real-time. This little window can verify your application is running in the mode you think it is for a developer in another country. Simply making a box with a text field in it that showed Flash Player&#8217;s sandbox security type saved me 3 days (I lost 3 figuring this out, heh). Additionally, they can help empower others to do testing &amp; diagnostics on their own. Just be careful these are not a security risk for code and/or company information if deployed in production.</li>
</ol>
<p><strong>Successful Exit</strong></p>
<p>If you have good unit test coverage, can automate their running, your build is automated in some fashion (even if just client side only), and you have gui or command lines way to gain insight to your running application to find out more about errors, you&#8217;re in awesome shape.</p>
<h2><strong>Tier #8: Architecture</strong></h2>
<p>While good architecture requires a book full of information + years ofÂ experimentationÂ to get right, what we&#8217;re concerned with here is IMPROVING existing architecture. If you are starting a project from scratch and own the architecture, great, use this phase forÂ maintenance. Otherwise, we&#8217;re looking for that sweet spot of a 1 day change for a more decoupled, easier to use &amp; test in code system. If something takes longer than 3 days, you&#8217;ll be hard pressed to merge it back in and notÂ inconvenienceÂ other developers&#8230; unless it&#8217;s very little code.</p>
<p><strong>Milestones</strong></p>
<ol>
<li><strong>Tight Factories</strong>: Any part of your application which takes outside data into it&#8217;s system, such as external JSON/XML as well as user input, needs to be furtherÂ hardened. DRY the code, layer with <a href="http://jessewarden.com/archives/pix/moar-unit-tests-jxl.jpg">#moarUnitTests</a>. Form a convention on what happens when parsing/decoding fails; do you throw errors orÂ returnÂ null and log them, thus passing the burden of handling null to your system? Decide as a team.</li>
<li><strong>Fault Tolerant Services</strong>: Whether to a back-end, an external call to JavaScript in a host page, or an ad library&#8230; if it&#8217;s not your code, it&#8217;s a service. Make sure you wrap that with a Proxy that can NOT explode, and logs everything that went wrong. That extra 20 minutes pays off mad dividends.</li>
<li><strong>MVC/MVP/MVVM/YourMom/SC/PV/PM</strong>: As a team, pick one an over arching architecture pattern and stick with it for new code. I like <a href="http://martinfowler.com/eaaDev/SupervisingPresenter.html">Supervising Controller</a>, while others of my front-end Â ilk like <a href="http://martinfowler.com/eaaDev/PresentationModel.html">Presentation Model</a>. A lot of JavaScript web frameworks follow more of a <a href="http://martinfowler.com/eaaDev/PassiveScreen.html">Passive View</a>. The only right choice is team consensus &amp; comfortability. Then endeavor as a team to get certain parts moving in that direction. If there is old code, and you&#8217;re currently working on it, see if I can convert in less than a day to make more congruent with the rest of the architecture.</li>
<li><strong>DRY</strong>: If none of the above can be improved, simply making code more DRY is a good fall back task to more unit test coverage.</li>
<li><strong>TODO/FIXME/KLUDGE/HACK</strong>: Do a find all in the code. If you see those, fix them. #<a href="http://pragprog.com/the-pragmatic-programmer/extracts/software-entropy">fixBrokenWindows</a></li>
</ol>
<p><strong>Successful Exit</strong></p>
<p>You never really exit Tier #8; in fact you tend to loop back to either 7 or 6 and 7 and then back to 8. However, if you find yourself working on new features, or fixing bugs with no other drama and the rest of your team is doing the same&#8230; then you&#8217;re in epic shape.</p>
<p><strong>Conclusions</strong></p>
<p>As you can hopefully see, my priority list helps keep you focused on delivering value to those that matter quickly. Good software development is iterative. Earning trust is also iterative; you don&#8217;t take people&#8217;s money and disappear for 6 months (that&#8217;s called good Capitalism via Waterfall). This whole list, while referring to software development, is all about relationships with people. Excluding code review, your challenge as a leader is delegating the tasks in each tier to divide &amp; conquer, mitigating conflicts, and solving hard software problems in addition the rest of yourÂ responsibilities.</p>
<p>Each tier builds upon the former all the way down the line. While deep in the bowels of fixing explosions in Tier #6, I&#8217;m still continuing to build meaningful relationships in Tier #3.</p>
<p>Remember:</p>
<ol>
<li><strong>Report</strong>: Know your true boss and what will make her happy.</li>
<li><strong>Understanding</strong>: Listen, learn about the company, the people, and dive into reading the code.</li>
<li><strong>Trust</strong>: Earn trust by providing immediate value.</li>
<li><strong>Lead</strong>: Take the initiative and move the team forward. Delegate, divide, conquer.</li>
<li><strong>Build</strong>: Make the build fast, easy, and capable of being duplicated if need be.</li>
<li><strong>Explosions</strong>:Â When things go awry, you need to immediately know where and why. Prevent fire drills.</li>
<li><strong>Diagnostics</strong>: Get good unit test coverage, integration tests, automate your builds, and build any customÂ diagnosticÂ tools needed.</li>
<li><strong>Architecture</strong>: Decide on a direction/framework, and continue to nurture the code, and developers, in that direction. Loop back to 6 &amp; 7 if need be.</li>
</ol>
<h6><a href="http://www.flickr.com/photos/55935853@N00/2401448261/">Title photo by Ewan Monro</a>Â is under aÂ <a href="http://creativecommons.org/licenses/by-sa/2.0/">Creative Commons &#8211; ShareAlike Attribution license</a>.</h6>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Consulting Chronicles #6: Refactoring</title>
		<link>https://jessewarden.com/2012/04/consulting-chronicles-6-refactoring.html</link>
					<comments>https://jessewarden.com/2012/04/consulting-chronicles-6-refactoring.html#comments</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Tue, 03 Apr 2012 14:50:09 +0000</pubDate>
				<category><![CDATA[Consulting Chronicles]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[chronicles]]></category>
		<category><![CDATA[consulting]]></category>
		<category><![CDATA[consultingchronicles]]></category>
		<category><![CDATA[refactoring]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=3080</guid>

					<description><![CDATA[Introduction Refactoring is the discipline of applying a multitude of small, low-risk techniques to a code base in order fix and improve it. While corroborated by the software community, employing such techniques in a consulting context can be challenging because people are involved, often in a negative situation. You need 2 weapons to win the [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img decoding="async" style="padding-right: 8px;" src="http://jessewarden.com/archives/blogentryimages/refactoring-4.3.2012.jpg" alt="Refactoring" width="320" height="240" align="left" /><strong>Introduction</strong></p>
<p>Refactoring is the discipline of applying a multitude of small, low-risk techniques to a code base in order fix and improve it. While corroborated by the software community, employing such techniques in a consulting context can be challenging because people are involved, often in a negative situation.</p>
<p>You need 2 weapons to win the refactoring battle. First, you need to understand what refactoring techniques are at your disposal and how to implement them. Below, I&#8217;ve listed the core ones I see needed time and time again. Second, you need to have a plan on how you engage the client company and their employees to allow you to do the first. That&#8217;s covered in the next article.</p>
<p><span id="more-3080"></span>I&#8217;ve talked about how you do various parts of these initiatives in previous articles. What I want to talk about today is 1 of the 2 things: The core things you need to be concerned about in refactoring. In the next article we&#8217;ll talk about aÂ prioritizedÂ plan you should follow when engaging a client where refactoring is needed. These are aimed at being used in the worst situations, but can provide positive benefits inÂ benignÂ or benevolent situations as well.</p>
<p>You should be able to take this blog post and the next, and from them both progressively improve a poor quality code base as well as engage a challenging client amongst challenging circumstances.</p>
<p><strong>Note On Languages</strong></p>
<p>I&#8217;ve intermingled JavaScript, ActionScript, and Lua to help provide a variety of examples, show this list is technology agnostic, and provide corroboration of techniques across technologies. That and I miss coding Lua since I&#8217;ve been so busy and needed an excuse. This does have a strong focus with front-end languages, namely those which run in a browser.</p>
<p><strong>Nomenclature</strong></p>
<p><strong>Factory/Decoder/Parsing</strong>: Taking any kind of data, such as JSON or XML, and converting Â into something you need it for. This could be as simple as accessing properties on it to converting it to a completely different type of object, or even creating new objects from it.</p>
<p><strong>Coding Conventions</strong></p>
<ul>
<li><strong>Factory Errors vs. Null</strong>: Below, I&#8217;m using both error and null. Error means if a Factory/function/decoder fails in anyway to understand its data, you throw an error. This helps in unit testing, and expose errors early in the weakest part of a front end application; those that utilize non-strongly typed data. Optionally, when you find a parsing error, you return null instead. Consumers of the Factory must test for null, but youÂ mitigateÂ runtime exceptions and expose faulty consumers. I like using both, but it&#8217;s a lot of work to be sure.</li>
<li><strong>Don&#8217;t Create Grenades</strong>: Regardless of language,Â <a href="http://jessewarden.com/2009/06/error-handling-in-actionscript-3-dont-make-grenades-or-how-to-not-crash-safari.html">you shouldn&#8217;t create grenades</a>. This means don&#8217;t use throw/error. Instead, dispatch a custom error event that is opt-in. Consumers shouldn&#8217;t have to worry about the code they&#8217;re using bubbling up problems to their area of worry unless they&#8217;ve opted into those concerns. ActionScript, JavaScript, and Lua also don&#8217;t have a strongly typed ways to verify with the compiler that these contracts have been met, unlike Java&#8217;s throwable. Thus, don&#8217;t throw, inform to those who wish to know. Log regardless.</li>
<li><strong>Factory vs. VO Self Parsing</strong>: Some like Factory&#8217;s to parse external data (JSON/XML, etc.) into ValueObjects for an increased likehood of DRY code (shared parsing code that&#8217;s easier to unit test). Others like ValueObjects to serialize/deserialize themselves to reduce coding overhead as well as make the API easier to use. I&#8217;ve used both below, but I&#8217;ve found this is usually a team decision and also depends on how complex your VO&#8217;s are.</li>
<li><strong>Model vs. Command vs. Remote Proxy</strong>: From architecture perspective, some people prefer to have a Model handle Application Data, and a Command/Controller/Presenter handle remote Service calls to update that data. Some prefer wrapping both inside of a Remote Proxy (basically a Model that has serivce(s) inside it), and allowing Controllers/Mediators/Presenters/ViewControllers to make calls on those Remote Proxies. I use both Model &amp; Commands below, but no Remote Proxies. It&#8217;s up to you and your team which you think is best. If you&#8217;ve gotten this far in the discussion, you&#8217;re clearly better off than most. The point here is solve for Model and/or Application logic encapsulation.</li>
<li><strong>try/catch</strong>: I use try/catch liberally. Developers concerned about performance, such as game developers or those using complicated parsing algorithms should take note the significant performance cost of try/catch as well as liberal use ofÂ <a href="http://martinfowler.com/refactoring/catalog/extractMethod.html">ExtractMethod</a>. ThisÂ articleÂ assumes the code is in bad shape and you/your team needs to refactor it over many months to ensure your team can preventÂ fire drills, meet milestones, and start to build a firm foundation. If the code base has the following problems outlined in this article, your first order of business should be fixing them first before you start optimizing. If you really need performance, just use unit tests instead and pray.</li>
<li><strong>Singletons</strong>: While not a replacement for global variables, and generally frowned upon, well written ones are a good first step if they have access control and utilize strong-typing. (ex Model).</li>
</ul>
<p><strong>Refactoring Basics</strong></p>
<p>Improving existing code can be done in 3 ways: handling exceptions, using a good architecture, using strong-typing if available, and following refactoring paths. The reason you use refactoring,Â especiallyÂ in a consulting/contracting context with existing code bases is that you&#8217;re not allowed to rewrite them from scratch. Thus an unwritten bequeathment ofÂ responsibilityÂ occurs between the code base and you: it now becomes your problem. Its failings become your failings. The insecurity it gives your client now has them project that insecurity, andÂ responsibilityÂ to remedy it, onto you.</p>
<p>I&#8217;m assuming you&#8217;ve already done a code review by this point to ensure you, or your firm, want to even getÂ involved. If you don&#8217;t but are still here, it&#8217;s probably because they&#8217;re paying you a lot of money to wallow in their mess. In that case, welcome to the suck.</p>
<p>The original <a href="http://martinfowler.com/refactoring/">definition of refactoring</a>, referring to Martin Fowlers here, is making a small, positive change that has low inherent risk. This is done to ensure you don&#8217;t break anything. The theory is, over time if you make enough positive changes, you&#8217;ll make the whole code base positive.</p>
<p>Life is more complex than that, but the point here is that you use refactoring to affect positive change without breaking the code and looking like an idiot in front of your client and ticking off their customers. You <strong>do not</strong> make large, sweeping changes to the code base, even if they are needed. Take it slow and steady, 1 little change at a time. Some of the examples below are small (such as using strong-typing in place of Object and *), and some are larger (such as modifying your Model layer) are larger. Sometimes such changes you need help in tackling because it&#8217;s sphaghetti code; team refactoring can be invigorating and you get a lot more done, so don&#8217;t think you have to do this on your own.</p>
<p>When in doubt, make a small, positive change. If you take more than 3 days to make a change, abort.</p>
<p><strong>Exceptions</strong></p>
<p>Your first priority in refactoring should be handling exceptions or errors. It&#8217;s ok if you see how sausage is made in the meat factory, but it&#8217;s <a href="http://www.msnbc.msn.com/id/46926159/ns/business-us_business/#.T3pMl6sS3vI">not ok</a> if your client does. You can turn explosive bedlam into a controlledÂ spectacle. That&#8217;s right, things breaking can be made into looking like your in total control. Magic isn&#8217;t magic; it&#8217;s sleight of hand through distraction.</p>
<blockquote><p>&#8220;Look at this pretty logging window created by our company to handle such situations. All errors are now known to us, when and where they happen. This awesome ability to report said errors amongst your staff, not just QA, but you, your customers&#8230; everyone, even while in production! No surprises or fire drills here&#8230; ALL at no extra charge.&#8221;</p></blockquote>
<p>But how do we get there? Let&#8217;s start at bottom.</p>
<p>A lot of programming languages execute functions or methods in 2 modes: protected or omg-it-might-blow-up-we&#8217;re-hardcore mode. JavaScript/CoffeeScript, ActionScript, and Java for example use try/catch. Ruby uses begin &amp; rescue. Python uses try/except. Lua uses pcall. Most languages have various ways to ensure that if code explodes, it&#8217;s done so in a controlled fashion. Additionally, some have global exception handling as well.</p>
<p>Exceptions are the first area of uncontrolled chaos that must be contained. No controlled refactoring can take place without tackling these areas first.</p>
<p><strong>Architecture</strong></p>
<p>Architecture comes into play for large code bases, although, using it for small code bases can help you learn (albeit hard to appreciate as it&#8217;ll often get in your way of getting r done).</p>
<p>Architecture refers to how an application is built. It&#8217;s usually anÂ amalgamationÂ of design patterns used in a common way. For the sake of this article, we&#8217;re using architecture in a small sense of the word in helping move parts of the code to be more encapsulated, make things that break easier to identify, test in isolation, that sort of thing. While references to MVC/MVP/MVVM can get really esoteric and subjective, we&#8217;re not concerned with that.</p>
<p>What you need to verify with defining &#8220;good architecture&#8221; for you and your team is how it works, agree on approach, and ensure it helps you test things in isolation. If y&#8217;all agree, can be independently productive, and if something breaks you know where&#8230; that&#8217;s good architecture. Don&#8217;t get hung up on the definitions, get hung up on the contract on how things talk to each other, and that your team all agrees on that contract. This&#8217;ll come into play later in the next article regarding team synergy.</p>
<p><strong>Strong Typing</strong></p>
<p>Not much to say here. Don&#8217;t use Object/*/Dictionary. If you do, wrap it with a strongly typed API or unit tests. Putting the burden on the consumer of those objects leads to lots of code. Lots of code == bad.</p>
<p>Don&#8217;t do this:</p>
<pre lang="actionscript">var person:Object = {};
person.firstName = "Jesse";
person.lastName = "Warden";</pre>
<p>Do this:</p>
<pre lang="actionscript">class PersonVO
{
   public var firstName:String;
   public var lastName:String;
}

var person:PersonVO = new PersonVO();
person.firstName = "Jesse";
person.lastName = "Warden";</pre>
<p>When you don&#8217;t have strong-typing (JavaScript/CoffeeScript/Lua), <a href="http://jessewarden.com/archives/pix/moar-unit-tests-jxl.jpg">#moarUnitTests</a>. For JavaScript use <a href="http://jshint.com">jshint</a>,Â <a href="http://jslint.com">jslint</a>, and annotations that various frameworks use to infer type like Google&#8217;s Closure compilerÂ for great justice.</p>
<p><strong>Refactoring Paths</strong></p>
<p>Beyond the suggestions below + mentioned resources, you have to use your own intuition. Refactorings on their own are good but when done as a team effort in strategic areas, you can make greater headway, earn more trust from your client, and do more &#8220;relevant&#8221; refactoring.</p>
<p>There are some things you&#8217;ll know are right such as investing in a good GUI logger, making friends with IT, etc. Others, on what to fix first, how to support dual architectures in some areas, and how to portray transparency to your client&#8230; some of those are just experience. When in doubt, go with your gut. The less code of the choices, the better.</p>
<p>A good refactoring path allows you the ability to code right now, satisfy non-programmers for trust earning, with assurance you havenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t coded yourself into a corner. It&#8217;s like a good marriage:Â compromise.</p>
<p>You&#8217;ll lose some battles. The goal is to win the war.</p>
<p>You&#8217;ll have detractors such asÂ who don&#8217;t have their Code License; knowing the rules before breaking them&#8230; or some who are just afraid. Some are ivory tower zealots who aren&#8217;t punished for getting nothing done (some are rewarded). Some have emotional scars from attempting to fix things, and are hesitant to do what&#8217;s right. This is usually when they know the value but cannot effectively articulate it to stakeholders (this is called a &#8220;software developer&#8221;). Some are just insecure and don&#8217;t believe in their own refactoring ability and thus hold you back as well (<a href="http://en.wikipedia.org/wiki/DISC_assessment">low D on DISC</a>). Some think you&#8217;re full of it.</p>
<p>Refactoring is temporal. You are creating a positive change to last for awhile&#8230; but not forever. It&#8217;s ok to refactor something, then refactor it again later as long as you&#8217;re actually making an improvement upon a problem. If a ship is taking on water, the first thing you do is plug the holes with wooden spikes. Later, when the French stop firing at you and your hangover is gone from drinking all the wine you found on their now apprehended ship, you can plug the holes proper with a leather &amp; tar mixture. Then once in dry dock, replace the planks.</p>
<p>Architecture is not temporal&#8230; but can be as well. You&#8217;re supposed to establish rules and guidelines on how you approach a code base. Sometimes, however, you can jury-rig a solution to hit some deadline, or get a build out the door for some managerial milestone. Later, you can re-assess. Sometimes, you&#8217;re initial hack is controlled; meaning you are writing throwaway code on purpose. In doing so, you can make it easier to fix later.</p>
<p>Architecture is generally decided upon by the team, and you move forward for the length of the project on it.</p>
<p>Refactoring is a strategy that can change daily.</p>
<p><strong>Step #1: Exceptions</strong></p>
<p><strong>Case</strong>: Service layer has 3 failure points: entry, error, and exit parsing.<br />
<strong>Solution</strong>: Validate post data, log error, wrap parsing/factory/decoding.<br />
<strong>Language</strong>: JavaScript using <a href="http://amplifyjs.com">AmplifyJS</a></p>
<p><strong>Bad Code</strong>:</p>
<pre lang="javascript">amplify.request.decoders.appEnvelope =
    function ( data, status, xhr, success, error )
    {
        if ( data.status === "success" )
        {
            success( data.data );
        } else if ( data.status === "fail" || data.status === "error" )
        {
            error( data.message, data.status );
        } else {
            error( data.message , "fatal" );
        }
    };

amplify.request.define( "decoderExample", "ajax", {
    url: "http://server.com/service/doSomething/",
    type: "POST",
    decoder: "appEnvelope"
});

amplify.request({
    resourceId: "decoderExample",
    success: function( data )
    {
        data.foo; // bar
    },
    error: function( message, level )
    {
        alert( "always handle errors with alerts." );
    }
});</pre>
<p><strong>Refactored Code</strong>:</p>
<pre lang="javascript">/*
Our decoder function is now:
1. shielded from bad data
2. assumes the response not well formed from the get go
3. logs each parsing error separately for easier diagnosis
*/

// modified appEnvelope decoder function
function ( data, status, xhr, success, error )
{
    try
    {
        if(data == null || data == "")
        {
            error("Decoding error in parsing data.");
        }
        else if(data.status == null || data.status != "")
        {
            error("Unknown status.");
        }
        else if(data.message == null || data.message != "")
        {
            error("Uknown message.");
        }
        else if ( data.status === "success" )
        {
            success( data.data );
        }
        else if ( data.status === "fail" || data.status === "error" )
        {
            error( data.message, data.status );
        }
        else
        {
            error( data.message , "fatal" );
        }
    }
    catch(e)
    {
       error("Decoding error.");
    }
};

/*
Notice we:
1. Validate our requestData (you could do more than a null check) before making an actual service call.
2. Additionally, we log the failed request with the Service name and reason for easier diagnosis in a larger application.
*/

if(requestData != null)
{
    amplify.request({
        resourceId: "decoderExample",,
        data: requestData,
        success: function( data )
        {
            data.foo; // bar
        },
        /*
        Our request error handling now has:
        1. a log, vs. an alert, for logging our error
        2. a common logging signature for easier diagnosis in a larger application
        */
        error: function( message, level )
        {
            console.error("MyService::error, message: " + message + ", level: " + level);
        }
    });
}
else
{
    console.error("MyService::error, requestData is null.");
}</pre>
<p><strong>Case</strong>: Null values in GUI. View/GUI must assume data is not always good; must handle null without exploding.<br />
<strong>Solution</strong>: Check for null using if/then.<br />
<strong>Language</strong>: ActionScript 3</p>
<p><strong>Bad Code</strong>:</p>
<pre lang="actionscript">myTextField.text = person.name;</pre>
<p><strong>Refactored Code</strong>:</p>
<pre lang="actionscript">/*
We now:
1. check for a null VO first
2. if it is in fact null, we have a visual, conventional way of displaying null values w/o exploding.
3. if a property of the VO is null, that'll display as normal (in this case as an empty String)
*/

if(person)
{
   myTextField.text = person.name;
}
else
{
   myTextField.text = "???";
}</pre>
<p><strong>Case</strong>: Global Exception Handling<br />
<strong>Solution</strong>: Add global handler that logs errors away from users to see.<br />
<strong>Language</strong>: ActionScript and JavaScript</p>
<p><strong>Refactored ActionScript Code</strong>:</p>
<pre lang="actionscript">package
{
   import flash.display.Sprite;
   import flash.events.Event;
   import flash.events.UncaughtErrorEvent;

   public class ErrorHandling extends Sprite
   {
      public function ErrorHandling()
      {
         super();
         addEventListener(Event.ADDED_TO_STAGE, onAdded);
      }

      private function onAdded(event:Event):void
      {
         loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);
      }

      private function onUncaughtError(event:UncaughtErrorEvent):void
      {
         trace("Uncaught Error: " + event);
         try
         {
            // note, fails in Asyncronous errors
            throw new Error("stack trace creator");
         }
         catch(error:Error)
         {
            trace(error.getStackTrace());
         }
      }
   }
}</pre>
<p><strong>Refactored JavaScript Code</strong>:</p>
<pre lang="javascript">// via http://stackoverflow.com/questions/951791/javascript-global-error-handling
//
// more techniques here for Opera/Safari older versions
// http://stackoverflow.com/questions/645840/mimic-window-onerror-in-opera-using-javascript
//
// also note various browsers pass different arguments, and some suggest
// handling existing handlers if they exist
// https://developer.mozilla.org/en/DOM/window.onerror
//
// also note that the error in some browsers will still occur unless you handle it
// a certain way; here we're returning true from the error handler to do so.

window.onerror = function()
{
    if(arguments &amp;&amp; arguments.length &amp;&amp; arguments.length &gt; 0)
    {
        var logStr = "";
        var len = arguments.length;
        for(var index = 0; index &lt; len; index++)
        {
            logStr += "\t" + arguments[index] + "\n";
        }
        console.error("Global Error:\n" + logStr);
    }
    else
    {
        console.log("Global Error");
    }
    return true;
};</pre>
<p><strong>Step #2: Architecture</strong></p>
<p><strong>Case</strong>: Encapsulation of statefull, Model data.<br />
<strong>Solution</strong>: Encapsulate Setting of Model Data to single place (DRY)<br />
<strong>Language</strong>: Lua in Corona SDK</p>
<p><strong>Bad Code</strong>:</p>
<pre lang="lua">_G.score = 0

local scoreText = display.newText()
function updateScoreText()
   scoreText.text = _G.score
end
updateScoreText()

local powerUp = display.newImage("powerup.png")
powerUp.name = "powerUp"

local enemy = display.newImage("enemy.png")
enemy.name = "enemy"
function enemy:collision(event)
   if event.phase == "began" then
      if event.target.name == "bullet" then
         _G.score = _G.score + 1
      end
   end
end
enemy:addEventListener("collision", enemy)

local ship = display.newImage("ship.png")
function ship:collision(event)
   if event.phase == "began" then
      if event.target.name == "powerUp" then
         _G.score = _G.score + 1
         updateScoreText()
         return true
      end
   end
end
ship:addEventListener("collision", ship)

function onTouch(event)
   if event.phase == "began" then
      local bullet = display.newImage("bullet.png")
      bullet.name = "bullet"
      return true
   end
end

Runtime:addEventListener("touch", onTouch)</pre>
<p><strong>Refactored Code Round 1</strong>:</p>
<pre lang="lua">--[[
Notice we've added an addScore method to:
1. have a central place everyone can update the model data
2. make it easier to identify WHO is calling this add function
3. ensure we never forget to update our Text Field with the latest value like in the original code
]]--

function addScore(amount)
   _G.score = _G.score + amount
   updateScoreText()
end

-- Fixing our enemy collision handler to now call our encapsulated method
function enemy:collision(event)
   if event.phase == "began" then
      if event.target.name == "bullet" then
         addScore(1)
      end
   end
end</pre>
<p><strong>Refactored Code Round 2</strong>:</p>
<pre lang="lua">--[[
Now we use a more generalized Observer pattern, and dispatch an event
when the value changes. The system is free to listen to this event
and react however it needs to. This allows the GUI to change w/o worrying
updating the model changing behavior to compensate for a changing GUI API.
]]--

function addScore(amount)
   _G.score = _G.score + amount
   Runtime:dispatchEvent({name="onScoreChanged", newScore=_G.score})
end

-- we now can update more GUI parts as they become needed
function onScoreUpdated(event)
   updateScoreText(event.newScore)
end
Runtime:addEventListener("onScoreChanged", onScoreUpdated)

-- notice this includes encapsulated GUI controls as well;
-- they can just listen in on the Event Bus.
-- Here, we have a Level Progress bar that listens to the score change
-- to visually indicate how far along the user is until they level up.
require "com.company.project.controls.ProgressBar"

LevelUpProgressBar = {}

function LevelUpProgressBar:new()

   local bar = ProgressBar:new({width = 100, height = 60})
   bar.levelMax = 1

   function bar:onScoreChanged(event)
      self:setProgress(event.newScore, self.levelMax)
   end

   function bar:onLevelMaxChanged(event)
      self.levelMax = event.newLevelMax
   end

   Runtime:addEventListener("onLevelMaxChanged", bar)
   Runtime:addEventListener("onScoreChanged", bar)

end

return LevelUpProgressBar</pre>
<p><strong>Case</strong>: Access Control for Statefull Model Data Using Application Logic (English: you need to update some model data, and multiple parts in your application need to do this). aka, removing global variables.<br />
<strong>Solution</strong>: Utilize Proxy Pattern or Command Pattern for single access (DRY), this ensures there is only 1 way to update your model data, inputs are validated. This makes it easier to debug who is calling/invoking it, and what data they are passing, as well as ensuring those who need to know about the change are informed.<br />
<strong>Language</strong>: ActionScript</p>
<p><strong>Bad Code</strong>:</p>
<pre lang="actionscript">var firstName:String             = firstNameTextInput.text;
var lastName:String              = lastNameTextInput.text;
var birthdate:Date               = birthdateControl.value;
var myPersonVO:PersonVO          = new PersonVO(firstName, lastName, birthdate);
MyStaticModel.person             = myPersonVO;
MyStaticModel.person.lastName    = "McTaggart"</pre>
<p><strong>Refactored Code</strong>:</p>
<pre lang="actionscript">// First we create a factory class to test our creation &amp; validation in isolation.
// This is also easier to write unit tests for. It's also DRY in that all classes
// who need to create PersonVO's and validate them are using the same code to do so.

class PersonFactory
{
   public static function getPerson(firstName:String, lastName:String, birthdate:Date):PersonVO
   {
      if(firstName == null || firstName == "")
      {
         throw new Error("firstName cannot be null nor an empty String.");
         return;
      }

      if(lastName == null || lastName == "")
      {
         throw new Error("lastName cannot be null nor an empty String.");
         return;
      }

      if(birthdate == null)
      {
         throw new Date("birthdate cannot be null.");
      }

      return new PersonVO(firstName, lastName, birthdate);
   }

   public static const validateLastName(lastName:String):Boolean
   {
      if(lastName != null &amp;&amp; lastName != "")
      {
         return true;
      }
      else
      {
         return false;
      }
   }
}

// Second step, create a change event that those who need to know about a changing
// personVO in the model can be made aware of.

class PersonModelEvent extends Event
{

   public static const PERSON_CHANGED:String = "personChanged";

   public function PersonModelEvent(type:String)
   {
      super(type, false, true);
   }

}

/*
Third, create a Model class Singleton that:
- dispatches change events when it's internal person variable is changed, or modified
through accessor controls
- validates creation &amp; changes
NOTE: If classes need to operate on PersonVO itself, create additional methods to
operate on the internal PersonVO to ensure proper change events are dispatched.
NOTE: For those who wish to remove Singletons, create as an instance, and inject the dependencies,
whether via a DI framework such as SwiftSuspenders/Guice/Spring, or manually via
getter/setters for those classes who need instance access.
*/

class PersonModel extends EventDispatcher
{

   private var _person:PersonVO;

   public function get person():PersonVO { return _person; }
   public function set person(value:PersonVO):void
   {
      _person = value;
      dispatchEvent(new PersonModelEvent(PersonModelEvent.PERSON_CHANGED));
   }

   public function PersonModel()
   {
   }

   public function setNewPerson(firstName:String, lastName:String, birthdate:Date):void
   {
      // first, validate data is good, don't want to pollute our model
      var personVO:PersonVO;
      try
      {
         personVO = PersonFactory.getPerson(firstName, lastName, birthdate);
         person = personVO;
      }
      catch(error:Error)
      {
         trace("PersonModel::setNewPerson error: " + error);
      }
   }

   public function updateLastName(lastName:String):void
   {
      if(person)
      {
         if(PersonFactory.validateLastName(lastName) == true)
         {
            person.lastName = lastName;
            dispatchEvent(new PersonModelEvent(PersonModelEvent.PERSON_CHANGED));
         }
         else
         {
            trace("PersonModel::updateLastName, failed because the lastName '" + lastName + "' is invalid.");
         }
      }
      else
      {
         trace("PersonModel::updateLastName, failed because the current person is null.");
      }
   }

   private static var _inst:PersonModel;

   public static function get instance():PersonModel
   {
      if(_inst == null)
         _inst = new PersonModel();

      return _inst;
   }
}</pre>
<p><strong>Refactored Code 2</strong>:</p>
<pre lang="actionscript">/*
In the case of need of many needing to affect the Model, and there is no
desire to all Models/Proxies to have public methods accessible by others,
you can use the Command pattern. Additionally, this solves the use case
where multiple Models are needed to be accessed and/or modified. Finally,
we also handle asynchronous use cases where you need to update a Model(s)
based on a server response. Notice how each step is validated, and a log is
produced if any step fails. You need to know WHERE it failed and WHY.
Also, no rollback support in the following.
*/

class CreatePersonEvent extends Event
{
   public static const CREATE_PERSON:String = "createPerson";

   public var firstName:String;
   public var lastName:String;
   public var birthdate:Date;
   public var personModel:PersonModel;
   public var organizationModel:OrganizationModel;

   public function CreatePersonEvent()
   {
      super(CREATE_PERSON);
   }
}

class CreatePersonCommand extends AsynCommand
{

   // injected dependencies; you could use a DI framework,
   // wrap Command class creation with these, or simply pass
   // in through the Event payload like the below shows.
   private var personModel:PersonModel;
   private var organizationModel:PersonModel;
   private var createPersonService:RESTFullCreatePersonService;
   private var personVOToCreate:PersonVO;

   // Create a PersonVO, set on the PersonModel,
   // and ensure the OrganizationModel is updated with the
   // new person once the server has verified it's creation.
   public function execute(event:CreatePersonEvent):void
   {
      try
      {
         personModel = event.personModel;
         organizationModel = event.organizationModel;
         personVOToCreate = PersonFactory.getPerson(firstName, lastName, birthdate);
         if(personVOToCreate != null)
         {
            createPerson()
         }
         else
         {
            throw new Error("ERROR: CreatePersonCommand::exeucte, PersonFactory returned null.");
         }
      }
      catch(error:Error)
      {
         trace("ERROR: CreatePersonCommand::execute, error: " + error);
         finish();
      }
   }

   private function createPerson():void
   {
      createPersonService = new RESTFullCreatePersonService();
      createPersonService.addEventListener("success", onCreatePersonSuccess);
      createPersonService.addEventListener("error", onCreatePersonError);
      createPersonService.createPerson(personVOToCreate);
   }

   private function onCreatePersonError(event:Event):void
   {
      trace("ERROR: CreatePersonCommand::onCreatePersonError, event: " + event);
      finish();
   }

   private function onCreatePersonSuccess(event:Event):void
   {
      // server has successfully created PersonVO, let's update ours with what
      // the server sent back to ensure we now have a proper PersonVO.ID set
      // by the server
      if(createPersonService.savedPersonVO != null)
      {
         personModel.person = createPersonService.savedPersonVO;
         organizationModel.addNewPerson(personModel.person);
      }
      else
      {
         trace("ERROR: CreatePersonCommand::onCreatePersonSuccess failed, server sent back a null savedPersonVO.");
      }
      finish();
   }

}</pre>
<p><strong>Step #3: Strong Typing</strong></p>
<p><strong>Case</strong>: Using loose typing/variants/Objects/*, resulting in loss of compiler time checking and thus errors that only appear at runtime.<br />
<strong>Solution</strong>: Use strong-typing.<br />
<strong>Language</strong>: ActionScript</p>
<p><strong>Bad Code</strong>:</p>
<pre lang="actionscript">/*
Notice:
- personVO.lstName is a mispelling, but no error will be raised by the compiler.
- no error will be raised by the updatePerson function as Object is dynamic,
and lastName will be created and set on the personVO Object.
- no error will be raised if you pass something other than a personVO to updatePerson
except for runtime errors
*/

var personVO:Object = {};
personVO.firstName = "Jesse";
personVO.lstName = "Warden";

function updatePerson(person:*, newNameFromStringBlock:String):void
{
   var nameArray:Array = newNameFromStringBlock.split(" ");
   person.firstName = nameArray[0];
   person.lastName = nameArray[1];
}</pre>
<p><strong>Refactored Code</strong>:</p>
<pre lang="actionscript">/*
Notice:
- our "lstName" will be caught by the compiler
- our updatePerson function ensures only a PersonVO is accepted to be operated on. If not,
our compiler will let us know.
*/

class PersonVO
{
   public var firstName:String;
   public var lastName:String;
}

var personVO:PersonVO = new PersonVO();
personVO.firstName = "Jesse";
personVO.lstName = "Warden";

function updatePerson(person:PersonVO, newNameFromStringBlock:String):void
{
   var nameArray:Array = newNameFromStringBlock.split(" ");
   person.firstName = nameArray[0];
   person.lastName = nameArray[1];
}</pre>
<p><strong>Case</strong>: Service layer has no input validation, is hard to test, and has no error reporting. Burden is on class user to wrap in try/catch as well as parse server response including knowing business logic. Finally, asynchronous loader is not a class member variable, thus potential memory leak + harder to debug.<br />
<strong>Solution</strong>: Create a Service class that is easy to use, validates inputs, and logs errors. Encapsulates business logic.<br />
<strong>Langauge</strong>: ActionScript</p>
<p><strong>Bad Code</strong>:</p>
<pre lang="actionscript">class CreatePersonService extends EventDispatcher
{

   public var loader:URLLoader;

   public function CreatePersonService()
   {
      super();
   }

   public function createPerson(person:PersonVO):void
   {
      var loader = new URLLoader();
      loader.addEventListener(Event.COMPLETE, onComplete);
      var req:URLRequest = new URLRequest("http://someserver.com/restful/api/");
      req.data = person.toJSON();
      loader.load(req);
   }

   private function onComplete(event:Event):void
   {
      dispatchEvent(new Event("success"));
   }
}

var service:CreatePersonService = new CreatePersonService();
service.addEventListener("success", onSuccess);

function onSuccess(event:Event):void
{
   var json:Object = JSON.decode(service.loader.data);
   var person:PersonVO = new PersonVO(json.firstName, json.lastName, json.birthdate);
}</pre>
<p><strong>Refactored Code</strong>:</p>
<pre lang="actionscript">/*
Note:
- createPerson validates you gave it a valid PersonVO.
- all errors within class are opt-in, no throw's. User has to register event listener to hear; #dontCreateGrenades
- class assumes single-concurrency if possible, kills previous load call before proceeding
- listens for all errors, and responds with 1 error with more detail logged if needed; simplifies API
- wraps actual call to verify SecurityError isn't thrown and if it is, it's logged w/ opt-in error
- uses united tested Factory for DRY parsing and assumes
- assumes Factory can fail, and reports it as such
- result in the form of a strongly-typed ValueObject in a read-only property to ensure proper API usage
*/
class CreatePersonService extends EventDispatcher
{

   private var _savedPersonVO:PersonVO;
   private var loader:URLLoader;

   public function get savedPersonVO():PersonVO { return _savedPerson; }

   public function CreatePersonService()
   {
      super();
   }

   public function createPerson(person:PersonVO):void
   {
      _savedPersonVO = null;

      if(person == null)
      {
         onError("You cannot pass in a null person to create.");
         return;
      }

      if(loader == null)
      {
         loader = new URLLoader();
         loader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
         loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
         loader.addEventListener(Event.COMPLETE, onComplete);
      }
      else
      {
         try
         {
            loader.close();
         }
         catch(error:Error)
         {
            // only exception that is ok to swallow
         }
      }

      try
      {
         var req:URLRequest = new URLRequest("http://someserver.com/restful/api/");
         req.data = person.toJSON();
         loader.load(req);
      }
      catch(error:Error)
      {
         onError("CreatePersonService::createPerson, error: " + error);
      }
   }

   private function onIOError(event:IOErrorEvent):void
   {
      onError(event.text);
   }

   private function onSecurityError(event:SecurityErrorEvent):void
   {
      onError(event.text);
   }

   private function onComplete(event:Event):void
   {
      try
      {
         _savedPersonVO = PersonFactory.parsePersonFromJSON(loader.data);
         if(_savedPersonVO != null)
         {
            dispatchEvent(new Event("success"));
         }
         else
         {
            onError("CreatePersonService::onComplete, factory returned a null PersonVO.");
         }
      }
      catch(error:Error)
      {
         onError("CreatePersonService::onComplete, parsing error: " + error);
      }
   }

   private function onError(errorString:String):void
   {
      trace("ERROR: CreatePersonService::onError: " + errorString);
      dispatchEvent(new Event("error"));
   }
}</pre>
<p><strong>Step #4: Fine Tuning</strong></p>
<p>If you made it this far, and have managed to continue to maintain the above, congratulations! This stuff is icing on the cake. You can continue onto <a href="http://martinfowler.com/refactoring/catalog/index.html">smaller scope refactorings</a>, as well as continuing to increase your unit test coverage.</p>
<p><strong>Final Tips</strong></p>
<ol>
<li>When casting, ensure result is not null before using. If null, log the casting failure.</li>
<li>For Flash Player, set ExternalInterface.marshallExceptions = true if using ExternalInterface</li>
<li>Log all errors</li>
<li>Code Review. Often. Weekly. Whatever, pick a schedule.</li>
<li>Object / * / Dictionary == if you can&#8217;t avoid, wrap with unit tests</li>
<li>Remember: small, low-risk changes.</li>
<li>TODO was invented for a reason.</li>
<li>If you haven&#8217;tÂ committed to source controlÂ for 3 full days of working, abort and just check into a branch for later revisiting/reference.</li>
</ol>
<p><strong>Conclusions</strong></p>
<p>Remember, the most important refactoring you can possibly do is reading the code base for 1 hour a day, no more. Just 1 person. This is has more positive impact than good unit test coverage. Daily code reviews, even in isolation, areÂ extremelyÂ important. The earlier in the project life cycle, the better.</p>
<p>From that, you can make small, low risk changes. Keep track with TODO&#8217;s. Breathe, Rome wasn&#8217;t fixed in a day, and a pile of rubbish wasn&#8217;t fixed in one either.</p>
<p>For further, positive refactorings you can check an older <a href="http://martinfowler.com/refactoring/catalog/">list by Martin Fowler</a>, and <a href="http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052/ref=sr_1_1?ie=UTF8&amp;qid=1333060864&amp;sr=8-1">this book</a> has a ton of wonderful ones + tests as well. While a Code Review has decreasing value the more people you add in terms of defects found, the ability to learn &amp; make positive suggestions for architecture are wonderful. If you&#8217;re alone, use <a href="http://codereview.stackexchange.com/">codereview.stackexchange.com</a>.</p>
<p>In the next article I&#8217;ll show you how to get help with the above&#8230; and permission.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2012/04/consulting-chronicles-6-refactoring.html/feed</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Consulting Chronicles #5: Getting In, and Out, of the Industry</title>
		<link>https://jessewarden.com/2011/05/consulting-chronicles-5-getting-in-and-out-of-the-industry.html</link>
					<comments>https://jessewarden.com/2011/05/consulting-chronicles-5-getting-in-and-out-of-the-industry.html#comments</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Thu, 12 May 2011 16:11:59 +0000</pubDate>
				<category><![CDATA[Consulting Chronicles]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[consulting]]></category>
		<category><![CDATA[consultingchronicles]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[scrum]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=2644</guid>

					<description><![CDATA[Today, I&#8217;ll talk about how to get into consulting, what the skills and expectations are, and what can cause you to get out. What is Consulting? Consulting in the Flash/Flex world usually consists of 3 tasks that may be related: Offer your architecture expertise. Offer your code mechanic expertise. Augment an existing team. For #1, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Today, I&#8217;ll talk about how to get into consulting, what the skills and expectations are, and what can cause you to get out.</p>
<p><strong>What is Consulting?</strong></p>
<p>Consulting in the Flash/Flex world usually consists of 3 tasks that may be related:</p>
<ol>
<li>Offer your architecture expertise.</li>
<li>Offer your code mechanic expertise.</li>
<li>Augment an existing team.</li>
</ol>
<p><span id="more-2644"></span>For #1, companies either want you to architect a project, give professional feedback on a suggested/signed off architecture done by another firm (usually to give a stakeholder corroborated evidence), or are having scalability problems and want your advice.</p>
<p>For #2, things aren&#8217;t going well and they want you to fix it. No, not re-write it, fix it.</p>
<p>For #3, they want you to augment an existing team. Some firms do this because the pay + finder fee is good money. Other firms do not because you can sometimes be put into situations where you&#8217;re setup to fail since you may be smart enough to fix it, but you&#8217;re not in charge, thus you cannot do so.</p>
<p>#3 is how I got into consulting, staff augmenting an existing team. While the #1&#8217;s were fun, they were few and far between; usually big companies would rather pay lots of money to fix things vs. pay what it costs to do it right. This isn&#8217;t cynical, this is fact.</p>
<p><strong>Why Get Into Consulting?</strong></p>
<p>The reason is often simple: more money. More money than full-time/salaried/W2 work. More money than freelance/contracting.</p>
<p>Other reasons include working with really smart developers, learning about how Enterprise companies build &amp; sell software, Â learning about how to work in and manage large software teams&#8230; TONS of opportunities to just learn on a variety of subjects. Sometimes people havenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t worked on extremely large codebaseses. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s fun to take all the theory and see what it actually does in the real world, with real people.</p>
<p>Me personally, I like travelling, meeting new people, and seeing how different companies work.</p>
<p><strong>Getting Into Consulting</strong></p>
<p>You have a few options listed in order of ease.</p>
<ol>
<li>Find a firm, become an employee.</li>
<li>Find a firm, become a sub-contractor.</li>
<li>Become an independent contractor.</li>
</ol>
<p>If you find an existing firm, especially when your country isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t in a recession, this is the easiest way. Whether large like Deloitte and Accenture, to smaller firms (more focused on Flash/Flex) like Roundarch and Universal Mind. Regardless of skill level, while youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll be sold to the client as a â€œconsultantâ€, but larger firms will ensure a senior is on the project unless youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re merely staff augmentation. Joining as an employee usually is easier because youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re cheaper tax wise/cost wise to the firm, and youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re more versatile to them. Meaning, since youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re on payroll, they can pay the same rate to fix a huge clientâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s code base as well as working on your firms intranet when in between clients.</p>
<p>If youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re the freelance type, or typically like getting a variety of clients (and often potentially making more money), becoming a sub-contractor is another option. This is how smaller firms get off the ground, and is common place even in larger firms. While you usually cannot do mundane work, this is often easier for smaller firms tax wise, thus itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s an option as well. If the firm has no current clients, you wonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t get any work though. A W2 will get paid for the 2 week downtime, you wonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t. Hustling during consulting engagements is usually harder than hustling during contracting ones.</p>
<p>If you have enough contacts or typically do only Enterprise type software (LiveCycle, BlazeDS, Java/Spring/Hibernate), then going the independent route is also an option. Basically, start your own company, and start working directly with clients. This is the hardest, even if you do Enterprise software, because most larger clients only work with â€œcompaniesâ€. Just because you have a company legally filed on paper doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t mean youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re a â€œcompanyâ€. Often theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll want multiple developers on a whim, liability insurance, and multiple large clients on your track record/portfolio. Iâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />m personally still learning the sales for this, but it seems networking tends to help a lot/the most.</p>
<p>My advice, seek out people you know from the community at Roundarch, Universal Mind, or Cynergy, and make sure youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re known to be available, even if they donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t currently have any openings.</p>
<p><strong>Skills</strong></p>
<p>Being a consultant involves a lot of things a normal software developer doesn&#8217;t do. Even if you&#8217;re a salaried/W2 employee, these are still required:</p>
<ol>
<li>leadership</li>
<li>large scale architecture</li>
<li>travel on-site to client&#8217;s location</li>
<li>expense reporting</li>
<li>meeting clients and their stakeholders</li>
<li>offering professional, 3rd party opinions</li>
<li>dressing nice</li>
<li>attending meetings for a company you don&#8217;t work for</li>
<li>interviewing/hiring members for your team and/or the company&#8217;s on the company&#8217;s behalf</li>
</ol>
<p>All the standard stuff like team management, working with the company&#8217;s stakeholders, and tracking your hours are there too. You also donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t always do all the above mentioned; sometimes just one. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s just those arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t normal required in traditional freelancing (excluding #3 and #5). Let&#8217;s break down what these skills mean.</p>
<p><strong>Leadership</strong></p>
<p>Unless your role is for staff augmentation, leadership is the most important skill for a consultant. You need to be able to inspire confidence in strangers you&#8217;ve just met, inspire confidence in your chosen direction &amp; decisions, and to keep people moving on the right path.</p>
<p>Some leadership skills can be taught. Some people are just born with the other aspects. If you don&#8217;t know how to do this, watch &amp; learn from those that do. Examples include raising your Charisma score. Doing one or more of the following will help:</p>
<ul>
<li>have good hygiene</li>
<li>have clean clothes that are ironed</li>
<li>dress to impress; this boosts your confidence as well. You want to look successful.</li>
<li>listen: people like good listeners</li>
<li>empathy: people like others who understand them. If you listen to their pains, and sound like you understand, you connect.</li>
<li>be knowledgeable: if you know what you&#8217;re talking about, you&#8217;ll exude confidence when you talk. You also won&#8217;t get offended if someone disagrees and will want to hear their point of view. If you don&#8217;t know, ask/listen vs. act like you know.</li>
<li>have a vision: assuming you know the companies problems, have a long term vision to fix everything. Communicating this to your colleague and your clientâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s employeeâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s is paramount.</li>
<li>communication: you need to be an effective communicator to articulate your vision to others, and get them to follow you. Be relaxed, look people in the eyes, be confident in your delivery, and be open to listen. Using slang/ebonics/l33t in normal conversation negatively affects peopleâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s perception of you. Be professional when you speak.</li>
<li>egg shells: crush those sons of bitches. You do NOT walk on egg shells. You&#8217;re a consultant; grab drama by the neck, raise it high, and execute it. Then, move forward.</li>
<li>be positive: while Andrew Dice Clay and Rush Limbaugh have gotten popular for their negative spin on things, they don&#8217;t last. Positivity is the antithesis to Entropy; that lasts, especially in people&#8217;s perception of you.</li>
<li>control your emotions: software is hard. People in large groups do really dumb things, particularly large companies. Have patience, breathe, and keep your emotions in check. Â Your self-control inspires confidence in your actions by others. People assume you have things under control if you&#8217;re relaxed and poised.</li>
<li>win: You have to WANT to win. You need ambition to reach your goals and vision. If you have that, you&#8217;ll have the motivation to do all of the above.</li>
</ul>
<p><strong>Large Scale Architecture</strong></p>
<p>The most common need in the Flex world is architecting how the Flex talks to the BlazeDS/LiveCycle, and how that talks to the Java, and how that talks to the client&#8217;s stuff. Often, they&#8217;ll have an existing infrastructure in place and you&#8217;ll need to decide &amp; describe how and where to integrate technology stacks to a client&#8217;s existing infrastructure and possibly already in progress project with the existing resources, which are often in a variety of teams.</p>
<p>You need to know this well enough that you can cater design, development, and deployment techniques to various client needs. You need to be able to effectively articulate these to the client, the team, and ensure the tasks meet the resources currently available; meaning the client can build, deploy, and support what you&#8217;re actually suggesting to do. Thatâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a lot of traditionally Project Management tasks.</p>
<p>If you don&#8217;t know how to architect large Enterprise sized projects, specifically Flex, learn. If the back-end/middle tier isn&#8217;t your thing, partner with those who know it. Unlike learning traditional software skills, you can&#8217;t really get away with practicing as a consultant. Based on my consulting gigs people can do this all the time if they&#8217;re a salaried employee of a large company. So, if you want to get on the fast track to learn, join <a href="http://universalmind.com/">a consulting firm</a> and get mentored.</p>
<p><strong>Travel On-site to Client</strong></p>
<p>Unless it&#8217;s staff aug, most consulting involves travelling on-site to the client&#8217;s location(s) to meet the stakeholders and team. This means donning your business casual, booking airfare &amp; hotel, and travelling both on the weekend and during the week. Being responsible by ensuring you have ample lay over time, donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t get the last flight out, Â arriving to the airport early, and arriving at a client site early to ensure you&#8217;ve gotten enough sleep are assumed.</p>
<p>For those with needy significant others and/or young children, this is challenging to do, and will determine if you do higher level consulting or not. This has forcibly paused my career which Iâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll defer to a later blog post.</p>
<p>To me, this was one of the draws I have to consulting. I like traveling to new places, meeting new people, and the lifestyle of being on the move. Being on the road is one thing that&#8217;s therapeutic to me.</p>
<p>If you don&#8217;t have a few thousand in the bank to cover the costs (flight, hotel, fuel, food), the firm you work for will have to front the money. Either way, you have to ensure this is tracked as reimbursed expenses for tax purposes (unless you&#8217;re salaried with the firm). The benefit of paying for these things yourself are tax write off opportunities as well as frequent flyer miles with certain airlines.</p>
<p>If you can use expedia.com, drive a car, and find your way around an airport, you&#8217;ll be fine. Sometimes you get to meet new people you sit next to on the plane. Yes, there are cool people in coach, but you want to strive to be in first class even if the company will only fund coach. Make sure you use your own miles program vs. the companies if you can. You aren&#8217;t paid for your travel time like lawyers, so it&#8217;s nice to have some way to offset costs; i.e. being able to work. Trying to type on your laptop in coach is torture vs. first class.</p>
<p><strong>Expense Reporting</strong></p>
<p>A lot of consultants, even if salaried, are required to document their time and expenses. This means documenting, usually in some web based time tracking program. Thus, you need to be aware of how much time you&#8217;re spending on tasks, what those tasks were, and how much more you think you&#8217;ll do. This can get tricky, too, when you end up in a staff aug position and basically end up running the project. Suddenly you&#8217;re holding the ball, and people are wondering why you&#8217;re billing time for meetings vs. coding&#8230; you can get into really uncomfortable, and extremely irritating and unfair situations. Examples include being the architect &amp; mentoring company employed developers on the project, and when the UAT comes up at the end of an Agile SCRUM Sprint, you show zero User Story points completed, and people in charge question what value youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re providing.</p>
<p>If you document well, cya (cover yer arse), and have transparency with the client into what you&#8217;re spending your time on by talking to them early and often, you&#8217;ll do fine. While they often don&#8217;t plan for you to spend a lot of your time in meetings for doing architecture, as long as they&#8217;re aware that out of 4 months of billable hours, 2 months were spent helping the client align their processes to ensure they could support the app, ensure the user stories/features in the application were valid, and the design was actually capable of being built&#8230; then you&#8217;ll at least get paid.</p>
<p>Document your time, be aware of what you&#8217;re working on, and what you need to work on. Communicate what you&#8217;re doing for the client often.</p>
<p><strong>Meeting the Client and Its Stakeholders</strong></p>
<p>I like meeting new people. I like talking. I like meeting successful people and learning from them. Consulting with companies that desire your expertise teaches you a lot about software that supersedes the construction of it, but how it&#8217;s actually consumed and sold. This makes you question a lot of the commonly held beliefs by OOP Purists and other fads touted in the news. It&#8217;s awesome. You get to learn how to build software, how to fix it, how to align teams, how to prevent fire drills, why you&#8217;d even want to prevent a fire drill, how to compromise amongst silo&#8217;d departments, how itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s sold&#8230; the list goes on and on.</p>
<p>To get things done, and get bigger problems resolved (like using the wrong technology stack/methodologies/processes), youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll have to meet &amp; talk with the big wigs. If you arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t comfortable talking with upper level management, having an MBA helps. If that isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t your thing, find someone who is good at it, and learn. Sometimes these are either A) the only people that can move you forward and/or B) theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll great at articulating why youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re so effâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />d and just need to deal with it.</p>
<p>Bottom line, you can get the REAL story behind why the way things are, and exactly where they are going by talking to project stakeholders vs. the variety of â€œthis is my world at this companyâ€ responses youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll get from interviewing employees who arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t Director level or higher.</p>
<p><strong>Offering Professional, 3rd Party Opinions</strong></p>
<p>Often youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re firm will be hired for your realm of expertise. Other times, they already have the expertise, whether internal employees or another firm, and just want your opinion as a 3rd party who isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t currently involved nor has stake in the current project. They actually care what youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re opinion is and pay for it. This helps them confirm what they already know with an â€œiron cladâ€ assessment, or perhaps challenging strongly held beliefs in a certain section of the company.</p>
<p>Sometimes these validations, such as:</p>
<p>â€œYes, this other consulting firm is billing out a bunch of n00bs to you for $150/hr, and yes, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re internal employee DID in fact build something amazing in 1 week what the 2 n00bs couldnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t do in 3 months.â€</p>
<p>&#8230;lead to consulting engagements. Sometimes confirming what the company already knows builds trust, and thus leads to a longer term engagement.</p>
<p>Other times youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re actually hired for a less valued position such as staff augmentation, but youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re experience/knowledge ARE in fact beneficial the project. Thus, you need to find a way to ensure those who need to know learn about what you know. If you sucked, you wouldnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t be hired for your high price, thus, ensure the client gets value from you via your professional opinions.</p>
<p><strong>Dressing Nice</strong></p>
<p>Iâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve mentioned this countless times before. Clothes make the man. Women typically dress to impress other women; in this case, women need to dress to impress the client. Business casual is usually ok, although, the larger the account, the more formal you need to look. In my opinion, you CANNOT be overdressed for an engagement. If someone mentions on the side you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t have to, theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re either threatened, or donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t understand the game.</p>
<p>Dress to impress. If you look impressive, you must be impressive. Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re thus apparently successful because youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re knowledgeable. This includes accessories such as the car you drive, the bag/briefcase you carry, and the business card you deploy.</p>
<p><strong>Attending Meetings for a Company You Donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t Work For</strong></p>
<p>Sometimes, especially if you end up being a shield for the rest of the team, or if you just want to learn about the lay of the land, the players, and all the drama, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll need to attend company meetings. These are often a waste of time, or things to be avoided at all costs. However, to management, THIS is their transparency to give to stakeholders at some companies. Providing attendance by your firm is often a requirement.</p>
<p>Either way, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re involved in the project, and need to attend the meetings, and sometimes participate. Sometimes you even need to call/create meetings (OMG, the horror!). These are usually to get consensus from the team on an issue that you couldnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t do in SCRUM, or resolve drama, or to brainstorm on how to solve some challenging coding issue.</p>
<p><strong>Interviewing/Hiring Members for Your Team and/or the Company&#8217;s on the Company&#8217;s Behalf</strong></p>
<p>Sometimes youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re brought onto a project, and realize you need help. The company looks to you to â€œbuild itâ€ or â€œfix itâ€; if that means more developers/designers from your firm, so be it, theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll find the budget. Getting resources can be challenging. At a smaller firm, you may have to have the resources yourself already ready to go. <a href="http://twitter.com/davidortinau">David Ortinau</a>, one of my mentors on this, has helped me create a spreadsheet of people Iâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve met over the years. On it, I list out people Iâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />d hire (and who I wonâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t ever hire), what their speciality is, and what the last rate I got them for was. This is because they are often working for me. Even at my firm, my partners are uber-busy, so I canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t immediately assume theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re always available. Obviously theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re my first pick to work with.</p>
<p>If youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re with a larger firm, they can often help in 2 ways. First, they can provide you additional consultants if the client has the budget for it. Secondly, they can sometimes provide resources from other firms. This is more challenging because usually the other firm will want their cut of providing a resource. This means, either your firm makes less revenue from that resource, or justifies the lack of serious profit from your dire need&#8230;. or both.</p>
<p>Other times, the company is looking to maintain the solution/software you/you and their team has created. This means hiring employees that work for the client. They&#8217;re responsibilities include adding features to &amp; maintaining that software. Often, youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re the most qualified to hire said employees. Interviewing potential coders is a challenge &amp; learned set of skills in and of itself.</p>
<p><strong>Getting Out of Consulting</strong></p>
<p>A profession that provides a significant amount of money, a huge opportunity to learn, and networking opportunities with new people &amp; companies seems like something you wouldnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t ever want to leave, right?</p>
<p>Wrong.</p>
<p>Consulting has a lot of overhead on the soul. This includes the following:</p>
<ul>
<li>copious amounts of travel to be on-site wherever the client is. This is time away from your loved ones.</li>
<li>dealing with incompetence where said incompetence cannot be fired/laid off, yet continues to actively sabotage your project and/or client relationship.</li>
<li>dealing with politics that theoretically help the companyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s stockholders, but ensure the software team is setup to fail</li>
<li>various implementations of Agile SCRUM that arenâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t true to the tenets of SCRUM, and thus donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t see the benefit of it. A lot of times, this angers everyone involved in the team including the PMâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s running it, and is just a gross feeling.</li>
<li>You potentially never â€œlove the codeâ€ youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re working on.</li>
<li>The ultimate consulting goal of â€œleaving the company better than you found itâ€ may potentially be unknowable in how to do so.</li>
<li>Entropy is scientific fact that all things eventually will return to chaos. Youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re constantly fighting this in consulting/leading large teams regarding the code base; this can take an emotional, and spiritual, toll.</li>
<li>Sometimes, companies pay you lots of money to produce code that never sees the light of day.</li>
<li>Sometimes, companies pay you lots of money to code in an IDE you loathe on an OS you are unfamiliar with using a framework you hate implementing design patterns you disagree with amongst a team who doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t understand why youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re unhappy with the status quo.</li>
<li>If things go sour, you can sometimes not get paid, or take awhile to get paid.</li>
<li>Depending on the team, the complex processes involved on the surface appear to provide no value to the project and prevent developers from actually writing code since they&#8217;re in meetings or writing docs instead.</li>
</ul>
<p>Add to that the paperwork around expenses &amp; taxes, and itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s an enough to make anyone want a salaried job. A steady, consistent paycheck with easy taxes. Sometimes way less stress, too.</p>
<p>In most cases Iâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ve seen a change of scenery, a long vacation, or just a different project is enough to rejuvenate even the most burnt out consultants. Other times a dive back into the W2 world is a great vacation from consulting.</p>
<p>Just be aware there is a huge pay scale difference between consulting and non-Enterprise salaried positions. Just because you take a salaried, full-time position at a large company because they offer comparable money &amp; benefits doesnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t mean youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll actually be able to use your consulting skills. There is a lot of power in not working for a company directly. You can get away with telling them off for being incompetent, explaining how to get out of the mess, and theyâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />ll thank you for it. You do that as an employee, you typically get a different reaction, one you donâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t want.</p>
<p>Bottom line, this can make finding comparable employment &amp; compensation challenging if youâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />re thinking of getting out. From a skill set perspective, usually only start-ups need someone of that caliber, and unless they have known backers, itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s hard for them to afford you unless they offer some serious equity.</p>
<p><strong>Conclusions</strong></p>
<p>Consulting is a profitable endeavor, usually involving your skills on larger projects for larger companies. You can work with various teams or simply offer your expertise, perhaps via training. Itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s a great opportunity to learn, meet new people, and discover the business of software and the development processes various companies use. The money canâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t be beat, either. The easiest way to get in is to find an existing firm such as <a href="http://www.universalmind.com/">Universal Mind</a> or <a href="http://www.deloitte.com/">Deloitte</a> and get hired.</p>
<p>The skills required are more demanding that normal freelance software development. Specifically, knowing how to architect extremely large applications, having good leadership skills, and the ability to communicate complex subjects succinctly are key. These skills can be learned and practiced.</p>
<p>Consulting is a demanding career choice and itâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />s ok to take a break from it. Being an expert in your field requires you to be constantly researching, learning, and being on top of your game.</p>
<p>Keep in mind, too, you can work for a consulting firm and â€œjust codeâ€. This isnâ€<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" />t consulting, though.</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2011/05/consulting-chronicles-5-getting-in-and-out-of-the-industry.html/feed</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>Consulting Chronicles #4: Qualifying Leads</title>
		<link>https://jessewarden.com/2010/07/consulting-chronicles-4-qualifying-leads.html</link>
					<comments>https://jessewarden.com/2010/07/consulting-chronicles-4-qualifying-leads.html#comments</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Tue, 20 Jul 2010 19:57:58 +0000</pubDate>
				<category><![CDATA[Consulting Chronicles]]></category>
		<category><![CDATA[consultingchronicles]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=2346</guid>

					<description><![CDATA[Rather than make the typical lateral developer move to learning a new language, runtime, or IDE, I&#8217;m instead trying to bring in more business. What I want to talk about today are my challenges in doing so regarding qualifying leads. Introduction Early in the year, I knew I was done with freelance, and working with [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Rather than make the typical lateral developer move to learning a new language, runtime, or IDE, I&#8217;m instead trying to bring in more business.  What I want to talk about today are my challenges in doing so regarding qualifying leads.</p>
<p><strong>Introduction</strong></p>
<p>Early in the year, I knew I was done with freelance, and working with other consulting firms.  Freelance doesn&#8217;t make enough money, and working with other firms prevents you both from doing what you want to do, as well as making more money.  I could either build my own firm, which required a ton of branding &amp; marketing work, or just join an existing one.  There are pro&#8217;s and con&#8217;s to each and after weighing the options for about a year, I just joined <a href="http://webappsolution.com">Web App Solution</a> as a partner for a year to see how it went.</p>
<p><span id="more-2346"></span>I figured, even without doing a marketing push on my blog, Twitter, and speaking engagements, it was a shoe in to more, larger engagements.  My assumptions were WASI already had an existing client base I could tap into, having 3 additional Flex + Blaze/LiveCycle developers associated with me exponentially increased my value to clients, and I could leverage my existing brand to enhance both.</p>
<p>It hasn&#8217;t worked out like that at all.  The recession from the fall of 2008 is still in full effect.  Back in 2006/2007, I&#8217;d have 4 clients I&#8217;d court, and then pick 1.  Getting them to sign a SoW was cake; I wanted them, they wanted me; it was just the formalities on getting a number we could both agree on.  Last year, and this year, I&#8217;ve lost count of how many clients I&#8217;m courting.  It&#8217;s gotta be in the realm of at least 20 who are worth pursuing, and tons more who aren&#8217;t, yet may pay some money in between the larger engagements.  That, and my expectations for engagements are higher.  As a company, we have a lot of value from a resources, tax benefits, and experience perspective.  We can charge more for that value.</p>
<p>Additionally, the type of clientele I target are very different from the clientele I targeted when I was freelance.  To summarize, I used to target Flash engagements that lasted 6 weeks or less (often just 2 days).  When I got into consulting, the firms I used to work for would usually target engagements, often Flex, that lasted 2 months, 6 months, to 18 months.  The 2 month gigs often cost more for the client, but didn&#8217;t have a lot of consultants on-site, and thus weren&#8217;t very profitable.  The 6 month gigs were either small engagements to help a mid-size company get started a project, or more often to save their failing project.  The 18 month gigs were often larger enterprises who wanted to create some B2B product, and needed a partner to do so.  Meaning, they didn&#8217;t the in-house development resources, and thus hired the firm.</p>
<p>My firm targets the same types of 6 and 18 month gigs.  To get those kinds of gigs, however, is really hard.  Companies are sitting on $2 trillion dollars in the USA, and a lot of the banks have $1 trillion to lend; all aren&#8217;t spending/lending it to grow their business because our Congress is trying to pass some new bill to replace the failed Sarbanes/Oxley.  The 250+ new rules has them scared, and thus they are holding back doing anything until I they know what our crazy blue gov&#8217;t plans to do.  The 2000 page document that no one in the Senate has read, has 150 page summaries being sent out to various companies by their lawyers.  Yes, I&#8217;m aware that &#8220;summary&#8221; is the incorrect adjective to utilize for &#8220;150 pages&#8221;, but it is what it is.  Also, given my blog word count, I&#8217;m aware I&#8217;m not at liberty to judge (too harshly anyway).</p>
<p>Thus, I&#8217;ve had to work extra hard to ensure the leads (potential customers) I&#8217;m dealing with actually have money and can afford my company&#8217;s services.  Once that&#8217;s complete, I have to barrage them with questions to ensure I understand what they need, and my company is in fact what they need.  Third, I then have to draft some documents, usually a proposal, to ensure I&#8217;ve documented and shown I have a more than adequate understanding of what their company needs my company to build/fix/help them with.  Fourth, this needs to be formalized into an SoW that ensures we&#8217;re protected, the client is protected, clearly states what the client will get, and ensures we get fairly compensated for what we&#8217;re doing.  Fifth, we need to close the deal.  I don&#8217;t want to do any of that, however, unless I&#8217;ve ensured the potential customer has any potential, and thus is worth spending time on.</p>
<p>I really really really suck at those things, hence this blog post explaining what I&#8217;ve learned and what I think I don&#8217;t know, as well as what others have advised I do.</p>
<p><strong>Qualifying Leads</strong></p>
<p>Qualifying leads means ensuring that those who contact you have money, have valid work, and they are worth talking to.  Just because someone who emails you for a Flash job has no money, and no valid work doesn&#8217;t mean they aren&#8217;t worth talking to.  I&#8217;ve learned a lot about our industry just talking to clients, getting to know them, learning about what they are working on, their perceived challenges, and who they know.  These are valuable networking contacts, and sometimes gateways to future work.</p>
<p>That&#8217;s the exception to the rule, though.  Your gut can quickly tell you if someone over email/the phone is a client you want.  While there are a lot of exploratory things you can look for, I only want to know 3 things before I spend any time investing more time than a quick phone call/email reply:</p>
<ol>
<li>How long is the project?</li>
<li>Do you have money to fund the project to completion?</li>
<li>Am I and/or my company a good fit for the project?</li>
</ol>
<p><strong>Project Length vs. Sales Cycle</strong></p>
<p>In the past years of doing freelance and consulting, I&#8217;ve found you can spend a TON of time on qualifying leads if you&#8217;re not careful.  While sometimes this leads to good networking contacts, as well as helping your fellow contractors/freelancers pay it forward by referring clients to them if you&#8217;re busy, you also lose a lot money.  As a freelancer, the only way to make more money is to raise your prices or increase your hours.  Freelancers often don&#8217;t really have high overhead costs, so you can&#8217;t reduce overhead.  Thus, time spent talking to clients to get work is time NOT spent working on billable hours.</p>
<p>Incidentally, this is one of the reasons I specifically try not to do any Flash work anymore.  The length of those projects, 2 days to 6 weeks, is significantly less than Flex projects which last 2 months to 18 months.  Sometimes you actually spend the same amount of time talking to a client to get the ball rolling on the project which significantly cuts into your margins (aka, profit made working on the project minus how much time it took you to get the client to let you start working on the project).  If I&#8217;m going to spend 2 total weeks courting a client when it only leads to a month of work, that&#8217;s pretty costly.</p>
<p>What I&#8217;ve noticed is that a lot of Flash freelancers tend to have many clients going on at the same time.  The churn and frequency of clients is very high; this offsets their down time.  That, and Flash projects have high frequencies of intense activity, and then die off for days at a time, usually as the agency waits for a clients feedback.  This works to the Flash freelancer&#8217;s advantage to arrange their schedule to make multiple clients work.  Additionally, there are federal laws that ensure freelancers can set their own hours (although I&#8217;ve yet to meet a client who gives a shit).</p>
<p>Bottom line, you want the shortest sales cycle (time it takes to get the client to sign your contract, or you sign theirs, or both so you can actually start designing/coding) with the longest amount of work.  Any downtime between gigs is time you aren&#8217;t making money.  Charging $200 an hour doesn&#8217;t mean much if you only work 3 month out of the year because it&#8217;s so hard to find clients who are willing to pay that much.  For some people, that&#8217;s actually fine.</p>
<p><strong>Do They Have Money?</strong></p>
<p>If a client doesn&#8217;t have money, they are usually wasting your time.  There are rare cases where a client is actually putting feelers out; this could be a director at a medium to large company, or an Entrepreneur who is doing recon before he talks to his investors.  Additionally, it&#8217;s not as black as white as having money or not; some don&#8217;t have enough, and maybe you can work something out.  You need to have a clear idea of what you charge.  That topic is too large for this post, but I&#8217;ll let you know how I operate for context.</p>
<p>I believe in creating high quality software with a high quality team, and thus charge for that.  I don&#8217;t compete on price.  I don&#8217;t lower my price to score a deal because a client thinks I&#8217;m expensive.  I know what my competitors charge, and I know I&#8217;m one of the best, and thus price appropriately.  There is a major problem in our industry right now with Flex and Flash work sometimes bleeding into each other.  This includes a LOT of factors that muddy the waters, and require a lot of education, re-education, and clarification that you need to do with clients.  Some of it is subjective, too, because there are a TON of people who do compete on price right now in our recession, and can give the perception that your points aren&#8217;t valid.</p>
<blockquote><p>&#8220;I can go to Best Buy and buy a laptop for $300 right now&#8230; why the heck would I buy a $1,500 Mac?&#8221;</p></blockquote>
<p>You don&#8217;t see Porche lowering their quality and price just because we&#8217;re in a recession.  Neither do I.</p>
<p>Regardless, common problems include pricing Flex projects as Flash projects.  A lot of programmers have flocked to using Flex and Flash Builder.  While 5 years ago, most of us would of used Flash to build a Facebook widget, nowadays a lot will use the Flex SDK.  This causes 2 problems.  First, you often get high caliber programmers put on low caliber projects that do not utilize their full skill set.  Building an Enterprise RIA is most often done utilizing the Flex SDK by software developers.  A lot of smaller scale Flash work is now more often more easily done using the Flex SDK, but the price point for such work is still in the low caliber, &#8220;quick git-r-done&#8221; programmer range.  Additionally, the time estimations for such low caliber work are often geared towards a shorter shelf life with consumers often use the tools, not clients who have a feedback channel.  Thus, the deadlines, and thus quality of code, are significantly lower because they can be.  This leads to extremely short, non-moveable deadlines.</p>
<p>This goes counter to what most Flex Developers who build Enterprise RIA&#8217;s are used to; long deadlines, mostly negotiable because of Time &amp; Materials contracts, with good quality code.  There are a lot of up and coming Flash Developers who utilize Flex for some of these projects, and thus helps create additional confusion on why one person use the Flex SDK is $30 and hour, and another is $80; when they effectively &#8220;doing the same work&#8221;. *face palm*</p>
<p>If you are one of those Flash Developers, this is fine.  If your&#8217;e a Flex Developer, you often have to ensure the client even gets Flex.  Most real clients don&#8217;t care what technology you use.  However, Design Agencies service a completely different clientele than software shops/consulting firms do.  As such, you need to ensure the lead on the phone/over email is talking about a &#8220;true Flex project&#8221;.  Otherwise, they are doing a Flash project with Flex, and their rate expectations will reflect this.  This means they&#8217;ll often be WAY too low than what you were expecting even if they go on about &#8220;Flex consuming SOAP web services&#8221;.</p>
<p>Another common client I get is the eff&#8217;d one.  Their developer went AWOL, their team doesn&#8217;t know what they are doing and need mentoring, or they are slowly realizing they are getting screwed over by another company and need me to confirm it.  If they are a big company, they&#8217;ve actually often factored this into the budget, or can easily get these budgets approved very quick.  While it sucks that its&#8217; easier to get bling approved to cut your losses than it is to help increase your gains, my consulting career has confirmed this with a lot of large companies.  However, every so often I get a company who&#8217;s eff&#8217;d, or they might not even know they are eff&#8217;d, and do NOT have the budget to get themselves out of it.  Sometimes they do, but by hiring a $30/hr miracle worker.  Consulting in bad situations is bad enough, that&#8217;s why you charge for it.  Consulting in bad situations where they client cannot afford it are situations I don&#8217;t put myself in.  While it&#8217;s hard to get the true scope of death-incarnate over the phone, it&#8217;s pretty easy to get the client&#8217;s background and understand if they can fund the rescue operation or not.</p>
<p>Keywords for me include,  but are not limited to, the following:</p>
<ol>
<li>2 week project</li>
<li>coder is almost done, but pulled off on another project</li>
<li>we&#8217;re almost done, but this one feature is killing us, and we&#8217;re not sure how to do it (usually means someone who doesn&#8217;t know Flash Player capabilities sold their client on something that they couldn&#8217;t do, or couldn&#8217;t afford)</li>
<li>we&#8217;re an design agency</li>
<li>Flash widget</li>
<li>our game is having a few problems</li>
</ol>
<p>I could go on and on, but all of the above basically mean &#8220;we can&#8217;t afford your services&#8221;.  A 2 week project isn&#8217;t profitable unless I can ensure 20 of them come in exactly at 2 week intervals, and I don&#8217;t spend months trying to line them up this way.</p>
<p>If the coder is almost done, but was pulled off onto another project, it means the company is small, or doesn&#8217;t have the resources to tackle larger projects, thus they need you for staff augmentation.  I&#8217;ve seen a few rare instances where Flex projects have this happen, but pulling the main developer off of a 6 month Flex project isn&#8217;t smart at all, and there typically isn&#8217;t just 1 Flex developer.  Thus, it&#8217;s a Flash project, under a deadline, you&#8217;re left beholden to that developers&#8217; code, usually not using best practices because the company is more focused on getting it done, on time.  Software isn&#8217;t done &#8220;on time&#8221;; if you think it is, you&#8217;re not building software, you&#8217;re building some short shelf life Flash project for a client on a fixed budget.</p>
<p>The &#8220;this last feature we need a heavy hitter on&#8221; usually implies either something that shouldn&#8217;t have been sold to the client in the first place, or a wrong approach.  For the latter, sometimes you can often knock it out in a day, but 4 hours of back and forth with the client for 8 hours of work is extremely unprofitable.  This can get worse if you actually do a good job, and they start expecting you to fix their technical debt.  While more hours are nice, if you only budgeted a day for the project, it gets complicated to fit into your schedule.</p>
<p>&#8220;We&#8217;re a design agency&#8221; means they&#8217;re used to getting Flash contractors for $30 to $50 an hour, thus your software developer rates aren&#8217;t going to fly.  Worse, most companies/firms charge more for shorter gigs because you have to take resources off of other projects to help the client with their shorter, less flexible project.  This has a major cost, and thus you factor that into your price.  This, in turn, makes agencies often get a more incredulous look at your price.  Bottom line, they want a Flash freelancer, and I&#8217;m trying to provide them a resource from my company.  Wasn&#8217;t meant to be.</p>
<p>Flash widget.  I don&#8217;t know many Flex coders using Swiz, Continuous Integration, and attempting to master TDD in their SCRUM process who build Flash widgets.  Thus, you&#8217;re often left with a really small budget, that&#8217;s fixed, that&#8217;s already coded, on the timeline, and you&#8217;re beholden to that alien workflow.  Not going to work.</p>
<p>Our &#8220;game is having a few problems&#8221; is often the worse.  Games are actually some of the most challenging things to code.  In Enterprise architecture, you often have a long history of patterns and processes to cull from.  In games, you have to have good knowledge of algorithms, specific design patterns, and a good breadth of technical understanding of how the Flash Player works.  If a client is calling you to help them fix this, they should of called you in the first place.  I&#8217;ve lost 2 game gigs last year where they ended up calling me back to help them fix it; by then I was deep into a gig, and cursed myself for my lack of sales ability.  I don&#8217;t like when clients get bit by the obvious, getting what they pay for, but I also don&#8217;t like when I would of saved them, but am not given the opportunity to do so.  Gaming architecture is often more tightly coupled for performance reasons, and thus is way harder to fix.  Combined by the fact most games are done in agencies on fixed budgets with fixed deadlines, it&#8217;s just a lose lose situation.</p>
<p>As you can see, making sure leads aren&#8217;t looking for a Flash freelancer is hard.  Once Flex seeped its way into smaller Flash projects, it made the perception even worse.  A larger majority of the &#8220;gigs&#8221; I&#8217;m filtering out are those above.  I&#8217;m looking more for &#8220;engagements&#8221;; longer term Flex projects that are for building software for companies.</p>
<p><strong>Is My Company A Good Fit?</strong></p>
<p>The last filter for leads is confirming my company is a good fit.  While a client may have settled on Flash, oftentimes I can teach them about Flex and we go the right route.  However, if they have their heart set on a custom PHP/Python back-end, it&#8217;s more difficult to sell my companies services.  My dad would say, &#8220;If they ask if you can do PHP, you answer that yes, you can do PHP&#8221;.  I know PHP, and I&#8217;m sure my fellow partners do too, but we specialize in Java.  That&#8217;s not just a preference, but Java tends to exist in the real of larger Enterprises.  There are some, yes, that do PHP&#8230; but the clients who provide the longer term Flex gigs use Java.  Back in the day, you didn&#8217;t invest in Sun servers because they were 10 times what a LAMP stack costs because you were dumb; it&#8217;s because it was WAYYYY easier to get Sun/Java consultants than LAMP consultants.  If you&#8217;ve invested half a million of your company&#8217;s money into a project, and no one can help you fix it when it breaks, you&#8217;re screwed.  Thus, double the budget, and ensure it&#8217;s a well known tech that you can hire consultants on in case things go south.</p>
<p>Thus, usually by mentioning something other than Java for the back-end, that&#8217;s usually my first indication we won&#8217;t end up working together.  While both PHP and Java have a lot in common in the open source world, if they&#8217;ve invested in a LAMP stack, they are doing so for cost reasons (most anyway).  Most large companies I&#8217;ve worked with do not care at ALL about cost; they care about making money.  If their costs are high, they focus harder on making more money to cover those costs.  I&#8217;ve seen a lot of good businesses run on LAMP, but they often aren&#8217;t the ones financing long term Flex projects.  Thus, middle-tier technology choice is often my first clue.</p>
<p>Another is vibe.  Does the client sound like someone I&#8217;d want to work with?  In freelancing, you can be way more forgiving.  If the client yells at the designer in front of you and makes her cry, you can usually hold your tongue, knowing you won&#8217;t have to work for that mean person anymore who doesn&#8217;t respect women in 2 weeks because you&#8217;ll be done.  For Flex projects that tend to last months, even a year; you&#8217;re basically entering a long term relationship.  You really need to ensure you both have the same set, or at least mostly common, beliefs.  If the client is more interested in getting it done than doing it right, I actually respect this because they believe in making money.  Clearly they respect the craft because they are still talking to someone like me who believes in finding that middle ground.  Now, keep in mind Jesse Warden is focused on quality first, money second.  Others are focused on money first, quality second.  It seems trivial, but when this forms the basis of your belief structure, you can get widely different responses on what client is worth forming a relationship with.</p>
<p>For example, if I can tell it&#8217;s going to be a staff augmentation job where you&#8217;re placed inside a huge company who doesn&#8217;t mind if you produce nothing of value for 9 months, most rational company owners would definitely move forward, and ensure more developers could be put on the project.  Once you take your cut, you ensure a significant amount of revenue flows your way, AND the risks are low; win win.</p>
<p>Not for me. I don&#8217;t want to spend 18 months of my life producing no value for my clients.  I didn&#8217;t invest 10 years of my life, 18 hours a day, every day honing my craft only to waste it warming a chair, judging the previous vendor&#8217;s code base and doing nothing to change it.</p>
<p>That said, I&#8217;ve had to lower my idealistic expectations a bit.  A lot of large companies who fund the engagements I want to be on often DO want me to produce value for them, they just don&#8217;t know how, and it&#8217;s just REALLY hard to get message across over a phone call.  That, and some of these larger companies don&#8217;t run as a dictatorship, and it&#8217;s harder to get things done in a democracy.</p>
<p>My dad the salesmen says, &#8220;You need to ask them questions.&#8221;  I&#8217;ve taken this a step further and asked them the same questions twice.  This can give me insight into their true motives.  Some clients really want you to come there, make bling, and help them create awesome software.  Others want me to work for free, or at least do the discovery phase for free.  The challenge I have is discerning between what the client needs to be educated about, and what they truly believe, and where we can meet in the middle to form a working relationship.</p>
<p>I&#8217;m still not sure what&#8217;s a good fit, but so far my criteria of ensuring they having money, paying for the discovery phase, and signing Time &amp; Materials contracts is good enough so far; weeds out 90% of the non-valid ones.</p>
<p><strong>Conclusions</strong></p>
<p>I&#8217;ve got the initial pitch down.  I listen, and ask a ton of questions.</p>
<p>The guys I work with are better at the above than I am.  They are, slowly, working with me to better understand who I should focus on, how, and how their SoW formulation process works (because mine clearly doesn&#8217;t scale to the Enterprise).</p>
<p>However, because of my personal brand and my vast network, I have an easier time of getting a plethora of leads.  Sometimes a hand off isn&#8217;t practical, and I need to feel them out directly.  Sending a bunch of $30/hr, 2 week, Flash gigs to my partners is just a waste of time.  I end up doing a lot of legwork talking to clients, feeling them out, and qualifying them as potential customers.  I&#8217;ve still got a lot to learn, and feel like a budding AS1 developer.</p>
<p>Another thing that&#8217;s extremely frustrating is that my personal brand right now does NOT reflect the clientele I want at all.  The honest, edgy, and high strung Jesse Warden is not what Enterprise clients are used to.  I&#8217;d argue that&#8217;s what you need to get anything done there.  Once I&#8217;m in these companies I can work my magic.  The problem is, I&#8217;m seen as the medicine they don&#8217;t want to take.  I&#8217;ve had 2 different salesman from a former consulting exclaim how they&#8217;d love to have me on a project, but they don&#8217;t see how I&#8217;d fit.  They&#8217;ve never seen me on-site with a client, in business attire, having a calm meeting with them working through their issues.  What they see is me at conferences rousing with my fellows in the industry, speaking at conferences being &#8220;me&#8221;, and giving honest accounts of how I do things.</p>
<p>That works great in the freelance game, and even in the consulting firm game, but not in the &#8220;I&#8217;m my own company&#8221; game.  Leads keep coming to &#8220;jessewarden.com&#8221; and contacting me as Jesse Warden vs. webappsolution.com and contacting me as WASI.  We&#8217;re in a huge rebranding effort right now which I believe will help.  Still, it&#8217;s effing frustrating.</p>
<p>Tom Link from Universal Mind once told me:</p>
<blockquote><p>&#8220;You don&#8217;t hire Schematic to get Schematic; you hire Schematic to get Danny Patterson.  Just because you hired Schematic doesn&#8217;t mean you get Danny Patterson&#8221;.</p></blockquote>
<p>I&#8217;m not sure if it was Danny Patterson or not, but that&#8217;s not the point; the point is, I know I&#8217;m sitting on a gold mine with my brand, but I&#8217;m not sure how to leverage it to make more bling.  Many people have been very forthcoming with advice, but none of it seems to work, or I&#8217;m just doing it wrong.  Many businessman who already make money in Flash/Flex without coding in Flash/Flex, and getting others to code for them, have told me I could be infinitely more rich than they were if I just leveraged my name to bring in business.  I&#8217;m not ready to do a marketing blitz on WASI just yet; we&#8217;re not ready, but I&#8217;m not sure what it would do if I did?</p>
<p>At this point, I&#8217;d argue that I could only do that doing Agency work because right now, all the Flex clients are either in Manhatttan&#8217;s financial sector, or through the magical, and elusive Adobe Professional Services gateway.  If I want those types of clients, I&#8217;ll have to start watching my mouth, redesign the format of my blog, and start playing the game differently; &#8220;clean up my act&#8221; as it were.  I&#8217;m not yet convinced I need to do that.</p>
<p>However, I&#8217;m a little frustrated I&#8217;ve spent years curating (buzzword bingo, WIN!) my personal brand only to have it cap out at some dollar amount.  Eff that.  I recognize if I want to make bling, I&#8217;ll eventually have to stop coding, and get others to code for me. Fine&#8230; but right now, I can&#8217;t seem to score the bigger clients.  I know we&#8217;re in a recession, and even if the big clients have money, they won&#8217;t spend it.  Those who typically just get a loan now, can&#8217;t.  I get it, I really do; I recognize I need to use context in understanding the current economic climate and it&#8217;s affect on rates, and frequency of work.  Our client sales cycles have tripled in the last 2 years because of it.  Clients still are signing, it&#8217;s just taking longer.</p>
<p>That said, people still buy Porches during the recession.  I just want to know how to get them and stop wasting my time with these damn recruiters that never give me anything of value, nor these small potatoes Flash gigs.  My dad gets mad when I ask him advice for this, and threatens to start working for me.  I don&#8217;t work with family.  However, at this point, I&#8217;m uber close to start focusing 50% of my attention on hiring a salesman, because this is ridiculous. Maybe it isn&#8217;t ridiculous, and it&#8217;ll soon be great, it just sucks now cause I suck at it.  People on Twitter have suggested I&#8217;m great at scoring the lead + the initial conversations, I just need to hire a <a href="http://www.youtube.com/watch?v=y-AXTx4PcKI">closer</a>.  :: shrugs ::</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2010/07/consulting-chronicles-4-qualifying-leads.html/feed</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title>Consulting Chronicles #3: Preventing Fire Drills &#038; Crises by Removing Land-mines and Using Diagnostic Tools</title>
		<link>https://jessewarden.com/2010/02/consulting-chronicles-3-preventing-fire-drills-crises-by-removing-land-mines-and-using-diagnostic-tools.html</link>
					<comments>https://jessewarden.com/2010/02/consulting-chronicles-3-preventing-fire-drills-crises-by-removing-land-mines-and-using-diagnostic-tools.html#comments</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Wed, 17 Feb 2010 14:54:26 +0000</pubDate>
				<category><![CDATA[Consulting Chronicles]]></category>
		<category><![CDATA[consultingchronicles]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=1979</guid>

					<description><![CDATA[Preface When brought into existing projects in a consulting role, there will often be the perception the project is &#8220;mostly done&#8221;, or &#8220;90% there&#8221;. Â Opening up the hood, you sigh. Â You marvel at the wonders of modern programming technology, how they&#8217;ve empowered even the shoddiest, hastily thrown together, duct taped to work and work well, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Preface</strong></p>
<p>When brought into existing projects in a consulting role, there will often be the perception the project is &#8220;mostly done&#8221;, or &#8220;90% there&#8221;. Â Opening up the hood, you sigh. Â You marvel at the wonders of modern programming technology, how they&#8217;ve empowered even the shoddiest, hastily thrown together, duct taped to work and work well, fooling many into a sense of functional complacency. Â You also wonder when, not if, it&#8217;ll explode in someone&#8217;s face.</p>
<p><span id="more-1979"></span>A lot of short lived software written for conferences and trade shows can get away with this. Â It just needs to work long enough to work once or twice. Â After that, who cares. Â In longer term products &amp; services for companies, most software follows the traditional rule of living 3 times longer than it&#8217;s intended life span. Â In consulting, you&#8217;re brought on to finish it, fix it, and prep her for long term maintenance, hell, maybe even adding additional features to it.</p>
<p>Sometimes you and your team can inadvertently become a victim of their own success. Â Once you&#8217;ve wrangled the problem areas of the code into a stable state, earned trust with your client, things start to settle down. Â At this point in the project, the code really does work as advertised, or you&#8217;ve merely stopped all the noticeable and constant explosions. Â The land-mines, or unexpected breakages haven&#8217;t occurred in awhile to remind people, in a sad way, you still have a lot more work to do.</p>
<p><strong>Introduction</strong></p>
<p>This post assumes you&#8217;re a consultant brought in to fix and help release an existing code base. Â The client needs to release, and you didn&#8217;t write the original code base, yet now are responsible for it&#8217;s architecture &amp; direction. Â The perception is, either because of your efforts or merely because there haven&#8217;t been any explosions lately, the code works just fine and just needs maintenance to get them to launch. Â Then, something horrible happens. Â The code doesn&#8217;t work, and NO ONE knows why. Â Suddenly mass insecurity sets in since the reality people thought they knew doesn&#8217;t exist anymore.</p>
<p>As an architect who didn&#8217;t architect the code, you may not be able to immediately remove that insecurity, but you CAN use it to your advantage. Â This post will show you how via defining what fire drills, crises, and land-mines in code are. Â It&#8217;ll also show you how to prevent them by using diagnostic tools, some of which you&#8217;ll have to write. Â A lot of these can proactively Â  Doing this will better equip you to prevent the code from not working suddenly, identify with confidence WHY it&#8217;s not working, and help build the team&#8217;s trust in your word.</p>
<p><strong>What are Fire Drills and Crises?</strong></p>
<p>A Fire Drill is a slang phrase used in corporate culture. Â It&#8217;s used to refer to situations where a manager/leader has a perceived importance of something that really isn&#8217;t, and demands an individual or team work on it. Â This work that comes up suddenly is chaotic, and in the end often accomplishes nothing. Â In terms of software, this often happens when a feature suddenly needs to be implemented in an extremely short time frame. Â This bypasses the traditional processes used by the team (Waterfall/Scrum), causing much commotion, and often damaging the code base short term and long term. Â The more common ones, though, are when un-announced demo&#8217;s are given by high level executives, a key feature doesn&#8217;t work, and suddenly something the team had been working 6 weeks on to get done now must be done in 1 day. Â Complete bullshit, I know, but it happens all the time.</p>
<p>Crises are very similar, although, valid. Â In a fire drill, the executives may not know that a newer production build fixes the key feature they wanted to demo, and a miscommunication just happened. Â In a crisis, everyone, including the developers, is under the delusion the feature actually works, and in a key demo, it does not. Â THAT&#8217;s a crisis. Â Fire drills, while perceived as important, aren&#8217;t. Â Crisis ARE important. Â Your code doesn&#8217;t work&#8230; or worse, your code doesn&#8217;t work, it&#8217;s live on production, and customers are flooding your call center.</p>
<p>Both can cause harm to the code, team morale, and trust in you as a consultant.</p>
<p><strong>Preventing Fire Drills &amp; Crises</strong></p>
<p>A lot of fire drills can be prevented by good communication. Â As a developer, you&#8217;re primary job is to kick some ass writing code, not give directors and executives transparency into the project; that&#8217;s the Project Manager&#8217;s job. Â As a consultant/architect, however, there is a LOT you can do to help empower the managers, PM&#8217;s, and testers with insight into the application, and good information on what&#8217;s happening.</p>
<p>If a PM knows what&#8217;s wrong with the application, they can confidently assuage the fears of those wondering why things are broke. Â The more information they have, the easier it is to articulate the problem. Â Sometimes it&#8217;s a reoccurring problem. Â The confidence, and perhaps slight indifference. in their voice when communicating to those above arising from this commonality will go far in ensuring people in charge don&#8217;t freak out.</p>
<p>Sometimes, a PM or tester will know before YOU do. Â This proactive action in both known, and new unknown problems, allows you to not only prevent higher ups from seeing problems before they happen, but also allow you to leverage the entire team in debugging your application. Â It&#8217;s one thing to have a developer and a PM duplicate a problem; it&#8217;s another when you have 5 people all getting the same results, with logs to confidently prove it.</p>
<p>During a crisis, a lot of fear is because of the unknown surrounding the situation. Â Why is this happening? Â Who&#8217;s responsible? Â Is it my fault, the back-end, or our 3rd party data provider? Â The worst thing anyone can do in a crisis is panic. Â You need to be calm, collected, and strategize how to diagnose the problem to inform those in charge, and then allow yourself time to actually attempt to fix the problem.</p>
<p>That&#8217;s easier said then done when the suits have a gun to you and your PM&#8217;s head&#8230; and perhaps you even LIKE your PM. Â Maybe you feel like the performance of the application is directly tied to team member&#8217;s perception of your ability, and helping them determine whether they like you or not? Â Perhaps you&#8217;re right? ZOMG!!!</p>
<p>Your application needs to talk. Â Your application needs to report what is going on with the various aspects of itself. Â It needs to tell the truth, or the truth of what it thinks it knows. Â You need to have external tools at your disposal to corroborate the application&#8217;s built in reporting and diagnostic tools. Â These can be off the shelf, open source, and ones you&#8217;ve built yourself specifically tailored to the application at hand. Â These need to be quickly &amp; easily accessible, and require little to no maintenance. Â They need to be relatively easy to use and understanding by not just developers. Â Reports generated need to be easily portable text.</p>
<p>These reports and tools allow proactive action against problems, help empower management with good information, and help prevent fire drills and reduce the severity of crisis situations, often preventing them.</p>
<p><strong>Reporting &amp; Logging</strong></p>
<p>How do you get this information? Â You&#8217;re application needs to talk to not just you, but anyone who asks. Â It needs to have a semblance of an agreed upon vocabulary. Â It needs to generate fine grained reports about volatile areas.</p>
<p>How do you get it to do that?</p>
<p>Logging. Â Logging is another way to say &#8220;trace&#8221; in Flash or Flex. Â It&#8217;s a lot more than just tracing out simple messages, though. Â You need a formalized way to send them as well as allow them to be readable when you have thousands of lines of messages. Â Here is some criteria of a helpful logging strategy:</p>
<ol>
<li>Shouldn&#8217;t require any fragile or complicated configuration to get it working</li>
<li>should fall back to Flash Player&#8217;s trace command so it works with the traditional Flash &amp; mxmlc debug players</li>
<li>should have special GUI created around the log messages to display, filter, and allow extraction</li>
<li>the GUI should be in the application itself. Â This allows anyone to access it easily. Â For widgets and small screens, if you&#8217;re showing a GUI, you clearly have enough room to show log messages.</li>
<li>the GUI should be able to be opened &amp; closed easily from within the application. Â Right click is usually the most unobtrusive, and easily removed for production code. Â Closing should not remove the log messages from memory, nor affect the logs in any adverse way.</li>
<li>The log messages should be able to be easily extracted, copied, and pasted.</li>
<li>The log messages should have built in, cross platform formatting to make them readable when pasted into email, text messages, and text files.</li>
<li>You should be able to scroll through older messages without being interrupted by the logger.</li>
<li>The log window should not adversely affect the application (in Flex 1, override Object.toString() is what some debuggers did, and this broke Flex&#8217; String formatters and validators&#8230; but ONLY when the log window was running).</li>
<li>Bonus points: per developer filtering, easy to turn on/off, color coded messages, and works in multiple compilers/IDE&#8217;s.</li>
</ol>
<p>Wow&#8230; more than just a simple trace in the Output window, ya? Â Why all the guidelines? Â Let&#8217;s break it down.</p>
<p><strong>Stay on Target&#8230;</strong></p>
<p>During a crisis, stress levels are high. Â You want to make it as simple as possible to quickly get logs from your application. Â This shouldn&#8217;t have to make you think or concentrate hard on getting it to work; it should just work. Â In the case it DOES screw up, or another developer doesn&#8217;t have/refuses to have your custom setup, as long as all of your special trace commands still output a trace command, you can utilize the existing debuggers in Flex/Flash.</p>
<p><strong>When Things Breaks, Look Here for Answers</strong></p>
<p>The special GUI is important. Â This clearly delineates where log messages go, how you interact with them, and is the gateway for non-developers into the app when something goes wrong. Â They will turn to this window when something breaks or doesn&#8217;t work correctly. Â This is the information they will be combing through for insight into why something broke. Â Sometimes this information is so helpful, it&#8217;s self-correcting, and you&#8217;ll never hear about their problems. Â Examples include clearly stating you don&#8217;t have a session, and thus the user needs to log back in. Â If you haven&#8217;t captured all session errors in your application&#8217;s Service layer yet, the PM/tester can re-login and try again. Â This, as opposed to the 3 email conversation, or the 1 minute phone call all to &#8220;just re-login dude&#8230;. you&#8217;re session is probably expired&#8221;. Â Doesn&#8217;t interrupt your focus, and ensures when problems do arise, those working with you know where to look.</p>
<p><strong>Filter Out the Noise</strong></p>
<p>As your application grows, both in size of code and developers, so to will the frequency of messages. Â Sometimes all of those messages are an important indication &amp; insight into the health of your application. Â Thus, you need an easy way to filter out the good ones from the bad ones. Â This is where a simple trace won&#8217;t do. Â You cannot differentiate once trace from another easily since it&#8217;s just text. Â No, using RegEx and clever time stamps doesn&#8217;t count. Â You need to create messages, a Value Object class that represents the message, the time it occurred, who sent it, where it came from, what it&#8217;s saying, and it&#8217;s type&#8230; at a minimum. Â You can go overboard here if you want, but just be aware of the old adage, more code == more problems. Â You want to make sure you&#8217;re only adding what you need, you don&#8217;t make the logging API a pain to use for the developers, and you don&#8217;t have to debug your logger for more than a day to ensure it&#8217;s not lying to you, or broken.</p>
<p>Filters can include differentiating between logs, warnings, and explosions&#8230; also known as errors. Â This allows anyone to see the entire state of the app, or just the problems, known and unknown. Â As multiple developers get on the project, you&#8217;ll sometimes get log messages you didn&#8217;t know about; this can sometimes make it easier or harder for you to debug your own issues. Â These should be filterable as well, whether at compile time or runtime. Â This, too, should be easy to configure.</p>
<p><strong>Portability &amp; Ease of Use</strong></p>
<p>Many debug windows in the Flash community are external. Â There are a few advantages of this, namely it makes it easy to debug applications running in a browser. Â You&#8217;re application isn&#8217;t affected, nor necessarily tied to the browser&#8217;s state. Â Other times, it&#8217;s completely separate from your code base, making integration cleaner. Â Finally, it&#8217;s easy to debug multiple applications using the same debug window.</p>
<p>I&#8217;ve found, though, in consulting &amp; contracting over the years, these never work with PM&#8217;s and testers as well as custom, home grown, in-application ones do. Â Installing and confirming things like Thunderbolt or DeMonsterDebugger work are challenging endeavors unto themselves requiring 3 technologies. Â This vs. &#8220;just run the app&#8221;. Â The last thing you need Firefox to wig out on you during a production push, it does, and suddenly you have zero insight into why your application isn&#8217;t working on your staging server&#8230; and people are freaking out because you&#8217;ll miss your production push.</p>
<p>The other nice thing is no matter where your application runs, so to will your logger run. Â This includes on your local box, your local web server, your QA server, and even production if you&#8217;re your so inclined&#8230; no configuration needed. Â Nothing like adding confidence to your code base.</p>
<p>This also means ANYONE using the application, from testers to PM&#8217;s to suits and bobs in a board meeting; if something goes wrong, you can quickly diagnose what it is without needing the Flash Debug Player installed.</p>
<p><strong>Copy Pasta</strong></p>
<p>Adding just a simple &#8220;Add to Clipboard&#8221; button goes a long way to making it easier for others to get errors to you when problems occur. Â If you&#8217;ve ever tried to copy and paste in Flash with it&#8217;s awesome focus-fun, you know what I&#8217;m talking about.</p>
<p><strong>Moveable &amp; Capable of Being Closed or Hidden</strong></p>
<p><a href="http://jessewarden.com/wp-content/uploads/2010/02/logwindow.png"><img decoding="async" class="alignleft size-medium wp-image-1987" style="margin: 4px;" title="logwindow" src="http://jessewarden.com/wp-content/uploads/2010/02/logwindow-300x230.png" alt="" width="300" height="230" /></a>The log window needs to be moveable and capable of being hidden. Â Some applications have buttons in certain places and you don&#8217;t want the log window to get in the way. Â A lot of times it&#8217;s just easier to close/hide it. Â Whether you visible false it, or just removeChild, whatever works. Â This should NOT affect the log messages. Â You should still be able to get log messages. Â This means that the logger class usually has no GUI, and the log window has knowledge of how to display those messages. Â That way, you can kill the GUI, and the messages are still being retained. Â More importantly, before Flash/Flex has even started, in the case of static initializer methods (which even the Flash IDE can&#8217;t debug), you can still get log information about them.</p>
<p>This should be easy to do. Â Usually making it &#8220;look&#8221; like a window is enough for most people to try to drag it. Â Using useHandCursor and buttonMode to true on the top part will show the pointy hand. Â Although the wrong gesture, it&#8217;s better than the cursor b/c it gives a hint the user can &#8220;do something with this part&#8221;.</p>
<p>In Flex, it&#8217;s easiest to just use PopUpManager. Â This puts your logger on top of everything, and if you kill it, you don&#8217;t affect other View&#8217;s. Â Bonus points if she remembers where you dragged it when it opens back up (hint: local SharedObject).</p>
<p><a name="logmessageformatting"></a><strong>Log Message Formatting</strong></p>
<p>Log messaging formatting is very much opinion. Â Thus, using standard formatting options such as newline (&#8220;\n&#8221;) and tab (&#8220;\t&#8221;) will ensure whatever your team decides on, it&#8217;ll work no matter where it&#8217;s copy pasta&#8217;d from. Â One convention I use to prevent needing strange metadata in your code is the following:</p>
<ul>
<li>have log, debug, info, warn, error, and fatal messages</li>
<li>color code them in the GUI with filters</li>
<li>all log messages start with &#8220;ClassName::methodName&#8221; where ClassName is the name of the class you are in, and methodName is the current method the log message is in. Â It seems a major pain at first, but I guarantee you when you start removing them 2 months later, you know EXACTLY where to find it vs. that one trace that stays there for weeks because no one found where the bastard is. Â It&#8217;s not that they couldn&#8217;t do a search/grep for Debug.log(, but they&#8217;d find 500 of his friends&#8230; so not worth the effort.</li>
<li>I provide a header method for each type of message; logHeader, debugHeader, infoHeader, warnHeader, errorHeader, and fatalHeader. Â These are usually just &#8220;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8221; color coded. Â When you put multiple logs in a method, especially for/while loops, this helps visually break up the hundreds of lines of log messages. Â This also enforces consistency amongst the team when other members will just use their own like &#8220;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&#8221; and &#8220;**************&#8221;, and it becomes cool from an artistic ASCII perspective, but a pain from a debugging standpoint.</li>
</ul>
<p><a name="writinglogmessages"></a><strong>Writing Log Message Types</strong></p>
<p>You need helpful log messages that aren&#8217;t written in g33k talk. Â It&#8217;s not just you that will be reading them, but testers and PM&#8217;s from a variety of backgrounds. Â You also need to write clear enough that if a bug crops up 3 months later, you&#8217;ve written a message that clearly identifies the problem. Â Trust me, you&#8217;ll forget as you focus on other things. Â Even if you don&#8217;t, a confidently written message goes a long way in assuaging people&#8217;s fears that you know what is wrong, and got it covered. Â Here, I&#8217;ll cover the 6 message types, and where &amp; why you&#8217;d use them.</p>
<p><strong>LOG</strong></p>
<p>Logs are used for common stuff that is integral the app, and always runs every time you run the application. Â This includes loading external service definitions, logging into the application, and other integral data your application needs to get from an external place before it runs. Â Logs should get cliche over time in larger applications; you should only start worrying when you don&#8217;t see them, and instead see errors. Â This, also, is a great indication that something totally wrong&#8230; is wrong.</p>
<p>Logs are checklist items to ensure your application is in working condition, or to confirm an action did in fact happen successfully.</p>
<p>Debug.log(&#8220;ServiceLoader::onComplete, we&#8217;ve successfully loaded our services.xml, and we&#8217;re ready to rock this mic!&#8221;);</p>
<p><strong>DEBUG</strong></p>
<p>Debug messages are your primary source of insight into new code. Â These are messages you&#8217;ll put into new code to ensure it works&#8230; or into old code that&#8217;s acting up. Â If you use Test Driven Developement and/or unit tests, these messages are used in tandem to be iron-clad sure that the things you think are happening are actually happening.</p>
<p>Debug.debugHeader();<br />
Debug.debug(&#8220;Alright&#8230; my method is actually running&#8230; amazing, I&#8217;m not fired.&#8221;);</p>
<p><strong>INFO</strong></p>
<p>Info messages are used in strange, insecure situations. Â When something happens you won&#8217;t to know about, but doesn&#8217;t adversely affect the application, you use an info message. Â They can also be used in tandem with debug messages. Â If you have a lot of debug messages, it&#8217;s sometimes hard to filter them alone, so you throw an info message into the middle to confirm/deny what you were testing/debugging.</p>
<p>Debug.info(&#8220;Dude, I didn&#8217;t get a security error this time!&#8221;);</p>
<p><strong>WARN</strong></p>
<p>Warning messages are used to report errors that don&#8217;t negatively affect the continued operation of your application. Â These include security errors when loading images, failure to save a file, or when a web service goes awol. Â These can lead to, or hint at, bigger problems but sometimes occur so often they don&#8217;t hurt anyone, you and your team just need to be aware they happened.</p>
<p>Debug.warn(&#8220;LoginService::onResult, succeeded logging in, but I&#8217;m getting yelled at to change my password, and we don&#8217;t have the popup wired in here yet.&#8221;);</p>
<p><strong>ERROR</strong></p>
<p>Error&#8217;s are usually a blanket message for all errors. Â These include synchronous, asynchronous, and custom problems that arise. Â You&#8217;ll often log these within try/catch blocks, asynchronous error event handlers, or when your code is expecting something to be true, and it&#8217;s not, and you&#8217;re screwed because it&#8217;s not. Â Sometimes you&#8217;ll just use a warning instead because you don&#8217;t care right now, or it&#8217;s not your fault, or you just can&#8217;t do anything about it. Â Errors usually imply something needs to be, and can be, fixed.</p>
<p>Examples:</p>
<p><code> </code></p>
<p><code> </code></p>
<p><code> </code></p>
<p><code> </code></p>
<p><code></p>
<pre><span class="keyword">try</span>
{
        fileStream.writeObject(obj);
}
<span class="keyword">catch</span>(ioError:<span class="identifier">Error</span>)
{
        Debug.error(<span class="string">"FileSaver::onSave, Couldn't save the file, ioError: "</span> + ioError);
}

<span class="keyword">function</span> onIOError(<span class="identifier2">event</span>:IOErrorEvent):<span class="keyword">void</span>
{
        Debug.error(<span class="string">"FileSaver::onSave, Couldn't save the file, ioError: "</span> + ioError);
}</pre>
<p></code></p>
<p><strong>FATAL</strong></p>
<p>You shouldn&#8217;t have to ever use these. Â You&#8217;ll find that WARN and ERROR messages on their own cause concern amongst the non-developers on your team. Â Even messages written with a concerned tone using LOG/DEBUG/INFO can arouse suspicion, and fill your inbox unnecessarily. Â You should only also NEVER write fatal messages when you&#8217;re emotional, like when a 3rd party web service breaks for the umpteenth billionth time, and it&#8217;s not your fault&#8230; yet your team always gets blamed. Â Maybe the code isn&#8217;t in a solid enough place yet to actually debug it.</p>
<p>Fatal&#8217;s should really be saved for situations in which you&#8217;re royally screwed. Â If you fail to save a file, and you&#8217;re app is built a Notepad like app&#8230; you&#8217;re pretty screwed, but you&#8217;re not royally f&#8217;ed&#8230; there is a big difference. Â Maybe the user is out of hard drive space, or the file is locked. Â If you can&#8217;t recover from an error, but perhaps can wait it out, you still have a chance.</p>
<p>If your external services.xml file doesn&#8217;t load, and thus you&#8217;re entire app doesn&#8217;t work? Â Yeah, that&#8217;s a fatal message.</p>
<p><strong>More on Messages</strong></p>
<p>Litter your application with these, but only the ones you need. Â Sorting through hundreds of messages to solve a simple null pointer exception is painful; don&#8217;t make your job harder than it has to be&#8230; but don&#8217;t skimp on helpful details either. Â It&#8217;s an art, and you&#8217;ll get better over time. Â Sometimes your messages will be great for 6 weeks&#8230; and then after that section of code base always works, you can comment them out.</p>
<p>Finally, try to be proactive with errors &amp; warnings. Â If something breaks, and you have an idea, provide insight into perhaps why. Â Examples include ExternalInterface.call or stage.displayState == &#8220;fullscreen&#8221;. Â Both can fail because the HTML/JavaScript embedding them didn&#8217;t have the proper parameters set. Â You can explain what these are. Â Even if that isn&#8217;t the problem, knowing they are gone usually hints that perhaps the html-template in Flex Builder got messed up during a merge, or perhaps the wrong HTML was pushed to the server, etc. Â These are really nice when they popup months later, and you immediately go, &#8220;I&#8217;ve never seen this message before&#8230; we clearly did something out of the ordinary.&#8221;.</p>
<p>Finally, keep in mind you should try not to push debug messages to your staging &amp; production servers. Â You need at least 2 servers without messages in case they negatively affect things. Â Accessing objects inside of a debug message itself can cause a null pointer for example. Â Also, trace is basically a write to the disk in some situations, and slows your app down. Â While removing the messages and speeding your app up may seem like a good thing, sometimes strange race conditions your debugger fixed will arise. Â Better to see them before you move to production.</p>
<p><strong>Reporting</strong></p>
<p>Logging is a form of reporting, but reports specifically are run on certain sections of the code base and data to get finer grained information, and ONLY on that section. Â Sometimes you can write a unit test to get the report you want, or other times just a custom class/application. Â Examples include validating, en masse, all data coming from your back-end is valid. Â On my current project, I loop through 500 videos and ensure they play within 10 minutes; all I do is hit a URL in the browser and it runs. Â It prints out custom log information on the status so I know clearly what&#8217;s going on. It&#8217;s ONLY for that particular report, so I don&#8217;t need to do any filtering.</p>
<p>Reports can be run in specific SWF&#8217;s tailor made specifically to run them. Â Making these easily accessible to others allows increased insight to various parts of the application. Â Example:</p>
<p>&#8220;Jesse, the application isn&#8217;t displaying images from the image server again.&#8221;</p>
<p>&#8220;How do you know it&#8217;s the image server that&#8217;s failing?&#8221;</p>
<p>&#8220;You&#8217;re debug window said it was.&#8221;</p>
<p>&#8220;Did you run the image server tester app?&#8221;</p>
<p>&#8220;Yes, and it confirmed that our internal development image server works, but when we he hit the production 3rd party one, it fails, so it&#8217;s definitely their fault again, not ours. Â I&#8217;ve already told the build master to switch to our local server for our noon demo until the 3rd party can get their act together. Â Just wanted to let you know if you start getting old images.&#8221;</p>
<p>Within seconds, someone from your team can run a SWF that ISN&#8217;T your application, and determine it&#8217;s not the application that&#8217;s broken. Â Sometimes, applications take awhile to run, as well as awhile to navigate to the problem section you want to test. Â If the problem occurs repeatedly, you make it dead simple to diagnose by all. Â Win.</p>
<p>Using these reports in tandem with other data allows PM&#8217;s to place pressure where they need to, with the team&#8217;s confidence behind them.</p>
<p><strong>Other Examples of Fire Drill &amp; Crisis Prevention</strong></p>
<p>This crap happens to me ALL the time. Â An IM pops up:</p>
<p>&#8220;Dude, the app isn&#8217;t showing any data!!!!&#8221;</p>
<p>&#8220;I know. Â I already told our boss. Â It&#8217;s not our fault, it&#8217;s the server team having migration issues. Â They&#8217;ll have it up in about 10 minutes working again.&#8221;</p>
<p>&#8220;Whoa&#8230; that was quick.&#8221;</p>
<p>That, vs. panicking, and then you have to run the app. Â This assumes you aren&#8217;t in the middle of something and the app can even compile. Â Within seconds, you clearly identified the problem, informed the necessary parties, and set the team at ease. Â That as opposed to a fire drill which breaks team focus. Â As we know, developer focus is EXTREMELY valuable to maintain.</p>
<p>Another is:</p>
<p>&#8220;Jesse, Java middle tier dev here. Â We&#8217;re not seeing video&#8217;s work here, but a quick test in the browser shows they are coming from Amazon&#8217;s CDN no problem. Â I didn&#8217;t want to spend an hour running scripts to sort through failed video FTP logs, so was curious if you knew of anything before I did so?&#8221;</p>
<p>&#8220;Huh?&#8221;</p>
<p>:: runs video tester ::</p>
<p>&#8220;Hrm&#8230; works in the tester; you checking production?&#8221;</p>
<p>&#8220;Yep.&#8221;</p>
<p>&#8220;Ugh&#8230; hold on, lemme test&#8230;.&#8221;</p>
<p>:: tests ::</p>
<p>&#8220;Yep, my code broke it&#8230; I&#8217;m getting error messages from a totally different server in the app itself. Â Give me an hour, I&#8217;ll push a new build.&#8221;</p>
<p>&#8220;Thanks!&#8221;</p>
<p>First, I saved a middle tier developer&#8217;s time. Â Second, I quickly ascertained the core video services worked; it&#8217;s just my latest code change broke it. Â This WITHOUT having to resort to a debugging session, or even comparing tagged builds in SVN.</p>
<p><strong>More on Video Diagnosis</strong></p>
<p>I use video diagnosis as an example reporting application merely because streaming video is really complicated. Â There are a lot of failure points, and it helps to know which point failed. Â Without verbose logging, it&#8217;s hard to tell what the error really was. Â In dealing with 3rd party CDN&#8217;s, they will NOT respond to you unless you can easily point the finger. Â Thus, you need verbose coverage of errors to effectively communicate all bases on your side are covered.</p>
<p>For example, does the NetConnection work? Â If one of his 7 failures, excluding the 10 billion ones you have manually parse (yes, PARSE) out of NetStatus, do you know which one failed, and why? Â What about NetStream? Â Are they failing because of your session? Â Your token? Â A malformed URL that botched the whole process?</p>
<p>This is where a complex section of code is better tested in isolation. Â Unit tests help here, yes, but a lot of times you need to run a lot of stateful code that gets way too complex to test in just 1 unit test. Â That, and you verbose reporting data, in order. Â Data that you can send to those in charge and CDN&#8217;s for help tickets.</p>
<p>Having a simple Flex app that plays a bunch of videos and reports verbosely on their successes and failures is invaluable without having to:</p>
<ol>
<li>run the app (assuming it complies, and assuming it&#8217;s working on a specific server where the problem is reported)</li>
<li>login</li>
<li>navigate to section</li>
<li>select video play</li>
</ol>
<p>&#8230;slow! Â If you do this more than 2 times, you&#8217;ll probably be doing it a lot more. Â Things that are complex break more often, thus having diagnostic tools around them helps you more quickly ascertain the problem. Â Remember, while unit tests specific units of code, diagnostic tools test application functionality. Â While you can write unit tests to do this, writing a simple GUI anyone can run quickly to see if something works is invaluable.</p>
<p><strong>Service Layer Diagnostic Tools</strong></p>
<p>For most services (web service, REST, SOAP, Remoting, etc), unit tests will suffice. Â If you can quickly test 30 web services, and see that not only do they work, but the data they are sending back is valid, it&#8217;s really nice to blame the middle tier guys &amp; gals so you can get back to work. Â It&#8217;s always easy to blame the client because that is the main GUI used to access &amp; use the services. Â Granted, the middle tier developers can access your unit tests as well, but sometimes it&#8217;s helpful to provide a GUI for them to quickly test as well. Â This includes customizable parameters that can be sent with verbose logs that ensure you&#8217;re code is sending &amp; getting what it needs. Â Trust me, the more empowered your middle tier developers are, the better off you&#8217;ll be in the long run.</p>
<p>Tools you don&#8217;t have to build here include Firebug for Firefox, Charles HTTP Proxy, and Wireshark. Â All work right now, and all aren&#8217;t your code.</p>
<p>Some tools are built upon a specific service. Â For example, one project we were showing a bunch of images for a certain account. Â Each account had certain images show on certain dates &amp; times. Â It was INTEGRAL that the GUI correctly represented this. Â Since there were a lot of failure points, I created a simple GUI to easily validate that the data I had not only was visually valid for the middle tier developer to confirm in the database, but also matched our applications use of the data. Â It was just a simple DataGrid, in a TileWindow, with 1 custom itemRenderer. Â However, that one component found sooooo many bugs, and really gave us a lot of confidence our back-end was working as it should&#8230; and my parsing code blew chunks.</p>
<p><strong>Performance Diagnostic Tools</strong></p>
<p><a href="http://jessewarden.com/wp-content/uploads/2010/02/stats.png"><img loading="lazy" decoding="async" class="alignleft size-full wp-image-1986" style="margin: 4px;" title="stats" src="http://jessewarden.com/wp-content/uploads/2010/02/stats.png" alt="" width="70" height="100" /></a>While Flex Builder comes with a profiler, you can create your own profilers as well. Â You can access the sampler classes, and/or make your own profiling tools to constantly update you (or manually) on the current performance of your application. Â As RIA&#8217;s tend to push a lot of browser based app limits, it helps to know just how far you are really pushing things.</p>
<p>Existing tools include <a href="http://code.google.com/p/mrdoob/wiki/stats">Stats</a>, which making accessible via right click menu is awesome. Â Also, Grant Skinner&#8217;s <a href="http://www.gskinner.com/blog/archives/2010/02/performancetest.html">PerformanceTest</a>. Â Getting familiar with how Flex&#8217;s profiler works, at least for memory, is a wonderful start.</p>
<p><strong>More on Tools</strong></p>
<p>Most diagnostic tools I create are simple, quick, and exist in a self-contained window visually, and package in the code base. Â This ensures the code is easily removed if it causes a problem, it has a low risk of causing a dependency, and I can easily work on the tool in relative isolation. Â I ONLY create a tool when the area in question is risky and/or hard to test. Â Additionally, sometimes I need a GUI to provide simple functionality to test that I can&#8217;t do easily on my own.</p>
<p><a href="http://jessewarden.com/wp-content/uploads/2010/02/so.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-1985" title="SharedObject Debugger" src="http://jessewarden.com/wp-content/uploads/2010/02/so.png" alt="" width="370" height="230" /></a></p>
<p><a href="http://jessewarden.com/wp-content/uploads/2010/02/so.png"></a>For example, I&#8217;ve had 2 applciations were we implemented client side caching via Local SharedObjects. Â Have you ever tried to delete these things? Â Pain the ass, and slow. Â What if you could just click a button IN your app? Â That&#8217;s right, 3 clicks and they are dead? Â What if you could see ALL SO&#8217;s you&#8217;re application uses, how much room they take up, and what their contents are&#8230; IN your application? Â What if you could edit them? Â Exacatly. Â Flash Player allows you to delete them, but it&#8217;s tedious, requires an external website, and there is no good, x-platform apps that quickly give you business insight into your local cache. Â When I say &#8220;business&#8221; I mean, relevant to your application.</p>
<p>For example, just because a Local SO has a ByteArray of BitmapData (since BitmapData doesn&#8217;t serialize properly) doesn&#8217;t mean it&#8217;s actually an image your GUI should show. Â Perhaps you&#8217;re utilizing BitmapData as a faster multi-dimensional array, and saving them to the disk this way. Â You&#8217;re GUI knows what to display, and how.</p>
<p>Another reason is ease of use. Â Having PM&#8217;s and QA testing sessions in a browser based app is pretty straightforward in Safari and Firefox. Â Same with new GUI changes; just clear your cache. Â But what about Flash cookies? Â &#8220;Right Click, choose &#8216;Cache Viewer&#8217;, hit the &#8216;Delete&#8217; button&#8221;. Â Hell, those instructions will fit in a Tweet!</p>
<p>The most infamous: &#8220;What version of Flash Player are you running?&#8221;</p>
<p>&#8220;How do I know?&#8221;</p>
<p>&#8220;Right click, and it&#8217;ll say.&#8221;</p>
<p>Booya. Â Tools don&#8217;t have to be complicated windows&#8230; they could just be simple log messages that can be triggered, or information inside your right click menu.</p>
<p><strong>Landmines</strong></p>
<p>The last thing to touch on is land mines. Â Logging, reporting, and diagnostic tools prepare you for the worst. Â The worst is when you start removing land mines. Â Sometimes you don&#8217;t know you have land-mines until someone steps on one. Â Examples include the login service timing out. Â The ENTIRE APP fails to work merely because of a hiccup in the server. Â The client wasn&#8217;t written to&#8230; oh I don&#8217;t know, try again a couple of times. Â Once it happens, you need to remove it. Â Hopefully you&#8217;ll have a log message&#8230; like the login service never reporting an error, NOR a success. Â If you don&#8217;t, you&#8217;ll learn your lesson, and log that shiz. Â It&#8217;ll never get by you again.</p>
<p>&#8230;oh crap, a timeout. Â No seriously, THIS TIME it won&#8217;t get by me again. Â I&#8217;ll log when the timeout occurs AND whether or not they worked.</p>
<p>Now you&#8217;re talking.</p>
<p>Other more common land-mines include code that blatantly assumes no throws will ever be thrown. Â Things like Loader.load, NetConnection.connect, or no try/catch blocks around navigateToURL. Â Those things are just WAITING to explode. Â If you don&#8217;t have a try/catch, they&#8217;ll blow up eventually. Â If you do, but no log, this is MUCH MUCH worse. Â It&#8217;ll explode, and no one will know. Â Like when the tree falls in the woods, but no one is there to hear it, it doesn&#8217;t make a sound. Â You need to log all errors.</p>
<p>&#8230;except for NetStream.close()&#8230; he&#8217;s the exception to the rule.</p>
<p>Bigger land mines include sections of code that break, and don&#8217;t tell anyone. Â A lot of time developers won&#8217;t get a list of error messages, nor a GUI element to utilize in those cases. Â Feeling insecure, they&#8217;ll either just log it, or perhaps LET it break on purpose to get someone motivated to provide design/UX direction. Â It&#8217;s better to log those messages with proactive verbiage, and even using built-in alert controls (like Flex&#8217;) until a designer/management can provide the developer with what they need. Â Informing the user of a problem with an ugly dialogue, and a log for QA testers/PM, is MUCH better than a hidden log message with no visual indication of what went wrong.</p>
<p>It may not seem like a land-mine, but if no one knows why clicking a button didn&#8217;t work, they&#8217;ll feel insecure about using the app. Â If they are a stakeholder, this insecurity can lead to a fire drill. Â Even if you and/or your team knows the problem, they don&#8217;t since you didn&#8217;t tell them.</p>
<p>Again, most land-mines from a consulting perspective are the ones you don&#8217;t know about. Â A lot of times, the code base is too large for you to properly dig in and ascertain potential problems. Â At least providing diagnostic tools for that region, or empowering others on your team to use/build them, keeps you abreast of what&#8217;s going on. Â I&#8217;m not talking about null pointers; I&#8217;m talking about dependencies that you don&#8217;t know about breaking, and no one, including you, immediately knowing what&#8217;s wrong.</p>
<p><strong>Using my JXLLogger v2</strong></p>
<p>I&#8217;ve provided a sample logger I use in Flex &amp; AIR apps. Â You can use it in pure AS3 projects if you just utilize a simple LocalConnection. Â It doesn&#8217;t follow all of my rules above, but it&#8217;s good enough to get the job done. Â Simple drop the SWC into your libs folder, and go:</p>
<p><code> </code></p>
<p><code> </code></p>
<p><code> </code></p>
<p><code></p>
<pre><span class="keyword">import</span> <span class="identifier2">mx</span>.<span class="identifier2">managers</span>.<span class="identifier2">PopUpManager</span>;

<span class="identifier2">PopUpManager</span>.<span class="identifier2">createPopUp</span>(<span class="identifier">this</span>, DebugMax, <span class="identifier">false</span>);
DebugMax.<span class="identifier">log</span>(<span class="string">"Application::init, DebugMax ready and able, SIR!"</span>);</pre>
<p></code></p>
<p>Thenceforth, anywhere in your application, you can go, DebugMax.log(), or debug, etc.</p>
<p><strong>Cons</strong></p>
<p>Having your application clearly talk to you and your team, with associated diagnostic &amp; reporting tools to help augment your existing debugging capabilities&#8230; what could wrong that?</p>
<p>It&#8217;s more code.</p>
<p>More code means more things that can possibly go wrong. Â More code means more things to maintain, to steal your focus from my core objective. Â It&#8217;s even worse in Agile/Scrum where while it may be a necessity, to create code to help debug other code, yet you&#8217;re technically only getting the user story points for one particular feature. Â While you get better at recognizing what tools you need to create, and thus factor that into your perception of the challenge associated with specific user stories, it&#8217;s sometimes hard to justify.</p>
<p>&#8220;Did you finish the login service?&#8221;</p>
<p>&#8220;No.&#8221;</p>
<p>&#8220;Why not?&#8221;</p>
<p>&#8220;&#8230;well, my server-reporting app that allows me to see if the server is awake took longer than anticipated.&#8221;</p>
<p>&#8220;You were only supposed to code 1 class that logged into the server, not right a server monitoring application.&#8221;</p>
<p>&#8220;Dude, that server goes down ALL the time and the LoginService class has no GUI; we don&#8217;t have an easy way to debug yet what errors are real, what are our code, and what&#8217;s that bloody server.&#8221;</p>
<p>&#8220;I don&#8217;t care, you&#8217;re clearly off task.&#8221;</p>
<p>&#8220;And you clearly are a douche!!!!&#8221;</p>
<p>See what I mean? Â If you use the same arguments against Test Driven Development, they have the same negative consequences here, specifically, you&#8217;ve created more code to maintain. Â Worse, that code isn&#8217;t often factored into project planning &amp; budget. Â It&#8217;s just assumed that if your design or data model changes, that you go update your tests classes because they &#8220;pay for themselves&#8221; in the future. Â Hopefully that future is before your next UAT/deadline, and they + the things you need to get done that the client/your boss actually cares about are finished.</p>
<p>It&#8217;s really hard to argue against good logging. Â Everyone benefits, and you can do it whilst you code. Â Creating diagnostic tools can sometimes be justified as simple prototypes for a larger GUI. Â If you have to create a real-time graph for example, that is REALLY complicated. Â Creating a simple tool that just shows the values as they are is much easier, and VERY valuable in the long run to visually compare against your in-development graphing component.</p>
<p>Full blown diagnostic tools, however, can usually only be justified to those who&#8217;ve been doing this for awhile, are confident in your ability to not go off on a tangent (assuming you don&#8217;t have better things to do), and/or actually have a business need.</p>
<p>For example, Flex &amp; Flash applications are SWF&#8217;s. Â As such, they are a binary format that is self contained on the page, and doesn&#8217;t have massive integration with the browser like HTML/JS/CSS does. Â Thus, common debugging and reporting tools &amp; plugins available on the web do not work well with Flex/Flash apps as they do with HTML ones (ie Firebug, and various web developer toolbars built into some browsers). Â Therefore, sometimes clients will specifically request monitoring tools and/or ways of testing the health of the application and/or getting reporting metrics from it.</p>
<p>Again, most of the times where these tools &amp; techniques are valuable is when you&#8217;re consulting on a large code base you don&#8217;t know. Â Like wrapping strange code with unit tests, they are created to give insight into how the code behaves since if it were good, it&#8217;d be easy to find out, and you wouldn&#8217;t need custom diagnostic tools. Â You&#8217;re creating these tools for yourself to compare the information your good, working code is giving you about the &#8220;great unknown&#8221;. The more solid information you have in chaotic situations, the better. Â You can be the calm in the middle of the storm, and slowly spread that calm over time.</p>
<p>In those situations, while management/stakeholders still want fixed features and new functionality, you&#8217;re clearly there as a consultant for a reason. Â Establishing a strong beachhead that can confidently stand on to effectively assess the situation is the right thing to do.</p>
<p><strong>Conclusions</strong></p>
<p>A simple test to ascertain if you need to utilize logging &amp; diagnostic tools in your application is to ask yourself: Does my current team have fire drills and our crises? Â If yes, then yes, you need logging &amp; diagnostic tools.</p>
<p>A simple test to ascertain if your application has land-mines can either be solved by doing a little digging yourself. Â Do you commonly see sections of the code where obvious try/catch are needed? Â Does the code assume a lot of things will never be null, yet have no centralized factory functions to ensure they aren&#8217;t? Â Do things blow up in the app randomly, and know one on the team has a good idea as to why?</p>
<p>Using logging to make your application talk will help you develop and debug with confidence. Â It&#8217;ll also have the wonderful side effect of having your team members, even the non-developers, getting insight into the application, sometimes solving their own problems, and providing you with helpful information to solve errors when they occur. Â Nothing like having a verbose log with a JIRA ticket.</p>
<p>Using reporting tools can empower others to get finer grained information about problem areas, and having optional tools to corroborate problems, especially with 3rd party libraries &amp; services.</p>
<p>Removing land-mines from the code ensures they won&#8217;t blow up; and if the do, you know, or knew, it was going to happen via a log message and/or diagnostic tool. Â The real challenge is figuring out what land-mines you focus on, and those you don&#8217;t. Â That just comes from experience.</p>
<p>Preventing stressful situations and empowering the team to have insight into the workings of the application goes a long way to earning trust with your client. Â The app may be full of hundreds of little time bombs, but eventually you&#8217;ll know about all of &#8217;em, and those you don&#8217;t, you&#8217;ll know why. Â As will your team. Â That allows you to kick ass&#8230; even if the current code base doesn&#8217;t.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2010/02/consulting-chronicles-3-preventing-fire-drills-crises-by-removing-land-mines-and-using-diagnostic-tools.html/feed</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
	</channel>
</rss>
