A/B Testing Links:
- How to keep visual design consistent while A/B testing like crazy
- Effective A/B Testing
- A/B Testing at PBworks
- PickFu | Cheap & instant market research. A/B Testing. Public Opinion Surveys. Poll Testing.
A/B Testing with Mixpanel:
Model-View-Controller, or MVC for short, is an software architecture pattern for user interfaces that creates a distinction between the display (or view), the data (or model), and the interaction (or controller). In this article, I’m going to focus specifically on how MVC applies to the client side of web applications. What I mean is that MVC in a web based ui translates to
This separation of concerns means that as long as the model stays consistent, you can
For a great example of 1 checkout css Zen Garden. Here, the same HTML (the model) can be seen with many different views.
Now checkout the jquery ui demos for a clear example of both 1 and 2. Again, the same HTML has many different views with the various CSS themes, and you can also see jquery ui controller code in action. The Javascript manipulates the model, affecting what you see and how you see it, independently of which theme (or view) you choose.
What this all means is that you can create semantically correct HTML optimized for search engines, CSS so your page looks good for humans, and Javascript to make your page interactive. In other words, content can be separated from presentation, which can be separated from the interaction behavior. The CSS and Javascript can be developed (mostly) independently and only be loosely coupled to the HTML.
Taking this a step further, it’s possible to create generic views and controllers using CSS and Javascript that work on a small generic model. jquery ThickBox is an example of this, since it can be used on any page where you have <a class='thickbox' ...>...</a>. As long as your HTML supports the generic model, you can reuse the CSS and Javascript across multiple pages.
jQuery sliders:
jQuery tooltips:
Usability testing:
Misc:
Code = Information. [1] Therefore, Software Architecture can be approached as Information Architecture. Information Architecture can be defined as
The above definitions and much of the inspiration for this article comes from the book Information Architecture for the World Wide Web. My goal is to explain some of what an Information Architect does, and that software developers, especially the lead developer, should approach their code as an information system, applying the principles of Information Architecture. Why? Because it will lead to more organized, better structured, easier to understand code, which will reduce maintenance costs, decrease training time, and generally make it easier for you and your team to get things done.
So, what are the core focus areas for an Information Architect?
Organization Systems are exactly what you think they are: systems to organize information. Imagine if you had to come into your current code base completely fresh, knowing nothing about it. Does that thought horrify you? If your code isn’t organized, then it can be very hard for new developers to come in and figure out what’s going on. Think of your code repository as a shared information environment. If you are the only one that can navigate it, let alone modify it, then you’ll always be stuck maintaining it. Hopefully your goal is not job security, but to provide an environment conducive to change.
So how should you organize your code? Unfortunately, that’s not something that’s really taught anywhere. My general practice is to follow the recommendations of the language/platform. If they say all code should go in a directory called src/, then that’s where I put it. If every class is supposed to be in its own file, then that’s what I do. And if the platform documentation doesn’t specify how to do something, I’ll find a major open source project and see how they do things. The key to an organization system is to maintain logical consistency. Then, as long as you know the logic, you can figure out where things are or where something should go.
Labeling Systems are basically standard naming practices. In IA, a labeling system specifies what label goes with each element in every context. For programming, you’ll want a consistent naming scheme to make sure the all your code objects are consistently and clearly labeled. Good labels are simple, make sense in context, and hint at the details of the labeled object. The goal is to communicate information efficiently. You are not just writing code for yourself, you’re writing code for the team. The best code is not only functional, it’s readable, concise, and even beautiful. Clear labeling goes a long way towards achieving that ideal.
Navigation and Search Systems are very important to information focused websites, but they don’t apply much to code by itself. However, good Navigation and Search Systems are essential for API documentation. I believe that the quality of the API documentation has a huge effect on the adoption rate of libraries and platforms. [2] Good API docs can be great resource for quickly looking up a function and understanding how to use it. But if a developer can’t navigate and search your API documentation, then how will they figure out how to that function works? Luckily for us programmers, navigation is usually provided for free with a documentation generator. And google can handle the search for you.
While all programming languages have a controlled vocabulary, in IA this refers to domain knowledge. The principle is to use words and jargon that are common to whatever domain you are developing for.
Metadata, in this case, is information about the code, such as comments and documentation. Just as an Information Architect is in charge of the language use within a system, the lead developer should be in charge of the domain language and how to use it.
The goal of IA Research is to understand what needs to be designed and built before doing the work. In programming, you are often presented with problems you’ve never solved before. Hacking, or exploratory programming, is a way to figure out and evaluate possible solutions. Hacking is Research. The goal of research oriented hacking is to figure out possible solutions, evaluate platforms and technologies, and understand the constraints that come with each technology and solution. The knowledge you gather from research is used to drive your strategic choices.
IA Strategy is about platform, process and design. What programming language(s) will you use? What are the core design patterns and architectural choices? What version control system will the team use? How will you track progress? Your strategic decisions will set the design constraints of the implementation and drive the development process.
In software development, the code is the design, but not everyone will want to read your code to understand how things work. You may need to communicate the design in other ways, such as with diagrams, comments, and documentation. And if the code is being written by someone else, then it’s your job to communicate how their code will fit in to the rest of the system. Design documents aren’t for you, they’re for the other people on the team. You do want other team members to understand your code, right? And if your diagrams and documentation are good enough, you might even get business people to think they understand your software too 🙂
Information Architecture provides a top-down view of your software system. As a lead developer or software architect, IA principles and practices can help make sure that your system is well designed and that the design is communicated clearly to all team members. For further reading, I recommend Information Architecture for the World Wide Web and Documenting Software Architectures.
[1] Code = Data, Data = Information, Code = Information.
[2] I wish I had some data to back this up, but it’s certainly how I behave. Lack of clear documentation = fail.
Some say programming is engineering, others call it an art. A few might (mistakenly) think it’s a science. But both the art and engineering can be encapsulated under the umbrella of design. The best design is functional art, and a huge part of the artistic beauty of a product is a result of carefully engineered functionality. Products that are not carefully designed and engineered generally suck to use, and that applies to everything from cameras to software APIs.
There are 4 major principles of graphic design.
The principle of alignment is that everything on a page should be connected to something else on the page. The goal of alignment in graphic design is to create visual associations, often using a grid based layout. In software, we can apply this principle to the connectedness of data, such as the object inheritance hierarchy and relational data structures. Ideally, all your objects fit nicely into a well-defined hierarchy and your data structures relate to each other in an intuitive fashion. Of course, the real world of programming is never as clean as you’d like, but keep this principle in mind whenever you create a new object, add a new dependency, or modify relational structures.
Keeping your objects and data structures neatly aligned will result in easier to understand relations and hierarchies.
The principle of proximity is that related items should be grouped together. Grouping things together is simple way to show relatedness. In software development, that generally means putting related functions into the same module, and related modules into the same package. Helper functions should be located near the functions that call them. Basically, group blocks of code in a logically consistent manner. And if possible, put documentation and tests close to the code too (python’s doctest module provides a great way to do that). One of the major benefits of following this principle is that it reduces the amount of time you’ll spend searching thru and understanding your own code. If all your code is organized in logical groups, and related functions are near each other in the same file, then it’s much easier to find a particular block of code.
The principle of contrast is that if two things are not the same, then make them very different. The goal with contrast is to make different things distinctive from each other. Naming is great place to apply this principle. Names are all you have to distinguish between objects, functions, variables, and modules, so make sure that your names are distinctive and descriptive. Good names can tell you exactly what something is, and even imply its properties and behavior. Use different naming styles for different types of things. Private variables could be prefixed with an underscore, like _private, versus public variables like public, and CamelCase class names, as in MyClassName. Having a distinctive naming style lets you know at a glance whether something is a class, variable, or function, making your code much more readable. Whatever naming style you choose, use it consistently.
The principle of consistency, or repetition, is that you repeat design elements. Repetition helps patterns become internalized and instantly recognizable. For programming, that means keeping a consistent code style, with consistent naming practices. Also, try to use well known standard conventions and protocols, shared libraries, and design patterns. Your code should make sense, or at least be readable, to those familiar with the language and domain. You’re not just writing code for yourself, you might be writing code for other programmers, maybe your manager, but most importantly, you’re writing code for your future self. It always sucks coming back to code you haven’t touched in months and not knowing what the hell is going on. Consistent style and software design can save you from that headache.
If all this seems like obvious common sense to you, then great! But common sense isn’t always so common. The point of this article is make you aware that everyday software programming is filled with design choices. Naming a variable is a design choice. Creating a new module is a design choice. The layout of your working directory is a design choice. Be conscious of these choices and use the above principles and to inform your decisions. The choices you make communicate how the software works and how the code fits together. Make every choice deliberate and justifiable. Use refactoring to improve the design without affecting the functionality.