Programming practice - language-agnostic

I've decided to get some experience working on some project this summer.
Due to local demand on market I would prefer to learn Java (Standard and Enterprise Editions).
But I can't even to conjecture what kind of project to do. Recently I had some ideas about C. With C I could to contribute to huge Linux projects. I don't mean that my work will be surely commited. I could get the code and practice with it. But C it's not right thing to get good job in my area. In case of JavaSE there is a chance to develop some desktop applications. But thinking about JavaEE I get stuck. I'll be very thankful for answers.

CodingBat.com will give you good core Java practice.
Project Euler is still the best for all around practice. You can use whatever language you'd like to solve the problems there.
For actual projects, I almost always start on something easy like a Twitter client. It gets you exposure to all the basics along with UI and network communication. You can work up from there. Just don't start with something so overwhelming that you can't figure it out and want to give up. That's not going to get you anywhere.

The best advice is: work on a project that you have personal interest in. Something based on your hobbies, maybe.
If that doesn't work, make a blogging / CMS engine. Or an online photo album. Or an eStore. The world doesn't really need another of any of these things, but it will give you some good practical experience with JavaEE.
Another benefit of "re-inventing the wheel" (for learning) is that you have probably already used systems like these described above, and you have a good idea of how it can work, and maybe you have your own ideas of how it could work better. That can make requirements much simpler, and also will give you a sort of benchmark so you can see how close you can come to building a tool like the "real" ones out there. And if yours is really great, well, maybe release it and see what happens. ;)

There are many Java-based projects on SourceForge. Tinker with one you find interesting.

I've implemented either a betting pool or a Baccarat game in almost every language I've
learned.
This type of software covers:
Dates and times, with calculations
Currency types and things that can be converted to and from currency.
A discrete set of rules that is easy to test
States, transition between states and multiple entities responsible for state transition
Multiple users with different views of the same model End conditions
Multiple player blackjack and poker would work also.
One caveat is that in my day job I work on financial systems and there is a huge overlap
between things to consider when writing a multiplayer game of chance and a trading system.

build an address book. the concept is simple, so you're not stuck on "what" to write. You can focus on learning your chosen language. You get experience in working with a database, java ( insert any language here), and UI design.
when you decide to learn another language you can create the same thing. Since the database has been created already, you can focus on the language itself.
the concept of inputting data, storing data, and retrieving data is central to a lot of applications.

Have a look around http://openhatch.org/ for a project that sounds interesting.

Related

web site development best practices, design or code by first?

I'm using an MVC framework to develop a web site, I've to care about the design in the sense of look and feel (views) and the code (models, controllers).
I don't know what is the best way to proceed:
code and design iteratively by small chunks?
design first ?
you've got the point
I suggest you design first - it can be a rough design with a pencil/paper but it will give you an idea of what information should go on the page in what manner. This will help you with your views and controller logic. Dont' worry too much about colours at this point.
I always feel it is better to do things iteratively. Design a page or two, construct the model and controller relative to that page, and repeat for other pages.
Sometimes if you spend too long in your models and controllers and neglect your views, you'll end up doing way more or way less than what you need.
The 37 Signals (the source or Ruby on Rails and some really cool web apps) book Getting Real advocates working from the interface down. It gives you a better sense of how the site will be used before you do too much back end implementation.
Here is the specific chapter: From ideas to implementation.
PS: Read the whole book, it's brief and a really good overall philosophy for building things the way they should be build. And no I am not affiliated with them in any way.
One small, but very good tip I got, was to work out what kind of 'friendly' URL's you would like to see in your site. This in turn leads you to what routes your require, which in turn gives you an idea of the controllers and actions you will have to create.
It depends but there are several rules of thumb:
the bigger the project the more it benefits from the design first, design well approach.
if there's inter-dependence between the elements of the project - such as lots of foreign keys in the database - you are better off at the very least designing everything around those inter-dependencies, or you're gonna regret it later
MVC frameworks enforce some design decisions by their very nature, so use that to help you
beyond a certain size - say more than a week's work - it's an absolute necessity. Same goes if it's a team effort
In your particular case, since I'm not sure about the project size, I'd suggest having your schema designed ahead based on your needs, which will tell you about dependencies, and then do the iterative thing, starting with the dependencies.
If you have specific APIs you have in mind, it's a good idea to design around those as well
The beauty of MVC frameworks is it simply does not matter.
Obviously you'll need some vision to work to, but it's up to yourself. I'm a strong believer in iterative development. In this case you'd create a section of the site, views, models and so forth. Once that was working, move to the next section/feature of the site.
The both ways are OK but it would be better if you have a designed view (even a mock up) so you can know what data to get how to format it when you develop you model and controllers
My suggestion which will save you a lot of time and headache is start off with design.
You have two designs here. One is the UI (interface) design. All the visuals etc.
When you have a UI design you will know how to create your mark-up from the get go without having to do the work twice after you've completed a design.
The other is the software design. the MVC framework helps a lot with this but you also don't want to just start coding without having a plan. You'll find yourself back tracking a lot and recoding stuff you've already done that way.
An iterative approach is the way to go. I might suggest spending time on the model and getting it solidified first. Then, iterate through your controllers and views. This will help validate what you've done in the model, and bring up any glaring issues that need to be addressed sooner vs. later.
I, as most here would say design (at least to a extent) first.
I would wireframe interactions (these can, and should be be refined later) and, perhaps most important, (at least if it's a traditional web site you're working on) plan the architecture, map the structure of the site you're working on (the Information Architecture part). In order to get an overview of the site and know map out user paths through the content.
That's at least my 'modus operandi' for web sites if I'm working alone on them.
(I mostly work in a UX team so my professional workflow is more in the design part than production coding nowadays)
Understanding the Requirements
Database Design
User Interface Design
Business Logic Design
From my experience I would say you should always plan first. (I even plan my planning phase).
I assume you’re doing something like a GUI wired up via .aspx using the MVC model, maybe even the Entity Framework?
Web development like this can very easily get complicated once you start to build it up.
It is important that before you do anything you know exactly what it is that you are trying to do, this way you know when you are undershooting or overshooting your goals and whether or not the code you are writing actually fulfils the requirements.
There are many models which you can base your project development on, all of which loosely follow a sensible System Development Life Cycle in one way or another.
If you haven’t read up on the different development methodologies, here’s a site that will give you a good overview : http://www.itinfo.am/eng/software-development-methodologies/

Beyond simple coding: Where to go from here? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I've been coding since my early teenager years. I started out with HTML, went on to PHP/MySQL (created my own forums, social networking sites, etc..) and then branched out into more traditional languages such as Java and C++ (also picked up a little VB .NET in high school). I'm most familiar now with C++ as that is the language of choice taught to us in Computer Science II (skipped Comp Sci I) at RPI. I now feel like I have a very good knowledge of how to program from this class (the homework assignments were brutal).
It is now summer and I am interning at a company that is providing me some level of new experiences with programming, but I want more. I want to feel the incredible satisfaction that I got out of my computer classes at RPI whenever I finished a long assignment (generating every possible wordsearch from a set of words to include and exclude comes to mind).
My question is, where do I go from here? I tried following a tutorials online, but they were all too simple. I then tried heading over to sourceforge and helping out with various projects. But, as soon as I downloaded the code I got lost in its complexity. I have never created actual software of a real life applicapable scale. And I don't know where to get started. How do you transition from programming knowledge to actuall creation of software?
I'm also open to learning new languages (javascript/jQuery, ASP .NET, C#, Python), or using new libraries and/or frameworks with c++ (we only used the STL in Comp Sci II) and other languages. Again my question is, where do I go from here? And I am welcome to all possible answers.
Thanks Much,
Michael
You could join a big open source project, you'll learn a lot and accomplish something cool.
EDIT after comment: If this is too complicated for you, try starting a "real" project. I say "real" because it should be something that you want to do, not a "create a blog" or "how to do a loop". For instance last year I created a fully functional project management system that I now use for some of my projects. If this is real, you will be more motivated and you will want to get this done.
Pick the technology you want for it. I'd recommend Ruby on Rails because it's awesome and full of interesting concepts that will improve the way you code overtime (DRY, RESTful, MVC...)... but you can pick whatever you want.
Try to create your project using what you know and basic tutorials. You will get stuck and have to learn some more in order to get the features you want going. To me that's the best way to improve the way you code and general programming knowledge.
Since you'll start the project from scratch, you'll see where to start and how this will evolve. I'll take the project management tool. We started with "A project has todos" and we ended up with all kind of other features such as a complex calendar, a full ajax interface, a embedded chat...
Once you see how you did this, try doing the same with a friend of yours to get a fealing of teamwork in development. Learn how to use SVN, basecamp... learn about software development processes (Agile!), peer programming..
There's a lot to experience! Then you could give open source another try.
Hope that helps
I'd recommend trying a pure functional language, such as Haskell. It's a completely different way of looking at programming, and I found it very satisfying.
I recommend the book Real World Haskell for learning it.
Edit: In response to comments, my interpretation of the question is where can he go from here as a programmer. Functional programming is a logical direction. For someone learning functional programming for the first time, Haskell is nice because it doesn't really allow for imperative programming practices. Furthermore, it has basically all features you will find in other functional languages, which means it will be easy to pick up other functional languages.
I would suggest looking at Project Euler. It's a great and fun way to learn a new language, and it does provide that level of satisfaction when you solve the problems. They offer a huge range of problems at all levels of difficulty.
I think the best way to improve your skills as a programmer is to do what programming was intended for: solve problems. I'm sure you've been playing around on your machine and at one time thought to yourself "I wish there was a program that did this..." or "I wonder if there are any programs that do X..." Instead of just googling to see if someone else wrote it, write it yourself. Start with something small, and gradually make it more complex. Add features. Allow yourself to fail, and when you do, ask yourself (or us at stackoverflow) how to overcome that obstacle. Once you have the basics of programming, everything else is just making big things out of littler things, and the little things are usually pretty easy.
When you are making something you know you will actually use, it's more fun and more gratifying when you finish.
Do you understand all of the following and how they work?
Linked lists (single and double)
Sequential vs. binary search
Binary trees
Stacks
Red-black trees
Algorithmic complexity and big O notation
Recursion
Hash tables and hashing algorithms
If you don't feel completely conversant in any of these, take a class in data structures and algorithms.
It seems like you've experienced many languages, but have not created a real-world application. Creating software in any of those languages will bring you to a new level.
PS: Creating software is much more than just knowing how to mess around with a language.
Check out Design Patterns.
I believe that's beyond mere simple coding.
You could offer your abilities to a non profit or a friend or someone who needs a website or program built.
Tell them you can do it for free and then just go for it. As you start to make it you'll start to see what you need to learn.
For example I bit ago I had the program Peel www.getpeel.com on my Mac. But sold my Mac for Wind as I am traveling.
Seeing that there was nothing for Windows (or nothing I could find) like Peel. I build my own in PHP and am up to a 4th rebuilding of it as I learn betters ways to do each new thing I am learning.
You've got to find a particular type of functionality that interests you. For me it's been basic socket programming and making my own protocols. I got that feeling when I was able to create a functional file uploading control that worked in conjunction with a file upload service on the server which I had created. The protocol handles authentication, chunking and hash comparison. Sometime soon I plan on incorporating file-resume functionality as well.
Well my advice will be to find a problem/project you are interested in and try to code it. Trying a real problem is something that drives you. Find something not to complex but not too simple. Something to try when starting a new language is to write some tools. You can for example program a python script that print metrics on a C++ project. You can write a tool that extract some statistics from a website you use, etc. When I learn programming game programming was quite fun (I was young :-) ). You can try to program some simple game using a 3D engine like Ogre3D for example. Participate in an opensource project is great too but as you stated perhaps a bit overwhelming for now ;-)
Find something you like and that has a REAL useful goal for you. You will thrive to solve the problem and learn a lot along the way !
I think the transition from the kind of finite tractable problems that are part of class projects (and some internships) to "real world" projects is quite tough. Sounds like language syntax, getting bugs out of code etc. is something you are comforatble with.
When we come to larger projects, probably with many release cycles, with developers working together, different kinds of problems emerge. I remember being shocked when I saw my first big project plan - what a small propertion of the time was actually writing code!
The thing I found helpful as a junior was "Sitting By Nelly", I was lucky enough to work for enlighted employers who put me with very experienced and helpful developers. Sometimes to work with, sometime to work alongside. I reckon that helped me get over the hurdles you describe.
So, I reckon you need to find employment of this kind. Be less concerned about specific technologies, salary etc. Look instead for the culture and level of responsibility you would have.
I think you should really start a "real world application" as suggested here. You will see that a real project requires a bit more than just knowing the language.
I suggest you find some simple problem you had issue with, and make a software that solves that issue.
For example, if you want some kind of software that checks RSS feeds every 5 minutes and makes a little pop-up as soon as a new one comes along. Or you want a program that will let you do simple presentations by just dragging a few pictures in.
Then whatever you choose, start by making the simple solution to the problem and extend from there (like do different settings, extra features etc.)
I've looked for the answer to this question for a while now. Most all of the suggestions are usually either help an open source project or build something that interests you. I'm starting to realize that those answers are vague because what's 'interesting' or 'valuable' experience and how to get started doing it is completely subjective. Also, there's only one way to get real experience, which is to work on real projects. It's difficult but find a project, personal, open source, or otherwise that will increase your knowledge in a technology or platform that you think will hold your interest. Then just dig in. It doesn't have to be of earth shattering importance, just valuable in relation to your own goals.
There is no magic bullet transition from academic puzzle solving programs to real world applications. The best way to learn is just to jump in head first. It will take you a very long time to learn what you need to if you only ever look at your own code. You need to be looking at code written by professionals and struggling to understand why it works the way it does until you do understand it.
It seems overwhelming at first, but you will quickly start to see patterns if the application is at all logical. Well written code will be separated in logical ways, so you should be able to pick it apart one layer at a time.
For example, you could try a bottom up approach where you try to understand how the database interactions are handled before looking at the code that uses the database layer. You keep going upward until you get to the GUI event handlers.
Large enterprise applications can be even harder to understand because there might be a lot more than one executable, or component. Try to stay focused and learn what the component is responsible for doing, and then pick it apart a piece at a time.
You will see that there are not just patterns at the function and class level, but at higher levels as well. This makes it simpler to understand what is going on when you understand those patterns.
Try to find an internship or co-op position. I was in a similar situation after my first few courses. I took a co-op position sophomore year and I learned so much more on the job than I did in class. Class is great for teaching you theory and the basics. I learned C# on my first project on my co-op and that got me my second co-op position at another employer (wanted to see how it was working at a small company).
This past spring, I accepted a position at my first co-op employer, reworking my first major project I had started on my co-op. I have a list of side projects I also want to complete, which will help round out my skills, as well as learn some other languages.
So my suggestion is try finding a job where you can have a great mentor. On my second co-op, I learned alot of the coding standards that I code against from my supervisor. He was a great teacher, and really had some great input, and explained why things should be done certain ways.
You will almost certainly go nowhere unless you find something that interests you. Figure out what is interesting, and then how to write software involving it.
The only way to begin is to begin! There is really no other way... The best answers you get would always tell you this. You have the knowledge, now put it to work!

Have you employed any strategies or techniques to overcome user resistance when implementing a new system?

We have been trying now for a while to assist the management (of a customer) with the implementation of a a new system that is custom developed by ourselves, to their requirements. Their old system is text based (DOS) and their employees have been using it for years. The new system is Windows GUI and have many advanced features which will make their lives easier and their organisation more efficient. The problem is that the staff do not want to adapt to the new GUI environment and they are now resorting to be unfriendly and as unhelpful as possible, often placing serious obstacles in our way. The management is adamant that implementation must proceed. The system runs trouble free. We have been consistently friendly and helpful with all parties.
Any advise would be greatly appreciated! Have you encountered something like this before and did you manage to turn it round?
Note:This question is intended to help Programmers etc. with implementation difficulties by sharing experiences and factual solutions that worked. It is not intended to be subjective and indeed Programming techniques may help to solve the problem.
Use the tool
Somebody needs to really understand how the existing tool works. Not just well enough to walk through it; but well enough to do it for real. Why not take 2 weeks and go and do their job with them? That will both improve your understanding of the tool, and may foster a better working relationship with them. And while you're there, perhaps buy the drinks once or twice - it sounds corny, but anything that lowers the hostility, and lets you communicate.
User experience
Getting a good developer (or better: designer) who understanding user-experience is probably key. You can't just completely change their tooling and expect their productivity to remain the same.
Keyboard use:
Think of tools like Visual Studio, AutoCAD, etc - in most cases you don't need the mouse, and "die hard" types wouldn't notice if you took their mouse away. Try to respect this; provide shortcuts / chords (ideally the same as the existing system).
Terminology:
Keep it the same. Don't invent new terms for things.
Talk to them?
This may or may not be possible, but getting a few key users "on board" early can be pivotal; especially if you genuinely empower them to help with the user experience.
Find the faults
In the existing system. Take away their existing pain points and they may forgive you a lot.
Unfortunately it sounds like a case of needing to close the barn doors after the horses have bolted. You really need to get grass roots buy-in on the need for an improved system before beginning the project and maintain that relationship during the development.
By having champions of the system at the "coal face" level in the business would a) make sure you meet not only the management requirements but also the users goals which is all important in a successful system and b) the users get a system to which they have been a development party not just had a system thrust on them.
Getting people to moan about the short comings of an existing system is easy. Describing possible new systems before its create in way which allows the users to comment enables them to feel some control and gives you vital feedback. Be absolutely sure to identifier those killer gripes about the old system and make sure those are addressed in the new system.
Of course this all a bit late for you. The way forward is to create a review forum with the most vocal opponents and put them in a room with you and management. Get them to defend their reasons for not wanting the new system. If you can't show how your new system is better then perhaps it isn't. If you can see how the new system might be slightly improved (the movement may only need to be small) then do that, it may go a long way to get back the feeling of involvement you missed out on before.
I would sit together with the staff or a couple of the more loud mouthed opposers, go through what they find lacking with the system and suggest some of these changes to be incorporated in a future release(s). That way they will pay more attention to your the system and also feel more a part of the process instead of just being handed something like some peon. In addition it would also help avoid any misunderstandings about the system.
Get one / more of the user to be your champion by involving them in the development process. Make sure to choose the right ones. Hopefully one that you can reason with. When launching, do a launch event. Make it a big deal. Not necessarily applied to an application, but I've seen it worked in my previous work environments. If this is too late (you went ahead without any involvement from the actual users before), well... there is always things called staff turnover, lol. Out with the old and in with the new. Make the new users your buddy :).
You have to show some kind of benefit for making the change. A demo / mockup can be useful for this. Choose a manager to demo it to and wait. Let it become his idea. Then it might move forward. Being to pushy can cause a negative knee-jerk reaction which might block further consideration of the idea.
It is sad that software often gets replaced by a management decision without any user involvement and then people wonder why the system is rejected.
I've witnessed this first hand. A guy I once worked was told to develop a new version of an application "in secret". At the end of 6 months development it was shown to the users. It didn't meet their requirements and they were angry they hadn't been involved. Needless to say the software didn't make it into production and the developer left shortly after (I felt sorry for him as he had wasted 6 months effort and actually did a real good job considering the circumstances).
The chances are that the software is inferior to the previous application- perhaps data entry is actually slower (you will be biased as you wrote it- everyone likes to think their software is better).
Re-engage with the users, do some analysis and work out what is bad about the old system. If the new system can address the grips the users have with the old system you might be able to turn this around.
Edit- who was involved in engaged with your developers? Presumably the managers at the client, who probably never use the system? This is another big mistake people tend to make- managers driving requirements.
If the old system is perfect, then it never needed to be replaced in the first place!

How do you plan an application's architecture before writing any code? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
One thing I struggle with is planning an application's architecture before writing any code.
I don't mean gathering requirements to narrow in on what the application needs to do, but rather effectively thinking about a good way to lay out the overall class, data and flow structures, and iterating those thoughts so that I have a credible plan of action in mind before even opening the IDE. At the moment it is all to easy to just open the IDE, create a blank project, start writing bits and bobs and let the design 'grow out' from there.
I gather UML is one way to do this but I have no experience with it so it seems kind of nebulous.
How do you plan an application's architecture before writing any code? If UML is the way to go, can you recommend a concise and practical introduction for a developer of smallish applications?
I appreciate your input.
I consider the following:
what the system is supposed to do, that is, what is the problem that the system is trying to solve
who is the customer and what are their wishes
what the system has to integrate with
are there any legacy aspects that need to be considered
what are the user interractions
etc...
Then I start looking at the system as a black box and:
what are the interactions that need to happen with that black box
what are the behaviours that need to happen inside the black box, i.e. what needs to happen to those interactions for the black box to exhibit the desired behaviour at a higher level, e.g. receive and process incoming messages from a reservation system, update a database etc.
Then this will start to give you a view of the system that consists of various internal black boxes, each of which can be broken down further in the same manner.
UML is very good to represent such behaviour. You can describe most systems just using two of the many components of UML, namely:
class diagrams, and
sequence diagrams.
You may need activity diagrams as well if there is any parallelism in the behaviour that needs to be described.
A good resource for learning UML is Martin Fowler's excellent book "UML Distilled" (Amazon link - sanitised for the script kiddie link nazis out there (-: ). This book gives you a quick look at the essential parts of each of the components of UML.
Oh. What I've described is pretty much Ivar Jacobson's approach. Jacobson is one of the Three Amigos of OO. In fact UML was initially developed by the other two persons that form the Three Amigos, Grady Booch and Jim Rumbaugh
I really find that a first-off of writing on paper or whiteboard is really crucial. Then move to UML if you want, but nothing beats the flexibility of just drawing it by hand at first.
You should definitely take a look at Steve McConnell's Code Complete-
and especially at his giveaway chapter on "Design in Construction"
You can download it from his website:
http://cc2e.com/File.ashx?cid=336
If you're developing for .NET, Microsoft have just published (as a free e-book!) the Application Architecture Guide 2.0b1. It provides loads of really good information about planning your architecture before writing any code.
If you were desperate I expect you could use large chunks of it for non-.NET-based architectures.
I'll preface this by saying that I do mostly web development where much of the architecture is already decided in advance (WebForms, now MVC) and most of my projects are reasonably small, one-person efforts that take less than a year. I also know going in that I'll have an ORM and DAL to handle my business object and data interaction, respectively. Recently, I've switched to using LINQ for this, so much of the "design" becomes database design and mapping via the DBML designer.
Typically, I work in a TDD (test driven development) manner. I don't spend a lot of time up front working on architectural or design details. I do gather the overall interaction of the user with the application via stories. I use the stories to work out the interaction design and discover the major components of the application. I do a lot of whiteboarding during this process with the customer -- sometimes capturing details with a digital camera if they seem important enough to keep in diagram form. Mainly my stories get captured in story form in a wiki. Eventually, the stories get organized into releases and iterations.
By this time I usually have a pretty good idea of the architecture. If it's complicated or there are unusual bits -- things that differ from my normal practices -- or I'm working with someone else (not typical), I'll diagram things (again on a whiteboard). The same is true of complicated interactions -- I may design the page layout and flow on a whiteboard, keeping it (or capturing via camera) until I'm done with that section. Once I have a general idea of where I'm going and what needs to be done first, I'll start writing tests for the first stories. Usually, this goes like: "Okay, to do that I'll need these classes. I'll start with this one and it needs to do this." Then I start merrily TDDing along and the architecture/design grows from the needs of the application.
Periodically, I'll find myself wanting to write some bits of code over again or think "this really smells" and I'll refactor my design to remove duplication or replace the smelly bits with something more elegant. Mostly, I'm concerned with getting the functionality down while following good design principles. I find that using known patterns and paying attention to good principles as you go along works out pretty well.
http://dn.codegear.com/article/31863
I use UML, and find that guide pretty useful and easy to read. Let me know if you need something different.
UML is a notation. It is a way of recording your design, but not (in my opinion) of doing a design. If you need to write things down, I would recommend UML, though, not because it's the "best" but because it is a standard which others probably already know how to read, and it beats inventing your own "standard".
I think the best introduction to UML is still UML Distilled, by Martin Fowler, because it's concise, gives pratical guidance on where to use it, and makes it clear you don't have to buy into the whole UML/RUP story for it to be useful
Doing design is hard.It can't really be captured in one StackOverflow answer. Unfortunately, my design skills, such as they are, have evolved over the years and so I don't have one source I can refer you to.
However, one model I have found useful is robustness analysis (google for it, but there's an intro here). If you have your use-cases for what the system should do, a domain model of what things are involved, then I've found robustness analysis a useful tool in connecting the two and working out what the key components of the system need to be.
But the best advice is read widely, think hard, and practice. It's not a purely teachable skill, you've got to actually do it.
I'm not smart enough to plan ahead more than a little. When I do plan ahead, my plans always come out wrong, but now I've spend n days on bad plans. My limit seems to be about 15 minutes on the whiteboard.
Basically, I do as little work as I can to find out whether I'm headed in the right direction.
I look at my design for critical questions: when A does B to C, will it be fast enough for D? If not, we need a different design. Each of these questions can be answer with a spike. If the spikes look good, then we have the design and it's time to expand on it.
I code in the direction of getting some real customer value as soon as possible, so a customer can tell me where I should be going.
Because I always get things wrong, I rely on refactoring to help me get them right. Refactoring is risky, so I have to write unit tests as I go. Writing unit tests after the fact is hard because of coupling, so I write my tests first. Staying disciplined about this stuff is hard, and a different brain sees things differently, so I like to have a buddy coding with me. My coding buddy has a nose, so I shower regularly.
Let's call it "Extreme Programming".
"White boards, sketches and Post-it notes are excellent design
tools. Complicated modeling tools have a tendency to be more
distracting than illuminating." From Practices of an Agile Developer
by Venkat Subramaniam and Andy Hunt.
I'm not convinced anything can be planned in advance before implementation. I've got 10 years experience, but that's only been at 4 companies (including 2 sites at one company, that were almost polar opposites), and almost all of my experience has been in terms of watching colossal cluster********s occur. I'm starting to think that stuff like refactoring is really the best way to do things, but at the same time I realize that my experience is limited, and I might just be reacting to what I've seen. What I'd really like to know is how to gain the best experience so I'm able to arrive at proper conclusions, but it seems like there's no shortcut and it just involves a lot of time seeing people doing things wrong :(. I'd really like to give a go at working at a company where people do things right (as evidenced by successful product deployments), to know whether I'm a just a contrarian bastard, or if I'm really as smart as I think I am.
I beg to differ: UML can be used for application architecture, but is more often used for technical architecture (frameworks, class or sequence diagrams, ...), because this is where those diagrams can most easily been kept in sync with the development.
Application Architecture occurs when you take some functional specifications (which describe the nature and flows of operations without making any assumptions about a future implementation), and you transform them into technical specifications.
Those specifications represent the applications you need for implementing some business and functional needs.
So if you need to process several large financial portfolios (functional specification), you may determine that you need to divide that large specification into:
a dispatcher to assign those heavy calculations to different servers
a launcher to make sure all calculation servers are up and running before starting to process those portfolios.
a GUI to be able to show what is going on.
a "common" component to develop the specific portfolio algorithms, independently of the rest of the application architecture, in order to facilitate unit testing, but also some functional and regression testing.
So basically, to think about application architecture is to decide what "group of files" you need to develop in a coherent way (you can not develop in the same group of files a launcher, a GUI, a dispatcher, ...: they would not be able to evolve at the same pace)
When an application architecture is well defined, each of its components is usually a good candidate for a configuration component, that is a group of file which can be versionned as a all into a VCS (Version Control System), meaning all its files will be labeled together every time you need to record a snapshot of that application (again, it would be hard to label all your system, each of its application can not be in a stable state at the same time)
I have been doing architecture for a while. I use BPML to first refine the business process and then use UML to capture various details! Third step generally is ERD! By the time you are done with BPML and UML your ERD will be fairly stable! No plan is perfect and no abstraction is going to be 100%. Plan on refactoring, goal is to minimize refactoring as much as possible!
I try to break my thinking down into two areas: a representation of the things I'm trying to manipulate, and what I intend to do with them.
When I'm trying to model the stuff I'm trying to manipulate, I come up with a series of discrete item definitions- an ecommerce site will have a SKU, a product, a customer, and so forth. I'll also have some non-material things that I'm working with- an order, or a category. Once I have all of the "nouns" in the system, I'll make a domain model that shows how these objects are related to each other- an order has a customer and multiple SKUs, many skus are grouped into a product, and so on.
These domain models can be represented as UML domain models, class diagrams, and SQL ERD's.
Once I have the nouns of the system figured out, I move on to the verbs- for instance, the operations that each of these items go through to commit an order. These usually map pretty well to use cases from my functional requirements- the easiest way to express these that I've found is UML sequence, activity, or collaboration diagrams or swimlane diagrams.
It's important to think of this as an iterative process; I'll do a little corner of the domain, and then work on the actions, and then go back. Ideally I'll have time to write code to try stuff out as I'm going along- you never want the design to get too far ahead of the application. This process is usually terrible if you think that you are building the complete and final architecture for everything; really, all you're trying to do is establish the basic foundations that the team will be sharing in common as they move through development. You're mostly creating a shared vocabulary for team members to use as they describe the system, not laying down the law for how it's gotta be done.
I find myself having trouble fully thinking a system out before coding it. It's just too easy to only bring a cursory glance to some components which you only later realize are much more complicated than you thought they were.
One solution is to just try really hard. Write UML everywhere. Go through every class. Think how it will interact with your other classes. This is difficult to do.
What I like doing is to make a general overview at first. I don't like UML, but I do like drawing diagrams which get the point across. Then I begin to implement it. Even while I'm just writing out the class structure with empty methods, I often see things that I missed earlier, so then I update my design. As I'm coding, I'll realize I need to do something differently, so I'll update my design. It's an iterative process. The concept of "design everything first, and then implement it all" is known as the waterfall model, and I think others have shown it's a bad way of doing software.
Try Archimate.

Is there any place a developer can go besides Google to learn what it is they need to learn?

I'm not really asking about how programmers learn how to program. More about specific technologies. If I wanted to learn Hibernate, how do I know what I should know prior to Hibernate? Should I learn JPA before, during or after Hibernate? Is there a better solution to Hibernate? (And I'm not really looking for information on Hibernate specifically)
Maybe stackoverflow is the place to find these answers, but it seems like with the shear vastness of frameworks, apis, libraries, programming languages, platforms, and whatever other techie word you want to use, it takes an extremely long time to come up to speed on what technology to use, when and what you need to know prior to using it.
Sometimes the best way to learn is to just dig in to a framework. Sure, you could use someones wrapper API around something, but if there is something wrong w/ hibernate, then you wouldn't know what's happening.
And to answer "how do i know what i should know prior to hibernate", you don't, that's why you are learning. When learning about c++, started out with simple data types, but i didn't know about pointers yet, didn't need to, but i learned about them when i got there. Just gotta jump in and start playing around.
I use Wikipedia to compare various technologies to copmlete a task, although it can be incomplete with regards to commercial closed-source frameworks (probably because fewer people have access to them).
For specific technologies such as Hibernate, Java, JPA, LDAP (OpenLDAP in particular), Log4J, anything Apache: they all have wikis and/or forums associated with the product that are usually more helpful than a Google search for learning. Many even come with tutorials and you should try them.
Find a book on the subject and read it. Then email the author with additional questions. Most of these authors are more than happy to help especially if you've bought and read the materials they worked so hard to produce.
If that's still not enough for you, go to a conference covering the subject, if you can make it. Again you can meet many of the people responsible for maintaining and/or creating these technologies and I've found they are always willing to answer questions.
go to sites like Coding Horror, Slashdot, Techcrunch etc and find out what people are talking about. Usually if something is popular it's probably something you might want to talk a look at.
There are these things called "books" that are filled with all kinds of knowledge.
A lot of the time the documentation and/or tutorial for any technology or project will mention what prior knowledge is assumed or useful.
So for example hibernate: http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#tutorial-intro
"This tutorial is intended for new users of Hibernate but requires Java and SQL knowledge"
For me, the things that have helped my career and taught me what questions to ask are:
Podcasts -- .NET Rocks, etc., which introduce and discuss new technologies and put them in context
Join your local users group, and stick around after the presentation to talk shop with the folks there; you can learn a lot just by hearing what other people are doing and what they are working on learning next
Just look around online and start trying to use whatever tool/technology your trying to learn. As you try to learn one thing, you'll realize your lacking knowledge in other needed areas. at which point you can repeat the process of looking around for this new item you need to learn.
for example, maybe you want to learn Rails, so you start following rails tutorials, but you realize you suck at Ruby. so then you start to focus a bit more on the details of Ruby, then come back to Rails with a little more knowledge and continue on till the next roadblock. this isn't really totally correct, but you get the idea.
you won't always find a full guide of how to use everything. just give it a shot and work it out on your own if you have the time
There is an infinite number of things one could learn. Maybe a better approach would be to think of a project that interests you, or join an open source one, and then learn what you need to know to accomplish what is needed in that project. When you're done, pick a new project that might include new things not learned in the last project.
As far as free sources are concerned, as a .NET programmer I like www.asp.net, and there are many others, such as the ASP.NET quickstart tutorials at http://quickstarts.asp.net/QuickStartv20/default.aspx, C-SharpCorner is good, too, if you don't mind C#.
If you don't object to paying a little money, Lynda.com is a decent place. They have OK tutorials on all kinds of things, not just programming, and I got a decent grounding in Javascript using one of their tutorials. They are adding new things all the time, so if they don't have something on Hibernate now, they may later on. I think their basic rate is $25 per month, but you can just pay for one month and then soak up as many courses as you can find time for.
Asking a more specific question will get your a more specific answer here. When I want to read up on something I usually head to Wikipedia and then Google.
The truth is none of us have the time to read everything we'd like to. So I let someone else do it for me!
The way I solve this is by speed-reading the web - aka. subscribing and reading to other peoples blogs.
Everytime I come across something I'm not familiar with I google it.