330 likes | 479 Views
Bits and Pieces. Roger Billerey-Mosier Engineering Lead, Trulia, Inc. http://www.trulia.com. skip intro. Best Practices Rule. What are “Best Practices”? standard body of knowledge standard but always evolving almost a lingua franca, like a software library. Best Practices Rule (2).
E N D
Bits and Pieces Roger Billerey-Mosier Engineering Lead, Trulia, Inc. http://www.trulia.com
Best Practices Rule • What are “Best Practices”? • standard body of knowledge • standard but always evolving • almost a lingua franca, like a software library
Best Practices Rule (2) • Why “Best Practices”? • They work • Not all difficult or expensive to implement • They let you focus on what differentiates you from the competition • Being feature-equivalent is necessary, and not sufficient • The competition probably uses best practices • So you’d better implement them as well
Best Practices In Development • OOP is not optional. Spaghetti code is... • hard to read • impossible to maintain • Someone else WILL work on your code • impossible to share across pages/modules • Someone WILL ask you to put that widget from page X on page Y
Best Practices In Development • OOP is not optional • Separate data access, data and display • Avoid platform-specific code • Use a templating system • “MVC” model • Namespace your Javascript • Run unit tests • Use version control (CVS, SVN, etc.)
Avoid Platform-Specific Code Instead of: mysql_connect(‘mydb’, ‘myuser’, ‘12345’); $result = mysql_query(‘SELECT id,name FROM MyUser ORDER BY name’); while($row = mysql_fetch_array($result)) echo $row[‘id’].”\t”.$row[‘name’].”\n”; Do: $db = new db(); $db->query(‘SELECT id, name FROM MyUser ORDER BY name’); while($db->next_record()) echo $db->fetch(‘id’).”\t”.$db->fetch(‘name’).”\n”;
Best Practices In Development • OOP is not optional • Separate data access, data and display • Avoid platform-specific code • Use a templating system • “MVC” model • Namespace your Javascript • Run unit tests • Use version control (CVS, SVN, etc.)
Instead of endless strings of: display.php: <? echo “<h1>”.$name.”</h1>”; ?> Do: display.php: <? $tpl = new Template(‘template’); $tpl->assign(‘NAME’, $name); $tpl->render(); ?> template.tpl.html: <h1>{NAME}</h1> Use A Templating System
Best Practices In Development • OOP is not optional • Separate data access, data and display • Avoid platform-specific code • Use templating system • “MVC” model • Namespace your Javascript • Run unit tests • Use version control (CVS, SVN, etc.)
MVC Model, Simplified (1) • MVC = Model, View, Controller • Model = data and business logic • View = display, UI • Controller = “conductor” that shepherds them
controller.php $from = $_GET[‘from’]; $to = $_GET[‘to’]; $data = new Model($from, $to); $data->look_up(); $display = new View($data); $display->render(); Model.php class Model { private $_from, $_to, $_data; public function __construct($from, $to) { $this->_from = $from; $this->_to = $to; $this->_data = array(); } public function look_up() { // query from db using from, to, etc. } } View.php class View { private $_Data; public function __construct(&$Data) { $this->_Data =& $Data; } public function render() { $tpl = new Template(); $tpl->assign(‘TITLE’, $this->_Data->get_title()); foreach($this->_Data as $k => $v) { $tpl>assign(‘HEADER’, $k); $tpl->assign(‘VALUE’, $v); } return $tpl->render(); } } MVC Model, Simplified (2)
Best Practices In Development • OOP is not optional • Separate data access, data and display • Namespace your Javascript • This avoids naming conflicts • Use Javascript objects whenever possible • Run unit tests • Use version control (CVS, SVN, etc.)
Namespace your Javascript Basic namespacing: function MyNamespace() {} MyNamespace.validate = function(partridge, pear, tree) { alert(‘hello there, Ms. ’ + partridge); } You can now invoke validate as MyNamespace.validate(‘Cassidy’, ‘apple’, ‘shrub’);
Javascript Objects // constructor syntax function Person(name) { this.name = name; } Person.prototype.say = function(message) { alert(this.name + ‘ says “‘ + message + ‘”’); } var joe = new Person(‘Joe’, 24); joe.say(‘wassup’);
Best Practices In Development • OOP is not optional • Separate data access, data and display • Namespace your Javascript • Run unit tests • Automatically run regression tests • Test units are use cases; they help you design your class interfaces • Use version control (CVS, SVN, etc.)
Unit Testing Simplified <? $MyObject = new MyClass(); $Test = new TestUnit($MyObject); $test_data = array( array(‘test’ => ‘<h1>hello</h1>’, ‘expected’ => ‘hello’), array(‘test’ => ‘<div class=“blue”>xy</div>’, ‘expected’ => ‘xy’) ); foreach($test_data as $test => $expected) { // this invokes the strip method on the $MyObject object // with $test as argument // and compares the return value of strip with $expected // returns true if they match, and false if not, i.e. something like // if ($MyObject->strip($test) != $expected) return false; $pass = $Test->assert(‘strip’, $test, $expected); // you could email the developer, file a bug, log to file, etc. echo $pass ? “Pass” : “Fail”; } ?>
Best Practices In Development • OOP is not optional • Separate data access, data and display • Namespace your Javascript • Run unit tests • Use version control (CVS, SVN, etc.) • New code broken? • Roll back to previous stable state • Need to restore old feature? • Grab it from old version • Develop new features while maintaining stable code base for fixes? • Branch and merge
Best Practices in Design • Don’t co-opt standard widgets for other purposes • Users don’t have time to learn your whiz-bang new navigation/interaction • Switching costs are low (competition is one click away) • Don’t use yourself as a benchmark for your users • Hallway usability tests are cheap; use them
Best Practices in Design • Don’t co-opt standard widgets for other purposes • Users don’t have time to learn your whiz-bang new navigation/interaction • Switching costs are low (competition is one click away) • Don’t use yourself as a benchmark for your users • Hallway usability tests are cheap; use them
Best Practices in Design • Don’t co-opt standard widgets for other purposes • Remember basic, standard UI principles • logo in top left corner is clickable, goes home • checkboxes or radio buttons don’t reload • use links or buttons for actions that have a big UI impact • Bigger fonts are better than smaller fonts • Big widgets are better than small targets • Color-coding should be avoided • some 10% or more of users are color-blind; • use high-contrast color schemes
Best Practices in Design • Don’t co-opt standard widgets for other purposes • Remember basic, standard UI principles • Logo in top left corner is clickable, goes home • Checkboxes or radio buttons don’t reload • use links or buttons for actions that have a big UI impact • Bigger fonts are better than smaller fonts • Big widgets are better than small targets • Avoid color-coding • some 10% or more of users are colorblind • use high-contrast color schemes if you have to color-code
Best Practices in Design • Don’t co-opt standard widgets for other purposes • Remember basic, standard UI principles • Remember your audience • You’re a hip techie. Your users aren’t. • Your cool sliders SUCK.
Best Practices in Design • Don’t co-opt standard widgets for other purposes • Remember basic, standard UI principles • Remember your audience • You’re a hip techie. Your users aren’t. • Your cool sliders SUCK. • small target, very hard to acquire • lots of users (esp. w/ laptops) can’t drag easily • non-linear scale hard to represent
Best Practices in Design Oh, and... your cool Flash intro SUCKS too
Best Practices in Design • This doesn’t mean “don’t innovate” • It only means “don’t break what works” • You’re free to invent new things • hindsight.trulia.com • maps.google.com • your project here
Best Practices in Production • Serve compressed content from Apache • mod_deflate
Best Practices in Production • Serve compressed content from Apache • Minimize HTTP connections in browser • Minimize size and number of images
Minimize the Number of Images A rollover effect with 2 images can be achieved with a single image with both states: Your CSS then switches the states on hover: a.bgbutton { background: url(“pretty_button.gif") 0 0 no-repeat; } a.bgbutton:hover { background-position: 0 -54px; } <a class=“bgbutton” href=“http://www.example.com”>Anchor text</a>
Best Practices in Production • Serve compressed content from Apache • Minimize HTTP connections in browser • Minimize size and number of images • Shrink and join included content (JS, CSS)
Best Practices in Production If you have: <script src=“tools.js”></script> <script src=“site.js”></script> <script src=“sliders.js”></script> Remove comments, etc and merge the files into: <script src=“combined.js”></script> File size is bigger, but only 1 http connection is required; size matters less if you...
Best Practices in Production • Serve compressed content from Apache • Minimize HTTP connections in browser • Minimize size and number of images • Shrink and join included content (JS, CSS) • Use a CDN (Content Delivery Network) • Akamai caches static content • Akamai’s servers optimize the route to the client • Content is served from the closest server to the client’s computer
How to be Successful Without Really Trying To Fit into a PowerPoint Header Section • Have fun • Work with people who are better than you • Hire same • Learn from others • Embrace change • Resist change • Be kind to animals • Keep in touch: roger@trulia.com