Top design Questions

List of Tags
665
Bno

It seems to be the general opinion that tables should not be used for layout in HTML.

Why?

I have never (or rarely to be honest) seen good arguments for this. The usual answers are:

  • It's good to separate content from layout
    But this is a fallacious argument; Cliche Thinking. I guess it's true that using the table element for layout has little to do with tabular data. So what? Does my boss care? Do my users care?

    Perhaps me or my fellow developers who have to maintain a web page care... Is a table less maintainable? I think using a table is easier than using divs and CSS.

    By the way... why is using a div or a span good separation of content from layout and a table not? Getting a good layout with only divs often requires a lot of nested divs.

  • Readability of the code
    I think it's the other way around. Most people understand HTML, few understand CSS.

  • It's better for SEO not to use tables
    Why? Can anybody show some evidence that it is? Or a statement from Google that tables are discouraged from an SEO perspective?

  • Tables are slower.
    An extra tbody element has to be inserted. This is peanuts for modern web browsers. Show me some benchmarks where the use of a table significantly slows down a page.

  • A layout overhaul is easier without tables, see css Zen Garden.
    Most web sites that need an upgrade need new content (HTML) as well. Scenarios where a new version of a web site only needs a new CSS file are not very likely. Zen Garden is a nice web site, but a bit theoretical. Not to mention its misuse of CSS.

I am really interested in good arguments to use divs + CSS instead of tables.

Answered By: Konrad Rudolph ( 498)

I'm going to go through your arguments one after another and try to show the errors in them.

It's good to separate content from layout But this is a fallacious argument; Cliché Thinking.

It's not fallacious at all because HTML was designed intentionally. Misuse of an element might not be completely out of question (after all, new idioms have developed in other languages, as well) but possible negative implications have to be counterbalanced. Additionally, even if there were no arguments against misusing the <table> element today, there might be tomorrow because of the way browser vendors apply special treatment to the element. After all, they know that “<table> elements are for tabular data only” and might use this fact to improve the rendering engine, in the process subtly changing how <table>s behave, and thus breaking cases where it was previously misused.

So what? Does my boss care? Do my users care?

Depends. Is your boss pointy-haired? Then he might not care. If she's competent, then she will care, because the users will.

Perhaps me or my fellow developers who have to maintain a web page care... Is a table less maintainable? I think using a table is easier than using divs and css.

The majority of professional web developers seem to oppose you[citation needed]. That tables are in fact less maintainable should be obvious. Using tables for layout means that changing the corporate layout will in fact mean changing every single page. This can be very expensive. On the other hand, judicious use of semantically meaningful HTML combined with CSS might confine such changes to the CSS and the pictures used.

By the way... why is using a div or a span good separation of content from layout and a table not? Getting a good layout with only divs often requires a lot of nested divs.

Deeply nested <div>s are an anti-pattern just as table layouts. Good web designers don't need many of them. On the other hand, even such deep-nested divs don't have many of the problems of table layouts. In fact, they can even contribute to a semantic structure by logically dividing the content in parts.

Readability of the code I think it's the other way around. Most people understand html, little understand css. It's simpler.

“Most people” don't matter. Professionals matter. For professionals, table layouts create many more problems than HTML + CSS. This is like saying I shouldn't use GVim or Emacs because Notepad is simpler for most people. Or that I shouldn't use LaTeX because MS Word is simpler for most people.

It's better for SEO not to use tables

I don't know if this is true and wouldn't use this as an argument but it would be logical. Search engines search for relevant data. While tabular data could of course be relevant, it's rarely what users search for. Users search for terms used in the page title or similarly prominent positions. It would therefore be logical to exclude tabular content from filtering and thus cutting the processing time (and costs!) by a large factor.

Tables are slower. An extra tbody element has to be inserted. This is peanuts for modern web browsers.

The extra element has got nothing to do with tables being slower. On the other hand, the layout algorithm for tables is much harder, the browser often has to wait for the whole table to load before it can begin to layout the content. Additionally, caching of the layout won't work (CSS can easily be cached). All this has been mentioned before.

Show me some benchmarks where the use of a table significantly slows down a page.

Unfortunately, I don't have any benchmark data. I would be interested in it myself because it's right that this argument lacks a certain scientific rigour.

Most web sites that need an upgrade need new content (html) as well. Scenarios where a new version of a web site only needs a new css file are not very likely.

Not at all. I've worked on several cases where changing the design was simplified by a separation of content and design. It's often still necessary to change some HTML code but the changes will always be much more confined. Additionally, design changes must on occasion be made dynamically. Consider template engines such as the one used by the WordPress blogging system. Table layouts would literally kill this system. I've worked on a similar case for a commercial software. Being able to change the design without changing the HTML code was one of the business requirements.

Another thing. Table layout makes automated parsing of websites (screen scraping) much harder. This might sound trivial because, after all, who does it? I was surprised myself. Screen scraping can help a lot if the service in question doesn't offer a WebService alternative to access its data. I'm working in bioinformatics where this is a sad reality. Modern web techniques and WebServices have not reached most developers and often, screen scraping is the only way to automate the process of getting data. No wonder that many biologists still perform such tasks manually. For thousands of data sets.

I am a n00b in this kind of stuff but lately I've been hearing a lot about how good NodeJS is. Considering how much I love working with jQuery and Javascript in general, I can't help but wonder how to decide when to use NodeJS. The web application I have in mind is something like bit.ly - takes some content, archives it.

From all the homework I have been doing in the last few days, I obtained the following information. NodeJS

  • is a command-line tool that can be run as a regular web server and lets one run Javascript programs
  • utilizes the great V8 JS engine
  • is very good when you need to do several things at the same time
  • is event-based so all the wonderful Ajax like stuff can be done on the server side
  • lets us share code between the browser and the backend
  • lets us talk with MySQL

Some of the sources that I have come across are:

Considering that NodeJS can be run almost out-of-the-box on Amazon's EC2 instances, I am trying to understand what type of problems require NodeJS as opposed to any of the mighty kings out there like php, python and ruby. I understand that it really depends on the expertise one has on a language but my question falls more into the general category of: When to use a particular framework and what type of problems is it particularly suited for?

Any suggestions?

Answered By: Benson ( 240)

You did a great job of summarizing what's awesome about node. My feeling is that node is especially suited for applications where you'd like to maintain a persistent connection from the browser back to the server. Using a technique known as "long-polling", you can write an application that sends updates to the user in real time. Doing long polling on many of the web's giants, like rails or django, would create immense load on the server, because each active client eats up one server process. This situation amounts to a tarpit attack. When you use something like node, the server has no need of maintaining separate threads for each open connection.

This means you can create a browser-based chat app in node that takes almost no system resources to serve a great many clients. Any time you want to do this sort of long-polling, node is a great option.

It's worth mentioning that ruby and python both have tools to do this sort of thing (eventmachine and twisted, respectively), but that node does it exceptionally well, and from the ground up. JavaScript is exceptionally well situated to a callback-based concurrency model, and it excels here. Also, being able to serialize and deserialize with json native to both the client and the server is pretty nifty.

I look forward to reading other answers here, this is a fantastic question.

Edit: It's worth pointing out that node is also great for situations in which you'll be reusing a lot of code across the client/server gap. The (currently brand new) meteor framework makes this really easy, and a lot of folks are suggesting this might be the future of web development. I can say from experience that it's a whole lot of fun to write code in meteor, and a big part of this is spending less time thinking about how you're going to restructure your data so the code that runs in the browser can easily manipulate it and pass it back.

Edit: Here's an article on Pyramid and long-polling, which turns out to be very easy to set up with a little help from gevent: TicTacToe and Long Polling with Pyramid

281
Kristian D&#39;Amato

In a certain sense, I'm still very much a beginner, but I don't need to read C++ Primer or Learn C++ in 21 Days, or at least, I only take a peek every now and then for reference's sake. So what is my problem?

Basically, I started to write a small game to help my process of learning. Along the way, I've learned most of anything that you need to know to be called 'fluent' in C++. I know all about overloading, templates, exceptions, RTTI, polymorphism, etc. I've also taken another small step forward and started using the STL and its containers and algorithms. Recently I started reading about the Boost library. I also read some good material about design patterns and actually applied a couple of ideas to this game of sorts.

But now the whole thing has ground to a stop after about 3k lines of code. Why? It's not that I don't know the language or don't have the ideas. But knowing the vocabulary and having the ideas does not make one a novelist. Even knowing how to write sentences is not enough. You have to understand flow, structure, and all the rest to write a successful novel.

In my practical case, I'm tending to waste a lot of time structuring the code so as to work properly, e.g. I'm losing track of whether to send a certain kind of event before another. The program obviously compiles fine, but the runtime behaviour may not be exactly as intended. I'm also losing track of who owns what, who should take care of what, and so forth. Maybe I'm not strong enough when it comes to algorithms, or maybe the culprit is object oriented design - I'm not sure.

The truth is that the code is starting to look a lot like a chaotic mess, not so much in terms of the actual appearance of the code as in terms of the ideas themselves and their interrelation. The maintenance time has become too much already.

Anyway, sorry for the longish post, but I was wondering what to learn next. I've had a look at the books thread on SO, which is wonderful, but I was hoping for a rather more specific direction. I need to spend less time on the rewriting and more on the actual writing.

Answered By: Kylotan ( 131)

Ok, I have 2 answers for you - pick the one that is most relevant.

Firstly, to successfully finish your app, you need domain specific information. This isn't about C++ any more. If you're programming games, you need to read more about how games actually do it. Otherwise it's like trying to write a crime novel having memorised a dictionary and a grammar guide, to continue the analogy. It's not just about flow and structure - those are still fairly low-level concepts. You need to examine how people approach the genre and then from there you can pick out the types of flow and the structures you will need with more confidence. Messy code is often just as much about not fully understanding the specification as it is about not knowing how to program effectively. Knowing the domain helps you pin down clear and well-understood solutions.

I recommend the Game Coding Complete (3rd ed) book by Mike McShaffrey for a good insight into the overall approach to making a game. I have also heard good things about Game Engine Architecture by Jason Gregory but I haven't read it myself. Note that both of these books are quite complex and focused on industrial-strength solutions. If you don't need an industrial-strength solution, you might ask yourself why you're using C++ to write a game when other languages are more suitable for rapid development. Flash is a good choice, for example.

Which leads me on to my second answer: code something you actually care about. If you're only using the game project as a vehicle for learning the language, chances are high that you lost interest as you reached the point where you stopped learning new things about the language and had to start worrying about things specific to games that are more about rearranging the concepts that you already know. This is typically the point where learning is something you should be incorporating into practical solutions rather than something you have to force yourself to do purely for pedagogical reasons. We learn best when the task is interesting.

What is a good way to design/structure large functional programs, especially in Haskell?

I've been through a bunch of the tutorials (Write Yourself a Scheme being my favorite, with Real World Haskell a close second) - but most of the programs are relatively small, and single-purpose. Additionally, I don't consider some of them to be particularly elegant (for example, the vast lookup tables in WYAS).

I'm now wanting to write larger programs, with more moving parts - acquiring data from a variety of different sources, cleaning it, processing it in various ways, displaying it in user interfaces, persisting it, communicating over networks, etc. How could one best structure such code to be legible, maintainable, and adaptable to changing requirements?

There is quite a large literature addressing these questions for large object-oriented imperative programs. Ideas like MVC, design patterns, etc. are decent prescriptions for realizing broad goals like separation of concerns and reusability in an OO style. Additionally, newer imperative languages lend themselves to a 'design as you grow' style of refactoring to which, in my novice opinion, Haskell appears less well-suited.

Is there an equivalent literature for Haskell? How is the zoo of exotic control structures available in functional programming (monads, arrows, applicative, etc.) best employed for this purpose? What best practices could you recommend?

Thanks!

EDIT (this is a follow-up to Don Stewart's answer):

@dons mentioned: "Monads capture key architectural designs in types."

I guess my question is: how should one think about key architectural designs in a pure functional language?

Consider the example of several data streams, and several processing steps. I can write modular parsers for the data streams to a set of data structures, and I can implement each processing step as a pure function. The processing steps required for one piece of data will depend on its value and others'. Some of the steps should be followed by side-effects like GUI updates or database queries.

What's the 'Right' way to tie the data and the parsing steps in a nice way? One could write a big function which does the right thing for the various data types. Or one could use a monad to keep track of what's been processed so far and have each processing step get whatever it needs next from the monad state. Or one could write largely separate programs and send messages around (I don't much like this option).

The slides he linked have a Things we Need bullet: "Idioms for mapping design onto types/functions/classes/monads". What are the idioms? :)

Answered By: Don Stewart ( 203)

I talk a bit about this in Engineering Large Projects in Haskell and in the Design and Implementation of XMonad. Engineering in the large is about managing complexity. The primary code structuring mechanisms in Haskell for managing complexity are :

The type system

  • Use the type system to enforce abstractions, simplifying interactions.
  • Enforce key invariants via types
    • (e.g. that certain values cannot escape some scope)
    • That certain code does no IO, does not touch the disk
  • Enforce safety: checked exceptions (Maybe/Either), avoid mixing concepts (Word,Int,Address)
  • Good data structures (like zippers) can make some classes of testing needless, as they rule out e.g. out of bounds errors statically.

The profiler

  • Provide objective evidence of your programs heap and time profiles.
  • Heap profiling, in particular, is the best way to ensure no uneccessary memory use.

Purity

  • Reduce complexity dramatically by removing state. Purely functional code scales, because it is compositional. All you need is the type to determine how to use some code -- it won't mysteriously break when you change some other part of the program.
  • Use lots of "model/view/controller" style programming: parse external data as soon as possible into purely functional data structures, operate on those structures, then once all work is done, render/flush/serialize out. Keeps most of your code pure

Testing

  • QuickCheck + Haskell Code Coverage, to ensure you are testing the things you can't check with types.
  • GHC +RTS is great for seeing if you're spending too much time doing GC.
  • QuickCheck can also help you identify clean, orthogonal APIs for your modules. If the properties of your code are difficult to state, they're probably too complex. Keep refactoring until you have a clean set of properties that can test your code, that compose well. Then the code is probably well designed too.

Monads for Structuring

  • Monads capture key architectural designs in types (this code accesses hardware, this code is a single-user session, etc .)
  • E.g. the X monad in xmonad, captures precisely the design for what state is visible to what components of the system.

Type classes and existential types

  • Use type classes to provide abstraction: hide implementations behind polymorphic interfaces.

Concurrency and paralleism

  • Sneak par into your program to beat the competition with easy, composable parallelism.

Refactor

  • You can refactor in Haskell a lot. The types ensure your large scale changes will be safe, if you're using types wisely. This will help your codebase scale. Make sure that your refactorings will cause type errors until complete.

Use the FFI wisely

  • The FFI makes it easier to play with foreign code, but that foreign code can be dangerous.
  • Be very careful in assumptions about the shape of data returned.

Meta programming

  • A bit of Template Haskell or generics can remove boilerplate.

Packaging and distribution

  • Use Cabal. Don't roll your own build system.
  • Use Haddock for good API docs
  • Tools like graphmod can show your module structures.
  • Rely on the Haskell Platform versions of libraries and tools, if at all possible. It is a stable base.

Warnings

  • Use -Wall to keep your code clean of smells. You might also look at Agda, Isabelle or Catch for more assurance. For lint-like checking, see the great hlint, which will suggest improvements.

With all these tools you can keep a handle on complexity, removing as many interactions between components as possible. Ideally, you have a very large base of pure code, which is really easy to maintain, since it is compositional. That's not always possible, but it is worth aiming for.

In general: decompose the logical units of your system into the smallest referentially transparent components possible, them implement them in modules. Global or local environments for sets of components (or inside components) might be mapped to monads. Use algebraic data types to describe core data structures. Share those definitions widely.

206
Chris Ballance

Some of us just have a hard time with the softer aspects of UI design (myself especially). Are "back-end coders" doomed to only design business logic and data layers? Is there something we can do to retrain our brain to be more effective at designing pleasing and useful presentation layers?

Colleagues have recommended a few books me including The Design of Sites, Don't make me think and Why Software sucks , but I am wondering what others have done to remove their deficiencies in this area?

Answered By: Thorsten79 ( 362)

Let me say it directly:

Improving on this does not begin with guidelines. It begins with reframing how you think about software.

Most hardcore developers have practically zero empathy with users of their software. They have no clue how users think, how users build models of software they use and how they use a computer in general.

It is a typical problem when an expert collides with a laymen: How on earth could a normal person be so dumb not to understand what the expert understood 10 years ago?

One of the first facts to acknowledge that is unbelievably difficult to grasp for almost all experienced developers is this:

Normal people have a vastly different concept of software than you have. They have no clue whatsoever of programming. None. Zero. And they don't even care. They don't even think they have to care. If you force them to, they will delete your program.

Now that's unbelievably harsh for a developer. He is proud of the software he produces. He loves every single feature. He can tell you exactly how the code behind it works. Maybe he even invented an unbelievable clever algorithm that made it work 50% faster than before.

And the user doesn't care.

What an idiot.

Many developers can't stand working with normal users. They get depressed by their non-existing knowledge of technology. And that's why most developers shy away and think users must be idiots.

They are not.

If a software developer buys a car, he expects it to run smoothly. He usually does not care about tire pressures, the mechanical fine-tuning that was important to make it run that way. Here he is not the expert. And if he buys a car that does not have the fine-tuning, he gives it back and buys one that does what he wants.

Many software developers like movies. Well-done movies that spark their imagination. But they are not experts in producing movies, in producing visual effects or in writing good movie scripts. Most nerds are very, very, very bad at acting because it is all about displaying complex emotions and little about analytics. If a developer watches a bad film, he just notices that it is bad as a whole. Nerds have even built up IMDB to collect information about good and bad movies so they know which ones to watch and which to avoid. But they are not experts in creating movies. If a movie is bad, they'll not go to the movies (or not download it from BitTorrent ;)

So it boils down to: Shunning normal users as an expert is ignorance. Because in those areas (and there are so many) where they are not experts, they expect the experts of other areas to have already thought about normal people who use their products or services.

What can you do to remedy it? The more hardcore you are as a programmer, the less open you will be to normal user thinking. It will be alien and clueless to you. You will think: I can't imagine how people could ever use a computer with this lack of knowledge. But they can. For every UI element, think about: Is it necessary? Does it fit to the concept a user has of my tool? How can I make him understand? Please read up on usability for this, there are many good books. It's a whole area of science, too.

Ah and before you say it, yes, I'm an Apple fan ;)

I have been looking at game engine design (specifically focused on 2d game engines, but also applicable to 3d games), and am interested in some information on how to go about it. I have heard that many engines are moving to a component based design nowadays rather than the traditional deep-object hierarchy.

Do you know of any good links with information on how these sorts of designs are often implemented? I have seen evolve your hierarchy, but I can't really find many more with detailed information (most of them just seem to say "use components rather than a hierarchy" but I have found that it takes a bit of effort to switch my thinking between the two models).

Any good links or information on this would be appreciated, and even books, although links and detailed answers here would be preferred.

Answered By: lambdor ( 167)

We did some research on CBSE in games at our university and I collected some material over the years:

CBSE in games literature:

  • Game Engine Architecture
  • Game Programming Gems 4: A System for Managin Game Entities Game
  • Game Programming Gems 5: Component Based Object Management
  • Game Programming Gems 5: A Generic Component Library
  • Game Programming Gems 6: Game Object Component System
  • Object-Oriented Game Development
  • Architektur des Kerns einer Game-Engine und Implementierung mit Java (german)

A very good and clean example of a component-based game-engine in C# is the Elephant game framework.

If you really want to know what components are read: Component-based Software Engineering! They define a component as:

A software component is a software element that conforms to a component model and can be independently deployed and composed without modification according to a composition standard.

A component model defines specific interaction and composition standards. A component model implementation is the dedicated set of executable software elements required to support the execution of components that conform to the model.

A software component infrastructure is a set of interacting software components designed to ensure that a software system or subsystem constructed using those components and interfaces will satisfy clearly defined performance specifications.

My opinions after 2 years of experience with CBSE in games thought are that object-oriented programming is simply a dead-end. Remember my warning as you watch your components become smaller and smaller, and more like functions packed in components with a lot of useless overhead. Use functional-reactive programming instead. Also take a look at my fresh blog post (which lead me to this question while writing it :)) about Why I switched from component-based game engine architecture to FRP.

CBSE in games papers:

CBSE in games web-links (sorted by relevancy):