DekGenius.com
Previous Section  < Day Day Up >  Next Section

5.3 Considering Technical Requirements

With some of the external factors out of the way, it's time to form a plan to find the best possible foundation, from a technical perspective. You'll be tempted to get a standard middleware stack and build from there. In fact, just by starting with the gargantuan J2EE platform, you're probably making far too many assumptions.

After you've taken stock of external influences, start with the most basic question: what are you building? Without gathering a full set of requirements, you can still probably answer some basic questions. You don't have to have all of the answers from the beginning. In fact, you'll find that you create additional questions as you spiral inward, as in Figure 5-4. That's perfectly normal. The important thing is to consider the questions that will have the biggest overall impact on your designs. The outer-most questions tend to disrupt designs more. Inner questions tend to affect fewer systems.

Figure 5-4. As you explore foundational decisions, the process tends to spiral from the outside in
figs/bflJ_0504.gif


Your goal is to avoid over-designing out of the gate. (In fact, you'd prefer to under-design out of the gate.) You just want to avoid questions like, "So, isn't passing SQL input directly from the user interface going to murder security?" 10 minutes before you're supposed to be in production. Higher-level questions—the outer questions—prompt more detailed questions. This is natural, and helpful.

5.3.1 Outer Questions

Outer questions are the higher-level issues that shape your foundation quickly. You may be able to make a rough cut at your overall design without writing any code, but it's not necessary. Just nail down enough details to get some code rolling. Early code then helps to shape your requirements and thus your design. Here are some outer questions:


What are your external interfaces?

External interfaces make an excellent starting point when you're trying to iron out early decisions. An external interface is one that you don't fully control. Interfaces that cross major boundaries (such as programming languages, networks, firewalls, or JVMs) may need special consideration. You need a strategy for dealing with each before moving forward.


Who is your user?

In the early design stages, look at your user interface as one more external interface. A professional data entry clerk has more demanding requirements than an occasional departmental user. Supporting external clients over the Internet also dictates requirements.


What are your physical deployment restrictions?

Firewalls and existing deployment hard ware or software shape your solution. You want to sanity-check compatibility at every turn. For example, if you deploy a new message board discussing products with your existing e-commerce application, make sure to use a compatible JVM, servlet engine, and other software.


What are your database requirements?

Depending on your application, you may or may not decide to treat a database as just another distributed interface. Since databases form the core of many applications, I prefer to treat them separately. You'll need to decide on a persistence strategy fairly quickly. Is JDBC enough? Will you need a persistence framework? Do you expect to cache? Who owns the schema? These questions can make or break a project.


What components must/might you reuse?

You may have inherited some business components that you think might be useful. They'll come with some baggage, including programming languages and styles, an interface, and an overall philosophy. If developers err in this area, they often work too hard to reuse a component that doesn't fit. It's far better to steal some of the best ideas of the inherited components and start from scratch. However, if one of the components is a tax rules engine with an investment of 30 million lines of code, you'll have to use it. Your most critical task in that case is to wrap it in a way that's consistent with your architecture.


What's your security policy?

Most developers treat security as an add-on service. Unfortunately, that technique extends to most operating systems and programming environments. Fortunately, the news about Java and .NET is slightly better. If you decide on a consistent security policy before you start coding, you'll avoid some common problems. In this area, you can't guess; you need to know. If you've never heard of a SQL injection attack, call an expert. Then form a cohesive policy and follow it for all of your applications.


How fast does it need to be?

I can't think of many applications that were designed correctly for performance out of the gate. Most were either over-designed or under-designed. It's likely that yours will be, too. The critical point is to make decisions that will not paint you into a corner later. If you may need to cluster, don't build in dependencies that make clustering more difficult. You don't need to (and shouldn't) optimize prematurely, but understand the possible design implications of your expected load.

You can draw some rough lines in the sand by looking for the core requirements of your project. That's the purpose of the outer questions. You'll find that you've only got partial answers, but you may have enough information to understand your security model, the potential software layers, and potential deployment scenarios.

5.3.2 Inner Questions

After you've asked the outer questions and done some further development, you're going to need to fine-tune your architecture. That's the purpose of inner questions. Inner questions drill down into specialized problems; their goal is to refine your design, middleware requirements, and the interfaces between layers. Think of an inner decision as a major fork in the road. It's a detail that will definitely force a foundational architectural decision. Answering an inner question permits you to refine your design. Here are some examples of inner questions. As you can see, they depend almost entirely on your application:

  • Will we support stored procedures? And which persistence frameworks support stored procedures?

  • Does my façade layer need to be distributed? If not, do we still need to use session beans in the façade layer? If not, can we replace the J2EE application server with a simple servlet container and a web server?

  • Would a persistence framework simplify things? Am I spending too much time coding and debugging JDBC and raw SQL?

It's best to ask and answer these questions after you've had some experience with the problem. It's also best to put time and energy into answering the questions and then live with your first answer until something fundamental breaks.

5.3.2.1 Prototypes

Sometimes, you'll find that you need to write code to answer an inner question. That's expected and healthy. For example, you wouldn't want to use a persistence framework without trying it first. And you wouldn't want to use a persistence framework until you've established a need. (I tell my customers to push a POJO solution until it breaks, and only then get a persistence framework.) When you do decide to prototype, write just enough code to make your decision. Try to use production-coding techniques so you'll have a firm grasp of the shape of the solution. It's best to carve out a small but technically demanding scenario, one that proves a representative business requirement. If you're going to be paying for a product, consider getting a vendor's assistance.

Regardless of the technique that you use to answer the inner questions, make sure the team understands that once the decision is made, there's no going back. Technical decisions can fragment vulnerable teams. It's been my experience that in order to keep everyone pulling together, it's usually easier to get the entire team to agree to abide by a decision once it's made.

5.3.2.2 Documentation

When you think about it, what I've described is classical iterative development. Each iteration lets you know more about the system and solve more of your target problem. The primary way that processes differ in this area is the style and weight of documentation. You need to collect just enough documentation to do your job. Minimally, you've got to update your requirements to reflect any new, needed functionality, based in a foundational decision. The rest is entirely up to you. I prefer to keep it light. Frequently, I'll handle outer questions in meeting notes. For inner questions, if I need to get teammates to agree to a decision in a meeting or after a prototype, I'll try to follow the meeting or prototype exercise with a simple email that covers:

  • What we were trying to learn

  • What we decided

  • What contributed to the decision

Then I'll copy everyone who needs to sign off and say, "Does everybody agree?" This informal process has served me well as a developer. It's fast, to the point, and has just enough process to get the job done. In fact, as a consultant, most of my major agreements are not formal contracts. I also follow up with my clients, describing what I learned and letting the customer sign off. I find email organization services like listservs to be invaluable in this respect. You can create a distribution list for "architecture and design," for instance. Then, for all decision-making emails, simply copy the "architecture and design" listserv, making a threaded repository of all decisions publicly available to the whole team.

    Previous Section  < Day Day Up >  Next Section