11

There are many things that need to be considered when making a system, let's take for example a web based system where users log in and interact with each other, creating and editing content. Now I have to think about security, validation (I don't even think I am 100% sure what that entails), "making sure users don't step on each others feet" (term for this?), preventing errors in many cases, making sure database data doesn't become problematic through unexpected... situations? All these things I don't know how or where to learn, is there a book on this kind of stuff? Like I said there seems to be a huge difference between writing code and actually writing the right code, know what I mean? I feel like my current programming work lacks much of what I have described and I can see the problems it causes later, and then the problems are much harder to solve because data exists and people are using it. So can anyone point me to books or resources or the proper subset of programming(?) for this type of learning?

PS: feel free to correct my tags, I don't know what I am talking about.

Edit: I assume some of the examples I wrote apply to other types of systems too, I just don't know any other good examples because I've been mostly involved in web work.

6 Answers 6

10

As far as I can tell, professional programmers learn these things three main ways:

  1. Learning from a bad experience - You run across something wrong. You fix it. You say, "Hey, I shouldn't do that again. Next time I'll do X." You're clearly in the thick of that.
  2. Learning before a bad experience - Eventually, you learn to see certain sorts of problems coming. When you do, you'll try to avoid it. Maybe you read a book, maybe you search the web, maybe you try some experiments.
  3. Learning from experienced colleagues - This by far the easiest, although it's still not easy. The trick is figuring out whether the colleague is responding to a bad experience that's still relevant. Technology moves on, after all.

I'd encourage you to shoot for all three. Find a place with smart, experienced colleagues who will put up with your questions. Make sure it's a place that lets you ship early and often, so that you can try a lot of things. And take time for research and reflection.

2
  • As to #1), bear in mind that the bad experiences and mistakes you're learning from don't necessarily need to be your own. Spend time on the web, hang out where programmers do, learn some of their horror stories of crazy mistakes they've made or come across, keep them in the back of your head as you program.
    – Shadur
    Mar 17, 2011 at 9:17
  • 1
    I'd agree, Shadur, but I think some of the bad experiences really do need to be your own. Some people try to sit on the sidelines, waiting until they can make the perfect thing. But they really need to just get in there and start making if they want to improve their skills. Mar 17, 2011 at 19:05
4

When it comes to web apps, there is more good info compiled in this answer than any other single place I've ever seen.

But the reality is, there is a lot to know to put together a complete system well. There are studies to support 10,000 hours as the amount of practice that is necessary to reach a level of mastery, and developing information systems is no exception to that.

2
  • So I guess it's different for different things then, eh?
    – MetaGuru
    Mar 16, 2011 at 1:07
  • Many issues will be, say, specific to web apps and many will be more general. Not sure I entirely understand what you're asking tho. Mar 16, 2011 at 1:17
3

I like William Pietri's answer a lot (+1), but I believe it needs to be added to. Even presuming that what you mean by systems comprises solely of software.

But before I go into the meat of it, I don't know of a book to help. All that which follows, I learnt from experience (meaning the three points that William made).

What you are talking about spans at a minimum four broad roles. Sometimes one person might fill in all those roles, for small to medium sized projects, but when you start on large projects you need to at least somewhat separate those roles out. It is difficult for anyone to be expert at them all in any meaningful way.

  1. Business analyst

    That's the person who talks to the customer and translates their requirements into something an architect can make sense of. Basically a list of properly formulated requirements. This includes the obvious functional requirements (what must this system deliver?), but also non-functional requirements (what are the general characteristics that the system must fulfil? This may include security, reliability, availability, resilience, capacity, performance, robustness and other such requirements from a user point of view).

    This is the first pass at what the system must do, the very start of serious thinking.

  2. System architect

    This person produces the high level technical framework within which to work. They give the outline match plan. The general tools, techniques, constructs. They break down the whole system into smaller components, how they fit with one another, how they fit with the outside world...

    This helps in many ways refine what needs to be thought about. Very often problems will be discovered at that stage about the requirements as written by the business analyst. Back to them for some iterations to improve their understanding of what they want and their expression of it.

  3. System designer

    This role is about how to make it all work. This might be more team work than a one-man show. But there is likely a lead designer to oversee the whole system design. This person must dig into the detail and make sure the architect's view is something that can actually be built.

    Expect further refining of the architecture of the system, and therefore potentially of the business analysis.

  4. Tests manager

    This role is very often forgotten. But at the end of the day if you can't test it, how can you prove that you can build it? There must be a review of the results of all stages : business analysis, architecture and design by someone competent in testing who will be able to highlight deficiencies and therefore enable early corrections, way before any code gets written.

That's a short summary.

Those guys/gals are only the general run of the mill people in the chain to think about what must be thought about.

For complex projects such as large banking or space applications just to take two examples (think many hundreds to many thousands of man-days), there are many subject matter experts as we call them to review and support projects at every stage. These roles include security analysis, system sizing, capacity, performance, databases, clustering, and many other such narrow areas of expertise, including precise business areas. The variety of roles depends on the size and complexity of systems.

All that to say that you should not try and know it all, you won't. You can however get a grasp of the overall picture and on small projects you can delve into much more than on large projects, simply because the level of complexity allows you to be more rounded.

If you want to know how to design systems, then you need to start asking questions by thinking outside the box. Put yourself enough in the customer's shoes and try and think what could go wrong, what needs testing. Then get together with a real customer and push them to explain the extents and limits of the system they envision they need. Plus whenever I say 'customer', you must understand that this encompasses several very different people. There's the person who uses the system day in day out for what it was designed to do. There's the operator, technical support, the manager who needs some report or other, the auditor, the infrastructure team, the stakeholder who paid for it, the quality manager who needs means to test your system... Ask all of them (and if they are one person, ask them to put all these hats on one at a time), so ask them all what they need and you will have a good start at knowing what your system requirements are. From there you can derive the architecture, and from there the design.

For complex systems (whether software only or to integrate with hardware in the most generic sense) not only is one person not enough for each of the four roles I listed above, but you need to project-manage even the definition of what the system must do, let alone the other phases.

HPH, asm.

2

here to learn, is there a book on this kind of stuff?

Not "a book". A lot of books.

There's no royal road

Like I said there seems to be a huge difference between writing code and actually writing the right code

Right.

You're talking about "architecture", programming in the large.

Step 1. Read a lot of code. A real lot. Think of things you'd like to do. Find related open source projects. Read the code. All of it.

Step 2. Read more code. A lot more.

Step 3. Read books on architecture.

6
  • 2
    Read, read, read. But I have to suggest it's just not the same as what you learn when you actually implement real systems. Mar 16, 2011 at 1:15
  • @qes: The question was "where do you learn how to make systems properly?" You don't learn that by building real systems badly. Indeed, implementing real systems badly is the exact opposite of learning.
    – S.Lott
    Mar 16, 2011 at 1:39
  • 3
    From Code Complete, one of the things I liked best: "The software-engineering field makes extraordinarily limited use of examples of past successes and failures. If you were interested in architecture you'd study the drawings of [famous architects]... visit some buildings...".
    – Jacob
    Mar 16, 2011 at 2:16
  • @S.Lott: who said anything about doing it badly? Mar 16, 2011 at 3:17
  • @qes: without reading prior art, what are the odds of doing a large-scale program well? For a genius like yourself, it's possible that one might simply write good programs at all times and all scales. But for everyone else who hasn't looked at large scale programming, starting out by trying to implement a large system without having read anything is a path toward writing something that contains so many mistakes that nothing useful can be learned from it. Your experience may be different, but I know that I'm not smart enough to work without reading first.
    – S.Lott
    Mar 16, 2011 at 9:51
1

To amplify read lots of books....

Now you know you have a problem, there is some point in telling you to read these books. (Before you've done some real work, there is little point in discussing these books)

Design Patterns by Gamma,Helm,Johnson and Vlissides Pattern Languages of Program Design 1,2,3 and 4.

But don't try to apply every patter everywhere you see it could be used

that is a bad thing too.

Hope this helps.

1

The best way to learn how to do anything is to do it. If you want to learn how to speak French, you have to speak French, and read French and write French and read about French and go to France and talk to French people in French. If you want to know how to play the piano, you have to actually play the piano. You have to play simple songs and learn the structure of the piano, and the structure of music. You have to learn how to read music, and how to express music through a piano using your fingers. You have to learn what music sounds like and what kinds of sounds a piano can make versus what a guitar or a flute or a saxophone can do.

Programming is exactly the same. If you to know how to design a database, you have to design databases. If you want to understand cryptography, implement cryptographic algorithms and cryptographic protocols. If you want to write software that can serve multiple users simultaneously you have to understand how disk IO, network IO and threads work. To understand how that works you have write code that reads and writes from files, transmits data across a network, and synchronizes access to resources. All of that requires practice.

A "system" is, generally, just a collection of stuff. Pieces that coordinate to form a whole. To build something big, you have to build a bunch of small parts. So, if you want to learn how to build systems, just start building systems. Take a problem, break down into pieces, and implement each piece one by one. Eventually you'll have an integrated "system". You'll probably fail a few times along the way, but that's ok. If you aren't failing it usually means you aren't trying hard enough.

Also, I would recommend going to school to study Computer Science. That won't help too much with the "practice" part. You'll have to do that on your own, but it will help with the exposure part. You'll learn a lot, about pretty much everything related to how computers, and computer systems work, which is hard to learn on your own.

1
  • 1
    +1, Though I would suggest that just doing isn't enough. You won't know whether you have done it well or badly until you revisit the same code after some time has passed. And even then, you may know something is wrong, but not how it can be improved. One way to short-cut all of that is to ensure lots of promtp feedback from people more experienced on what you are trying to learn. So yes, "do" is very important, but feedback on what you do possibly even more so to speed up the learning process. Mar 16, 2011 at 7:04

Not the answer you're looking for? Browse other questions tagged or ask your own question.