I'm currently working on front-end web application that has a 3-tiered architecture:
- Client tier (the browser)
- Application tier (JEE application server, where the application will live)
- Backend tier (mainframe and legacy apps, various databases)
It has a layered architecture, and the layers in the Application tier are:
- Presentation layer: generates the UI that will be used in the Client tier
- Application layer: the equivalent of use cases, contains application logic
- Service layer: maps domain logic and data from Backend tier onto a Java model
- Integration layer: communicates with the Backend tier and contains gateways for JMS, email, ... and DAOs and other stuff
This is just an example project structure, and the end result will depend on the type of application. You can read more in my answer to this question on the division and naming strategy for packages.
You can add/swap/remove layers as you see fit. In a SOA for example, you can layer a Webservice layer on top of the Application layer or Service layer, so that the ESB (Enterprise Service Bus) can connect to your application or services. If any of this is impossible or seems very difficult, you don't have an optimal architecture and design.
When thinking about the structure of your project and to allow scenarios like the one above, some important properties of your modules and components you want are:
- Testability
- Reusability
- Maintainability
You can achieve this by designing for low coupling and high cohesion. Choosing a layered architecture by grouping modules by the level of functionality/abstraction is a good start. Within each layer grouping further by functionality helps as well. Letting each more specific layer only depend on interfaces of a more general layer reduces coupling too.