<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>It's Majax</title>
	
	<link>http://jmather.com</link>
	<description>"Any sufficiently advanced technology is indistinguishable from magic." - Arthur C. Clarke</description>
	<lastBuildDate>Mon, 25 Mar 2013 16:54:51 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ItsMajax" /><feedburner:info uri="itsmajax" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>How we can improve the hackathon experience</title>
		<link>http://feedproxy.google.com/~r/ItsMajax/~3/G86XFbFIB4M/</link>
		<comments>http://jmather.com/2013/03/25/how-we-can-improve-the-hackathon-experience/#comments</comments>
		<pubDate>Mon, 25 Mar 2013 16:54:51 +0000</pubDate>
		<dc:creator>Jacob Mather</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://jmather.com/?p=595</guid>
		<description><![CDATA[So I have been thinking a lot about hackathons and community participation (and the barriers thereof) lately. Let&#8217;s be clear here, I am talking about hackathons which feature a competition of one nature or another, however I&#8217;m sure some of this will be applicable and/or helpful generally. It started with attending the hackathon at SunshinePHP,(...)]]></description>
				<content:encoded><![CDATA[<p>So I have been thinking a lot about hackathons and community participation (and the barriers thereof) lately. Let&#8217;s be clear here, I am talking about hackathons which feature a competition of one nature or another, however I&#8217;m sure some of this will be applicable and/or helpful generally.</p>
<p>It started with attending the hackathon at <a href="http://2013.sunshinephp.com/">SunshinePHP</a>, and then became fueled by talking with members of the Developer Outreach program at <a href="http://www.mashery.com">Mashery</a>.</p>
<p>The way we generally do hackathons (as a PHP community) right now feels fundamentally broken. A few of the problems I see:</p>
<ul>
<li>There generally isn&#8217;t a lot of clear focus given on what to build, which really becomes an issue when you add the time factor in.</li>
<li>The expectation of the quality of &#8216;product&#8217; produced is way generally totally undefined for newcomers.</li>
<li><span style="line-height: 13px;">They are incredibly short. SunshinePHP had, I think, 5 hours of &#8216;hacking time&#8217; available. I think unless it&#8217;s long enough that you sleep in the middle of it, you&#8217;re going to miss some of the fundamental magic that can happen, without some help.</span></li>
</ul>
<p>I get that it&#8217;s difficult to add a hackathon to a PHP conference and make it a first class citizen. I get it. So instead of saying spend more resources on improving the hackathon, I have some ideas on how to take the current constraints and try to work within them to make the experience better while still fitting in to the traditional timeframes we have allotted.</p>
<h2>1. Pick a theme</h2>
<p>Having a theme for your hackathon will provide an overall context to how people work at deciding what project to do. It&#8217;s been said many times over that <a href="http://www.nytimes.com/2010/02/27/your-money/27shortcuts.html?_r=0">having too many choices is bad</a>. Help out your participants and give them a container to think in. Let them wander outside of it if they like, but it will help many people. Any theme will do, contrived or not, provided you follow the other tips below.</p>
<h2>2. Explicitly define the level of &#8216;done&#8217; you are looking for</h2>
<p>A lot of hackathon participants will be new (or relatively new) to the event style, so they enter it with whatever context they generally operate from. Myself, I&#8217;m always looking for the product in something, the viable business model, and the polish. Which is incidentally the totally wrong vantage point to use for a few hour hackathon. Let people know this. Tell them you&#8217;re expecting (maybe not even fully functional) prototypes of an idea. Tell them to focus on the raw creative pieces, and to leave the polish behind.</p>
<h2>3. Give them tools to mitigate the boring parts</h2>
<p>If you&#8217;re doing an API hackathon, write some wrappers for a few curated APIs (here&#8217;s where the theme comes in useful &#8212; use that to guide which APIs you pick to promote). If you&#8217;re doing a technology hackathon, have hard-copy references of important pieces of information to make it easier for developers to track and reference several places at once. If you care about the final presentation of the submissions (the polish), give developers a template to work from (probably based on Twitter Bootstrap, but not necessarily). Give them the right tools and setup to let them focus on the thing that they are good at.</p>
<p>There are other issues we face with conference bound hackathons (namely placement in the schedule, timing of that placement, and competing interests) but those just come inherent in the form-factor of the two or three day conference. If you don&#8217;t like these constraints, be sure to take a look at dedicated hackathons like the <a href="http://www.soflophp.org/events/104419222/?eventId=104419222&amp;action=detail">SoFloPHP Hack-a-thon</a> that my friend Adam Culp and the SoFlowPHP User Group are putting on in the next few weeks. Florida too far away? Start your own. Need help? <a title="Contact Me" href="http://jmather.com/contact/">Ask me, and I will work to get you in touch with people who can help.</a> Happy hacking!</p>
]]></content:encoded>
			<wfw:commentRss>http://jmather.com/2013/03/25/how-we-can-improve-the-hackathon-experience/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jmather.com/2013/03/25/how-we-can-improve-the-hackathon-experience/</feedburner:origLink></item>
		<item>
		<title>Code Evolution: Contact Form (part 2) – A2LAMP</title>
		<link>http://feedproxy.google.com/~r/ItsMajax/~3/igt6UGOWgnA/</link>
		<comments>http://jmather.com/2013/02/19/code-evolution-contact-form-part-2-a2lamp/#comments</comments>
		<pubDate>Tue, 19 Feb 2013 14:00:46 +0000</pubDate>
		<dc:creator>Jacob Mather</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Silex]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://jmather.com/?p=590</guid>
		<description><![CDATA[On Saturday, February 16th, 2013, I talked my way through setting up the same sort of contact form we set up in Code Evolution: Contact Form (part 1) using Silex instead of creating our own framework. There was a lot of invaluable discussion around the room about the value frameworks bring to the table as well. For code(...)]]></description>
				<content:encoded><![CDATA[<p>On Saturday, February 16th, 2013, I talked my way through setting up the same sort of contact form we set up in <a title="Code Evolution: Contact Form (part 1) – Ann Arbor PUG 2013" href="http://jmather.com/talks/2013-01-19/">Code Evolution: Contact Form (part 1)</a> using <a href="http://silex.sensiolabs.org/">Silex</a> instead of creating our own framework. There was a lot of invaluable discussion around the room about the value frameworks bring to the table as well.</p>
<p>For code reference, you can <a href="https://github.com/jmather/code-evolution-contact-form/tree/part1-finished">see where we started from</a>, and <a href="https://github.com/jmather/code-evolution-contact-form/tree/part2-finished">what the code looked like when we were finished</a>.</p>
<p>Related links:</p>
<ul>
<li><a title="Code Evolution: Contact Form (part 1) – Ann Arbor PUG 2013" href="http://jmather.com/talks/2013-01-19/">Code Evolution: Contact Form (part 1)</a></li>
<li><a href="http://silex.sensiolabs.org/">Silex Framework</a></li>
<li><a href="http://symfony.com/">Symfony Framework</a></li>
<li><a href="http://ellislab.com/codeigniter">CodeIgnighter Framework</a></li>
<li><a href="http://www.slimframework.com/">Slim Framework</a></li>
<li><a href="http://framework.zend.com/">Zend Framework</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jmather.com/2013/02/19/code-evolution-contact-form-part-2-a2lamp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jmather.com/2013/02/19/code-evolution-contact-form-part-2-a2lamp/</feedburner:origLink></item>
		<item>
		<title>Why you want my old job</title>
		<link>http://feedproxy.google.com/~r/ItsMajax/~3/lqQCEWVWCbc/</link>
		<comments>http://jmather.com/2013/02/14/why-you-want-my-old-job/#comments</comments>
		<pubDate>Thu, 14 Feb 2013 20:12:59 +0000</pubDate>
		<dc:creator>Jacob Mather</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Silex]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Symfony2]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://jmather.com/?p=583</guid>
		<description><![CDATA[So, for those of you who haven&#8217;t heard, I have put in my notice at my current place of employment (the Democratic Communications at Michigan State Senate) and taken a position with Mashery effective March 4th. Needless to say, I am really excited, but it does put my current team in quite a predicament, because they really need(...)]]></description>
				<content:encoded><![CDATA[<p>So, for those of you who haven&#8217;t heard, I have put in my notice at my current place of employment (the <a href="http://www.senatedems.com/">Democratic Communications at Michigan State Senate</a>) and taken a position with <a href="http://mashery.com">Mashery</a> effective March 4th.</p>
<p>Needless to say, I am <em>really excited</em>, but it does put my current team in quite a predicament, because they really need a developer!</p>
<h2>So let&#8217;s talk about the elephant in the room, shall we?</h2>
<p>The reasoning behind why I am taking a new job is multifaceted, but essentially it boils down to it feeling like it was time to look at what else was out there. There is a lot of interesting stuff going on here, and a <em>ton</em> of benefits, but nothing I was truly passionate about anymore.</p>
<h2>About those benefits</h2>
<p>The benefits here are great. 5+ weeks of PTO, great insurance, 401k matching, the list goes on and on. And that&#8217;s just the standard benefits. Let&#8217;s look at a few of the technical benefits:</p>
<ol>
<li><span style="line-height: 13px;">You get to pick your own platform for new projects &#8212; as the only developer, you decide how to solve the problems handed to you.</span></li>
<li>You get to work with an awesome team &#8212; everyone here &#8220;gets it.&#8221; The people you will work with here are skillful and creative, and understand how the art/science mesh of things work.</li>
<li>You get to solve actual pain points for actual people &#8212; most of your users are in the office, or next door. Real people that you can see as much (or usually as little) as you like. Building software that you can see the impact of directly is very cool.</li>
</ol>
<h2>The down sides</h2>
<p>As with everything, there&#8217;s some &#8220;less awesome&#8221; pieces of the job as well.</p>
<ol>
<li><span style="line-height: 13px;">It&#8217;s on-site in Lansing, Michigan. No remotesies.</span></li>
<li>You will be the only full time developer on staff. While that gives you a lot of freedom, if you can&#8217;t actually swim, you will want to stay out of this water. There is nobody else to blame when your project isn&#8217;t done on time.</li>
<li>There are on very rare occasions (2-3 times per year, we will say) some very tight deadlines. New websites going up in a matter of days. Usually the scope on these is kept fairly tight however.</li>
</ol>
<h2>The skill set required</h2>
<p>Realistically, you need to be able to handle everything involved with building a website beyond the html/css. You will have to set up vhosts in Apache, and understand the basic workings of source control (we&#8217;re set up with git and bitbucket). Deployment strategies are varied &#8211;  new stuff uses capifony and capistrano while older stuff deploys via FTP or (and I&#8217;m very very sorry) issuing a git pull on the live directory structure.</p>
<p>Current projects you will maintain will involve Symfony 1.4 (current CMS), Symfony 2 (some internal tools), and Silex (other external sites). Future projects can use&#8230; whatever you care to use, provided you&#8217;re not intentionally leaving a pile of junk for the next person to pick up.</p>
<p>You will be given all the rope you need to hang yourself many times over, so you have to really be self-reliant on completing your projects, as there is nobody else here who can do your job, for better or worse.</p>
<p>Interested? <a href="http://www.linkedin.com/jobs?viewJob=&amp;jobId=4870852">Check out the job posting on LinkedIn for more information.</a></p>
<p>If you have any questions, <a title="Contact Me" href="http://jmather.com/contact/">please feel free to contact me</a>, or just ask in the comment area below!</p>
]]></content:encoded>
			<wfw:commentRss>http://jmather.com/2013/02/14/why-you-want-my-old-job/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jmather.com/2013/02/14/why-you-want-my-old-job/</feedburner:origLink></item>
		<item>
		<title>Looking back: Sunshine PHP 2013</title>
		<link>http://feedproxy.google.com/~r/ItsMajax/~3/FejHXss9Gbk/</link>
		<comments>http://jmather.com/2013/02/14/looking-back-sunshine-php-2013/#comments</comments>
		<pubDate>Thu, 14 Feb 2013 19:23:11 +0000</pubDate>
		<dc:creator>Jacob Mather</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://jmather.com/?p=578</guid>
		<description><![CDATA[Warning: there is some name dropping. Okay, a lot of it. The only goal of it is to try and convey the extreem importance of attending smaller conferences like Sunshine PHP. Close knit communities in tight quarters breed very interesting opportunities to talk to people you normally might not have a chance to. Take advantage of it(...)]]></description>
				<content:encoded><![CDATA[<p>Warning: there is some name dropping. Okay, a lot of it. The only goal of it is to try and convey the extreem importance of attending smaller conferences like Sunshine PHP. Close knit communities in tight quarters breed very interesting opportunities to talk to people you normally might not have a chance to. Take advantage of it every chance you get.</p>
<h2>First, show up early</h2>
<p>If at all possible, come in the day before the event. Not only will you wake up rested for the conference, but you can take part in pre-conference festivities. The night before the conference, a rather large group of us all went out to dinner together. In no particular order (and please forgive me if I have left anyone out, or added anyone, it has been quite a few days): Jim Ruga, John Kary, Brian Fenton, Jeff Carouth, Sebastian Bergmann, Anthony Ferarra, Matt Davis, Damon Jones, Matt Frost, Beth Tucker-Long (and her family), and Lonnie Brown.</p>
<p>Now even if you&#8217;re not super community savvy, a few of those names should stick out like a very sore thumb.</p>
<h2>Second, don&#8217;t forget the hallway track</h2>
<p>I know, I know. You&#8217;re excited to go see all the speakers give their talks. By all means, if there are talks that look like they absolutely <i>cannot</i> be missed, then go watch them! However, don&#8217;t forget that you will likely be missing a rare opportunity to sit down and have a (near) one-on-one conversation with someone you normally may not run into. I lost count of the number of times I saw Cal Evans and Paul M. Jones talking at a table with a couple empty chairs, or Anthony Ferarra, or any number of people. If there&#8217;s someone you want to be able to have a prolonged conversation with, look out for them between talks and <em>talk</em> to them.</p>
<h2>Third, be actively involved</h2>
<p>The more you participate in the conference, the more you will get out of it. Join the hackathon, play jeopardy, or just Drink With Friends(tm) (seriously, how is that NOT a game yet??). Introduce yourself. Break out of your shell. As out of place as you feel, others feel the same and are just hoping someone comes and talks to them. If you talk first, then you don&#8217;t have to wait so long! Want to meet someone but not feeling up to introducing yourself? Come find me (or, if I&#8217;m not there, ping me on twitter and I&#8217;ll try to find someone to help you!) and I will go do the &#8220;hard awkward part&#8221; of the initial introduction.</p>
<p>Seriously. The PHP community is an amazing group of people. If you love the community, it will love you back. I&#8217;m not just talking about the publicly visible members, I&#8217;m talking about everyone. Each and every one of us contributes to the community in our own way, and it needs all of us to thrive. Coming to events like Sunshine PHP helps to foster the community feeling, because people stop being these faceless nicknames. It makes it easier to communicate with people online, and helps you feel like less of an &#8220;impostor&#8221; at future events, as instead of simply going to a conference, you get to go see your friends again!</p>
]]></content:encoded>
			<wfw:commentRss>http://jmather.com/2013/02/14/looking-back-sunshine-php-2013/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://jmather.com/2013/02/14/looking-back-sunshine-php-2013/</feedburner:origLink></item>
		<item>
		<title>Code Evolution: Contact Form (part 1) – A2LAMP</title>
		<link>http://feedproxy.google.com/~r/ItsMajax/~3/t_6PPjrdh5I/</link>
		<comments>http://jmather.com/2013/01/21/code-evolution-contact-form-part-1-a2lamp/#comments</comments>
		<pubDate>Mon, 21 Jan 2013 16:00:57 +0000</pubDate>
		<dc:creator>Jacob Mather</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://jmather.com/?p=566</guid>
		<description><![CDATA[So on Saturday, January 19th, I gave a talk about how to take existing code and refactor it into something a little more respectable. It&#8217;s a little wandering and has some faults perhaps, but shows you the ropes of how to iterate something over time. You can find the source code for where we started and where we ended for(...)]]></description>
				<content:encoded><![CDATA[<p>So on Saturday, January 19th, I gave a talk about how to take existing code and refactor it into something a little more respectable. It&#8217;s a little wandering and has some faults perhaps, but shows you the ropes of how to iterate something over time.</p>
<p>You can find the source code for <a href="https://github.com/jmather/code-evolution-contact-form/tree/part1-start">where we started</a> and <a href="https://github.com/jmather/code-evolution-contact-form/tree/part1-finished">where we ended</a> for this talk on GitHub.</p>
<p>Other links:</p>
<ul>
<li><a href="http://www.w3schools.com/html/html5_form_input_types.asp">HTML5 Elements</a></li>
<li>Email autocorrect &#8211; <a href="https://github.com/Kicksend/mailcheck">Kicksend&#8217;s mailcheck</a></li>
<li><a href="http://stackoverflow.com/questions/1417373/why-is-register-globals-so-bad">Why register globals is bad</a></li>
<li><a href="http://11heavens.com/true-or-false-in-php">True/False weirdness</a></li>
<li><a href="http://php.net/manual/en/control-structures.alternative-syntax.php">Alternate control structure syntax</a></li>
<li><a href="http://stackoverflow.com/questions/2829581/why-do-php-array-examples-leave-a-trailing-comma">Re: the array trailing comma debate</a></li>
<li><a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery">Cross-site Request Forgery (CSRF)</a></li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://jmather.com/2013/01/21/code-evolution-contact-form-part-1-a2lamp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jmather.com/2013/01/21/code-evolution-contact-form-part-1-a2lamp/</feedburner:origLink></item>
		<item>
		<title>Looking ahead: SunshinePHP 2013</title>
		<link>http://feedproxy.google.com/~r/ItsMajax/~3/uUzpHI6YoPs/</link>
		<comments>http://jmather.com/2013/01/21/looking-ahead-sunshinephp-2013/#comments</comments>
		<pubDate>Mon, 21 Jan 2013 14:00:33 +0000</pubDate>
		<dc:creator>Jacob Mather</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://jmather.com/?p=559</guid>
		<description><![CDATA[I am eagerly looking forward to attending SunshinePHP in February. I wasn&#8217;t planning to go for the longest time (cost related), but then, among other things, the community attacked. I&#8217;m looking forward to so many things. I have made many friends over the years, in the Symfony community specifically and the PHP community at large. I(...)]]></description>
				<content:encoded><![CDATA[<p>I am eagerly looking forward to attending <a href="http://sunshinephp.com">SunshinePHP</a> in February. I wasn&#8217;t planning to go for the longest time (cost related), but then, among other things, the community attacked.</p>
<p>I&#8217;m looking forward to so many things. I have made many friends over the years, in the Symfony community specifically and the PHP community at large. I want to greet old friends, and new ones. Seriously &#8212; come shake my hand and say &#8220;HI!&#8221; Beware &#8212; I will do the same to you!</p>
<h2>The Talks</h2>
<p>There are SO many good talks. Seriously:</p>
<ul>
<li>&#8220;<a title="Talk: Symfony2 + EmberJS for Fun and Profit" href="http://sunshinephp.com/schedule/talks/#symfony2-plus-emberjs-for-fun-and-profit">Symfony2 + EmberJS for fun and profit</a>&#8221; and &#8220;<a title="Talk: PHPUnit Best Practices" href="http://sunshinephp.com/schedule/talks/#phpunit-best-practices">PHPUnit Best Practices</a>&#8221; &#8212; I have no idea which talk I will attend. I know Dustin is an amazing presenter, but I&#8217;m curious to see if Sebastian shows underutilized parts of PHPUnit I have yet to discover.</li>
<li>&#8220;<a title="Talk: From the Ground Up - Coding, Deploying, and Scaling with AWS" href="http://sunshinephp.com/schedule/talks/#from-the-ground-up-coding-deploying-and-scaling-with-aws">From the Ground Up – Coding, Deploying, and Scaling with AWS</a>&#8221; and &#8220;<a title="Talk: Building OpenSky with Symfony2" href="http://sunshinephp.com/schedule/talks/#building-opensky-with-symfony2">Building OpenSky with Symfony2</a>&#8220; &#8211; I&#8217;m sure Rowan&#8217;s talk (AWS) will be full of great information, but I&#8217;d also love to see Jonathan present about how a large scale application has been built with Symfony2.</li>
<li>&#8220;<a title="Talk: Silex, the Microframework" href="http://sunshinephp.com/schedule/talks/#silex-the-microframework">Silex, the Microframework</a>&#8221; &#8212; I am already quite experienced with Silex, and will not attend, but if you&#8217;re curious, having talked to Ben on IRC, you will enjoy this.</li>
<li>&#8220;<a title="Talk: From POX to HATEOAS, Our Companies Journey to Build a Hypermedia API" href="http://sunshinephp.com/schedule/talks/#from-pox-to-hateoas-our-companies-journey-to-build-a-hypermedia-api">From POX to HATEOAS, Our Companies Journey to Build a Hypermedia API</a>&#8221;  &#8211; I&#8217;ve talked to Luke in IRC very rarely, and am interested in building stronger API systems, so I&#8217;m curious to see information on how his company has evolved their platform. If you have ever heard me talk about improving as a developer, I always say it happens a day at a time. I&#8217;ll bet Luke has a great story about his company&#8217;s evolution.</li>
<li>&#8220;<a title="Talk: Replication with MySQL" href="http://sunshinephp.com/schedule/talks/#replication-with-mysql">Replication with MySQL</a>&#8221; &#8212; I&#8217;m hoping I will have a need for the knowledge bomb Ligaya will drop in this presentation.</li>
<li>&#8220;<a title="Talk: Dream, Experiment, Create, and Share" href="http://sunshinephp.com/schedule/talks/#dream-experiment-create-and-share">Dream, Experiment, Create, and Share</a>&#8221; &#8212; If you haven&#8217;t seen Fabien present, this is your chance. He makes it look so easy.</li>
<li>&#8220;<a title="Talk: DOs and DONTs of MongoDB" href="http://sunshinephp.com/schedule/talks/#dos-and-donts-of-mongodb">DOs and DON’Ts of MongoDB</a>&#8220; &#8211; I&#8217;m looking forward to getting some great use-cases out of Jeremy&#8217;s talk. I don&#8217;t have any experience with MongoDB, and I&#8217;m hoping that will change.</li>
<li>&#8220;<a title="Talk: How Kris Writes Symfony Apps" href="http://sunshinephp.com/schedule/talks/#how-kris-writes-symfony-apps">How Kris Writes Symfony Apps</a>&#8220;, &#8220;<a title="Talk: Introducing Tests in Legacy PHP Applications" href="http://sunshinephp.com/schedule/talks/#introducing-tests-in-legacy-php-applications">Introducing Tests in Legacy PHP Applications</a>&#8220;, and &#8220;<a title="Talk: Bringing Good Design to the Table" href="http://sunshinephp.com/schedule/talks/#bringing-good-design-to-the-table">Bringing Good Design to the Table</a>&#8221; &#8212; I honestly have NO IDEA where I will end up here. Seeing Kris&#8217;s process when developing a Symfony2 app has the potential to be quite interesting, as other people always do things differently. However Jeff&#8217;s presentation on introducing testing and Brian&#8217;s talk about database design also sound excellent. So torn.</li>
<li>&#8220;<a title="Talk: Cryptography for the Average Developer" href="http://sunshinephp.com/schedule/talks/#cryptography-for-the-average-developer">Cryptography for the Average Developer</a>&#8221; and &#8220;<a title="Talk: Symfony and Javascript Combining the Best of Two Worlds" href="http://sunshinephp.com/schedule/talks/#symfony-and-javascript-combining-the-best-of-two-worlds">Symfony and Javascript: Combining the Best of Two Worlds</a>&#8221; &#8212; Anthony and I have tweeted back and forth on occasion, and I&#8217;m curious if he has added any more to the talk beyond what I have read from him online. On the other hand, Nacho is going to talk about JavaScript frameworks and Symfony2. Sorry Jordi &#8212; I use composer every day. However, if you like Chocolate, tell Jordi that Jacob said he had some for you.</li>
</ul>
<p>And that&#8217;s ignoring Rasmus, Cal, and Keith&#8217;s keynotes &#8212; those will be excellent.</p>
<h2>The People</h2>
<p>It adds an entirely different dimension to your community involvement (on twitter, on IRC, in mailing lists, on GitHub) when you have met the people you are interacting with. Heck &#8212; at Symfony Live 2012 in San Francisco, I used Fabien Potencier as my <a href="http://en.wikipedia.org/wiki/Rubber_duck_debugging">Rubber Duck</a>! Having that context, having met them in person, deepens the interactions you have with people online, and helps to make them more than just an internet handle. I&#8217;m looking forward to seeing so many of my friends again, while also taking the opportunity to meet some new ones as well.</p>
<h2>The Venue</h2>
<p>Seriously. Florida. In February. Do I really need to say more?</p>
<h2>And Finally</h2>
<p>If I find out you came to SunshinePHP and didn&#8217;t shake my hand, I will <span style="text-decoration: line-through;">personally convince GitHub to delete all of your code</span> be very grumpy.</p>
]]></content:encoded>
			<wfw:commentRss>http://jmather.com/2013/01/21/looking-ahead-sunshinephp-2013/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://jmather.com/2013/01/21/looking-ahead-sunshinephp-2013/</feedburner:origLink></item>
		<item>
		<title>2012 Recap</title>
		<link>http://feedproxy.google.com/~r/ItsMajax/~3/L3rAjcc3e00/</link>
		<comments>http://jmather.com/2012/12/31/2012-recap/#comments</comments>
		<pubDate>Mon, 31 Dec 2012 18:32:41 +0000</pubDate>
		<dc:creator>Jacob Mather</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Silex]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://jmather.com/?p=527</guid>
		<description><![CDATA[So I wanted to take a little time and document what happened in 2012 for myself. I think the biggest things I want t take away from 2012 are a few key lessons: Don&#8217;t Be Afraid of What Other&#8217;s Think If you spend your life mired in worries about what others will think of what(...)]]></description>
				<content:encoded><![CDATA[<p>So I wanted to take a little time and document what happened in 2012 for myself.</p>
<p>I think the biggest things I want t take away from 2012 are a few key lessons:</p>
<h2>Don&#8217;t Be Afraid of What Other&#8217;s Think</h2>
<p>If you spend your life mired in worries about what others will think of what you are doing, you will never get anything done.</p>
<p>Just do.</p>
<p>Too much of our lives (collectively) are spent wondering about what others will think about what we are doing? <b>So what</b>. Who CARES if you are wrong. People are wrong ALL OF THE TIME. What matters is that you are not <em>so attached</em> to your wrong opinion that you don&#8217;t change it when presented a valid argument otherwise.</p>
<p>It&#8217;s said the most &#8216;thought to to be smart&#8217; people aren&#8217;t smart because they&#8217;re <em>right</em> but because they are quick to <em>change their minds</em>.</p>
<p>I, of course, have the luxury of never particularly caring what others have thought of what I say or do. It&#8217;s lead to some pretty awful predicaments &#8212; but some pretty awesome ones too. Who, among my close friends, would have pictured me as being one of the ones to immediately volunteer for Symfony Jeopardy at Symfony Live? Especially when I am culturally dumb and (at time time) was quite technically deficient. That didn&#8217;t stop me from answering the only then-to unanswered question though!</p>
<p>Just do.</p>
<p>Go up in front of everyone, be a goof ball, have fun, laugh, be silly. Anyone who actually cares in a bad way isn&#8217;t anyone you want to associate with anyway.</p>
<p>Just do.</p>
<p>Don&#8217;t be afraid of what others will think. Seriously. Most commonly, what most other people will be saying is &#8220;Gee, I wish I could do that!&#8221; And you know why they can&#8217;t? BECAUSE THEY ARE AFRAID! 99% of the people who would say anything negative would never have the nerve to do anything like what you are doing. It&#8217;s 100000x easier to criticize than to produce. Be sure to check the background of those who give you negative feedback and take their input with the appropriate level of expertise it warrants.</p>
<p>Just do.</p>
<h2>Get out in the community</h2>
<p>The PHP Community in general is AMAZING. It&#8217;s full of brilliantly smart people you can talk to, and gives you external input to your internal processes. If your local community isn&#8217;t as as deep into the things you are? Learn to teach them! Learn about how to talk to other developers, how to share your skills and techniques. You&#8217;d be surprised what you&#8217;re capable of.</p>
<p>If you haven&#8217;t spoken to groups before, consider giving a few talks to a local user group. Most likely they&#8217;re running their regular speaker lineup through the wringer, week after week, and offering to talk about something (anything!) that you know even passingly well enough to talk about (I once essentially winged <a title="Introduction to Design Patterns – A2LAMP" href="http://jmather.com/talks/2012-12-15/">a talk about design patterns &#8212; shhhh!</a>).</p>
<p>The other thing being in the community will do is give you a feel for the pulse of where things are heading. There are currents and drafts in the community which you don&#8217;t catch unless you&#8217;re paying attention. See what&#8217;s on the horizon, and pay attention. You&#8217;ll never know what you&#8217;ll miss if you&#8217;re not paying attention.</p>
<h2>Prove you can ship</h2>
<p>I can&#8217;t reiterate this enough. The value of someone who can <em>actually ship a product</em> is waaaaay above someone who can only point to minor contributions in a larger project. If you&#8217;re one of those nameless cogs in a giant organization, it&#8217;s time to join an open source project or build your own thing on the side. Seriously. Nothing shows your value more than being able to to actually ship something. In the world of business, ideas are cheap, and execution is everything. Show people you can execute, and you will open doors.</p>
<h2>Know your stuff</h2>
<p>Read up on the important things core to being a high quality software developer: <a href="http://www.fluffycat.com/PHP-Design-Patterns/">Patterns</a>, <a href="http://www.thedeveloperday.com/php-anti-patterns/">Anti-Pattens</a>, and <a href="http://c2.com/cgi/wiki?CodeSmell">Code Smells</a>, among other things. These will teach you the do&#8217;s and don&#8217;ts of our industry, our trade. They will show you what to do, and often more importantly, what not to do. It&#8217;s the same as new inductees into Martial Arts learn <a href="http://en.wikipedia.org/wiki/Kata">Kata&#8217;s</a>, new developers need to learn these patterns, anti-patterns, and code smells. It gives you the tools to reflexively approach similar problems in the future, and tools to expand on when you need to create something out of thin air.</p>
<h2>Don&#8217;t be afraid to be wrong</h2>
<p>Look at my blog, or the advice I give out in #symfony &#8212; I&#8217;m &#8220;wrong&#8221; all of the time. There&#8217;s usually a much more efficient way to do something than I recommend &#8212; but I don&#8217;t know it! I help people <em>get stuff done</em>. The academic stuff can be left for those <a href="http://en.wikipedia.org/wiki/Ivory_Tower">Ivory Tower</a> folk. I&#8217;m much more interested in what gets stuff done in the trenches. Getting something done is more often much more important than doing it in the best possible way. Working implementations refactor much quicker than potential implementations grow while wandering in the sea of <em><strong>WTF I HAVE NO IDEA WHAT I AM DOING?!</strong></em>. Being wrong <strong>is not a bad thing</strong>. It means <em>both</em> that you were <strong>strong</strong> enough in your opinion that you could voice it, <em>and</em> that when presented with solid contrary evidence, <strong>you changed your wrong opinion into a right one</strong>. How awesome is that?!</p>
<h2>Enjoy what you do</h2>
<p>We&#8217;re in this because we have a <em>passion</em> for either building better code, or building things people love to use, or hell, even just building things. But if you&#8217;re not <strong>enjoying</strong> your work &#8211; <strong>seriously the door is right over there</strong>. Life is <em><strong>FAR TOO</strong></em><strong> SHORT</strong> to spend your days doing things you loathe. If you&#8217;re going to do something for your career, make sure it&#8217;s something you enjoy. I avoided doing development as an actual full career for many many many many many many many many years, because I was afraid that if I took what I <strong>loved</strong> and made it a <em>job</em>, it would never be the <em><strong>same.</strong> </em>Interestingly, I was right &#8212; it was never the same. <em><strong>Now I love going to &#8220;work&#8221; almost every single</strong></em><strong> day.</strong> Seriously, it&#8217;s that simple. Do what you love and you never work a day in your life. Honest.</p>
<h2>Now with that out of the way</h2>
<p>You may be asking yourself &#8220;But this is a recap &#8212; what do YOU do during this year?&#8221; Well, let&#8217;s see:</p>
<ol>
<li>I went to Symfony Live.</li>
<li>I started blogging more regularly.</li>
<li>I was more active in #symfony, #silex, #phpmentoring, #protalk, and #symfony-dev (yikes, right?).</li>
<li>I contributed to the <a href="https://github.com/symfony/symfony-docs/pull/1782">Symfony Documentation</a>.</li>
<li>I started attending User Groups regularly (in <a href="http://www.meetup.com/lansingweb/">Lansing</a>, and <a href="http://www.meetup.com/ann-arbor-php-mysql/">Ann Arbor</a>).</li>
<li>I <a title="How to act like you (maybe actually) care about your work – SFLive SanFran 2012" href="http://jmather.com/talks/2012-09-29/">gave a talk in front of 100+ people</a>.</li>
<li>I <a title="How to act like you (maybe actually) care about your work – Ann Arbor PUG 2012" href="http://jmather.com/talks/2012-11-17/">gave a talk over 30+ minutes</a>.</li>
<li>I <a href="https://github.com/Point5Foundry/tag-it-bundle">have at least one person using one of my open source bundles for Symfony2</a></li>
<li>I have given three people technical feedback on their technical products which have (I feel) reasonably improved the quality of their product (I think I have a knack for this &#8212; have sent an email to php|arch to be a technical reviewer &#8212; look for this in 2013&#8242;s recap!).</li>
<li>I convinced my 4 best business friends to <a href="http://point5foundry.co/">all be business friends together</a>.</li>
<li>I started <a href="http://phpmentoring.org/">mentoring officially</a> (Uzo, Luis, and Yitzchok &#8212; you guys are the best folks a mentor could ask for, really!).</li>
</ol>
<h2>What do I want to do, going forward?</h2>
<p>I&#8217;ll tell you what&#8217;s on my list.</p>
<ol>
<li>I want to launch a product (in the works)</li>
<li>I want to give a mainstream talk at a conference (not an unconf talk)</li>
<li>I want to be more involved in the community (you guys are awesome, seriously!)</li>
<li>I want to help more people hate their jobs less (hey, it&#8217;s what I do&#8230;)</li>
<li>I want to blog more (is this cliché?)</li>
</ol>
<p>Anyway &#8212; 2012 was great, let&#8217;s make 2013 even better!</p>
]]></content:encoded>
			<wfw:commentRss>http://jmather.com/2012/12/31/2012-recap/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://jmather.com/2012/12/31/2012-recap/</feedburner:origLink></item>
		<item>
		<title>Talk: Introduction to Design Patterns</title>
		<link>http://feedproxy.google.com/~r/ItsMajax/~3/NtLfIcDU60E/</link>
		<comments>http://jmather.com/2012/12/22/talk-introduction-to-design-patterns/#comments</comments>
		<pubDate>Sat, 22 Dec 2012 16:34:28 +0000</pubDate>
		<dc:creator>Jacob Mather</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://jmather.com/?p=520</guid>
		<description><![CDATA[I gave a little talk about design patterns last weekend, and followed it up with a few posts about specific patterns.]]></description>
				<content:encoded><![CDATA[<p>I gave a little <a title="Introduction to Design Patterns – A2LAMP" href="http://jmather.com/talks/2012-12-15/">talk about design patterns last weekend</a>, and followed it up with a <a href="/topics/patterns">few posts about specific patterns</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jmather.com/2012/12/22/talk-introduction-to-design-patterns/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jmather.com/2012/12/22/talk-introduction-to-design-patterns/</feedburner:origLink></item>
		<item>
		<title>About the Decorator Pattern</title>
		<link>http://feedproxy.google.com/~r/ItsMajax/~3/EKZah-JmwrI/</link>
		<comments>http://jmather.com/2012/12/21/about-the-decorator-pattern/#comments</comments>
		<pubDate>Fri, 21 Dec 2012 07:00:44 +0000</pubDate>
		<dc:creator>Jacob Mather</dc:creator>
				<category><![CDATA[Code Snippets]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://jmather.com/?p=505</guid>
		<description><![CDATA[The Decorator Pattern lets you to easily extend a given set of objects (either grouped via class inheritance or interface) and extend their functionality in a way that avoids needlessly duplicating code. Our example today will hopefully be pretty close to form, and while generally contrived, will simply illustrate the use of the Decorator Pattern. Let&#8217;s(...)]]></description>
				<content:encoded><![CDATA[<p>The <a href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator Pattern</a> lets you to easily extend a given set of objects (either grouped via class inheritance or interface) and extend their functionality in a way that avoids needlessly duplicating code.</p>
<p>Our example today will hopefully be pretty close to form, and while generally contrived, will simply illustrate the use of the Decorator Pattern.</p>
<p>Let&#8217;s say for instance, you run a video rental service. Let&#8217;s call it&#8230; SmedRocks. Now your crazy programmers have already built your inventory tracking system as a web service, and you have no control over how they have implemented it, but you have to fight the good fight and soldier on. Features must be implemented. To make this even simpler, our API has one function:</p>
<p><em>getVideos</em> &#8211; This returns all of the titles we have, no matter if they are currently rented or not.</p>
<p>Now getVideos returns a JSON array like so:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="json" style="font-family:monospace;">{
    {
        'title': 'Some Movie',
        'status': 'rented'
    },
    {
        'title': 'Some Other Movie',
        'status': 'available'
    }
}</pre></td></tr></table></div>

<p>I&#8217;m sure you can already see the problem with how it&#8217;s returning data. Rented movies and available movies are all mixed in! What a <strong>pain</strong>!</p>
<p>Ok, so let&#8217;s look at what we need to do to get started. Let&#8217;s make our API. This isn&#8217;t how you would ACTUALLY do this, it&#8217;s just an example to get us moving along:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> MovieApi
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getVideos<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">json_decode</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://example.org/rest/getVideos.json'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Excellent! We can now get our videos, but wait &#8212; we&#8217;re in the middle of building this and <em>example.org</em> seems to have gone offline. This isn&#8217;t going to help us get this going! So let&#8217;s refactor real quick so we can keep going on other things.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">interface</span> MovieApiInterface
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getVideos<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> LiveMovieApi implements MovieApiInterface
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getVideos<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">json_decode</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://example.org/rest/getVideos.json'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> OfflineMovieApi implements MovieApiInterface
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getVideos<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$json</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'{{&quot;title&quot;: &quot;Movie 1&quot;, &quot;status&quot;: &quot;rented&quot;},{&quot;title&quot;: &quot;Movie 2&quot;, &quot;status&quot;: &quot;available&quot;}}'</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">json_decode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$json</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Look at that! We&#8217;ve now defined a central <em>MovieApiInterface</em> which both implementations conform to, and have both an online and offline implementation which will also ultimately make writing tests easier.</p>
<p>Ok, now for the juicy part: we need to be able to ask this system for just rented or available movies. We could extend each API implementation, but that&#8217;s going to be some duplication we can live without.</p>
<p>Enter the Decorator Pattern.</p>
<p>With the decorator pattern, we can build an object that accepts a <em>MovieApiInterface</em> object in it&#8217;s constructor, and provides a uniform higher-level way to interact with our lower-level API.</p>
<p>Again, this is basic code to get you thinking, not optimized production-ready code.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> SpecificMovieFinder implements MovieApiInterface
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$movie_api</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span>MovieApiInterface <span style="color: #000088;">$movie_api</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">movie_api</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$movie_api</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getVideos<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">movie_api</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getVideos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getRentedMovies<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$movies</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getVideos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$rented_movies</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$movies</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$movie</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$movie</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">status</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'rented'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$rented_movies</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$movie</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$rented_movies</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getAvailableMovies<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$movies</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getVideos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$available_movies</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$movies</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$movie</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$movie</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">status</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'available'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$available_movies</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$movie</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$available_movies</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Now we have a simpler API that actually conforms to how we will use it in practice instead of how the API designers built the service. This is great! They get their way, and we get ours. Everyone wins.</p>
<p>So how do we use it?</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// development configuration</span>
<span style="color: #000088;">$offline_api</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SpecificMovieFinder<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> OfflineMovieApi<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// live configuration</span>
<span style="color: #000088;">$online_api</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SpecificMovieFinder<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> LiveMovieApi<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Now we get the same functionality on multiple implementations, and as an added bonus, our <em>SpecificMovieFinder</em> also still implements the <em>MovieApiInterface</em> allowing us to use it interchangeably with any <em>other</em> service that may need our api down the line!</p>
<p>My good friend <a href="https://twitter.com/kirkryyn">Beau Simensen</a> pointed out that unfortunately, my example is a little deficient. I&#8217;ll let his gist do the talking:</p>
<script src="http://gist.github.com/e86fcec25e0c2b4e6d7a.js"></script>
<p>Thanks Beau!</p>
<p>What are some other places you can think of using this pattern?</p>
]]></content:encoded>
			<wfw:commentRss>http://jmather.com/2012/12/21/about-the-decorator-pattern/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://jmather.com/2012/12/21/about-the-decorator-pattern/</feedburner:origLink></item>
		<item>
		<title>About the Proxy Pattern</title>
		<link>http://feedproxy.google.com/~r/ItsMajax/~3/kbqmsxLdiyE/</link>
		<comments>http://jmather.com/2012/12/15/about-the-proxy-pattern/#comments</comments>
		<pubDate>Sun, 16 Dec 2012 02:51:05 +0000</pubDate>
		<dc:creator>Jacob Mather</dc:creator>
				<category><![CDATA[Code Snippets]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://jmather.com/?p=496</guid>
		<description><![CDATA[Edit: Added an update with a more concrete example further down. I just wanted to share and provide a further explanation on the Proxy Pattern example I gave at the Ann Arbor PHP/MySQL User Group today. Source: https://gist.github.com/4302634 Now, Dan had mentioned that this could be done through simple inheritance instead of via interface contract,(...)]]></description>
				<content:encoded><![CDATA[<p><em>Edit: Added an update with a more concrete example further down.</em></p>
<p>I just wanted to share and provide a further explanation on the Proxy Pattern example I gave at the Ann Arbor PHP/MySQL User Group today.</p>
<p>Source: <a href="https://gist.github.com/4302634">https://gist.github.com/4302634</a></p>
<p>Now, Dan had mentioned that this could be done through simple inheritance instead of via interface contract, and after some thought, I realized that I disagree.</p>
<p>Typically with an API object, you will initialize with a remote URL, and perhaps a token:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$api_url</span><span style="color: #339933;">,</span> <span style="color: #000088;">$auth_token</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>But remember our new Cache API proxy only takes an API object and a Cache object.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$cache</span><span style="color: #339933;">,</span> <span style="color: #000088;">$api</span><span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>This fundamentally changes the contract that the initial API object creates, and as such, should then NOT extend the original API implementation.</p>
<p>Part of doing OOP well involves the management of contracts we establish. Changing the rules of a function in a sub-classed entity violates the <a href="http://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov substitution principle</a> (as referenced in <a href="http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)">SOLID object oriented design</a>).</p>
<p>Now, you COULD subclass the MyApi class, and add the Cache control via setter injection, but personally I don&#8217;t think that implementation is nearly as clean as providing a proxy object to add the caching functionality.</p>
<p>&nbsp;</p>
<p>p.s. I&#8217;ll leave QuickTime running but I think it did eat the recording of the presentation &#8211; sorry guys! I&#8217;ll put the slides up soon but I don&#8217;t know how much context they will provide given how light they were compared to the commentary that went along with it.</p>
<p>&nbsp;</p>
<p>Update (12/07/2012):</p>
<p>It has been pointed out that my example was perhaps a little too contrived, so I think I found a better one.</p>
<p>Let&#8217;s say you&#8217;re building a system out, and you know you want logging, but you don&#8217;t know what sort of implementation you want to do for said logging. Given that instance, let&#8217;s start with our basic interface:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">interface</span> Logger
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> info<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> debug<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> fatal<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Ok, great! So, because production schedules are tight, we decide to give a very basic implementation first:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> MyBasicLogger implements Logger
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> info<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">error_log</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'INFO: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> debug<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">error_log</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DEBUG: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> fatal<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">error_log</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'FATAL: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Alright! We now have our basic logger implemented!</p>
<p>Oh, what&#8217;s that you say? You want to use Monolog in place of error_log() in production? sure!</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> MyMonologLogger implements Logger
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$monolog</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$monolog</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">monolog</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$monolog</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> info<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">monolog</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addInfo</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> debug<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">monolog</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addDebug</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> fatal<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">monolog</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addCritical</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Now we have two ways of logging messages. Now comes the constraint that we want to be emailed when fatal errors are logged. Your first instinct would be to extend MyMonologLogger and add it by overloading fatal(), but then we can&#8217;t use that functionality on any other logger we ever build. How do we build this functionality in a way that we can reuse over and over again? <em>The Proxy pattern</em>.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> MyEmailingLoggerProxy implements Logger
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$logger</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span>Logger <span style="color: #000088;">$logger</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">logger</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$logger</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> fatal<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">logger</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fatal</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">mail</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'admin@example.com'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'A fatal error has occurred'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> info<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">logger</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">info</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> debug<span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">logger</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">debug</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$message</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>And now, no matter what we choose as our logging backend, now or in the future, we will always easily be able to have those fatal errors emailed to us by simply putting our chosen logging system inside an instance of MyEmailingLoggerProxy.</p>
<p>I hope this clears some things up!</p>
]]></content:encoded>
			<wfw:commentRss>http://jmather.com/2012/12/15/about-the-proxy-pattern/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<feedburner:origLink>http://jmather.com/2012/12/15/about-the-proxy-pattern/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 4.021 seconds. --><!-- Cached page generated by WP-Super-Cache on 2013-05-19 22:34:45 -->
