In this second instalment we are going to review another set of frames. This guideline should help you to understand what is involved on each one of them as well as considerations and known patterns.
You can find the first part following this link.
The second part looks like this:
The following guideline can help you to identify the key issues on each area of the frame and some recommendations that we usually share with our customers in the ADC team (Application Development Consultant ). Note that this list is not exhaustive and are general suggestions that can help you on your design process.
Configuration ManagementThe message here is clear, we need to move configurable options to a configuration file so the user can change it without recompiling the application. Yes, is quite clear but the problem is that developers usually overlook how this information is accessed and secured. We have seen many times user names and passwords on these files without any security! Not only have that, with time these configuration files grow to unmanageable levels that jeopardized the application execution.
· Lack of or incorrect configuration information
· Sharing configurations around farms
· Not securing sensitive configuration information (exposing passwords/identities)
· Lack of security around the configuration files
Consider the following guideline:
· Use IIS sharing configuration features in order to deploy configuration files over a farm.
· Consider using least-privileged process and service accounts.
· Categorize the configuration items into logical sections, this method can help you secure different areas (features like configuration delegation in IIS are very helpful in this scenario)
· Encrypt sensitive information in your configuration store
· Restrict the access to your configuration information
· Provide a separate administrative application to deal with configuration files.
Implement a component that exposes an API that is different from the client API in order to allow any custom implementation to be seamlessly plugged in.
Coupling and CohesionWhen you are designing components for your application you should ensure that are highly cohesive and loose coupling is used across layers. Coupling refers to the dependency between components and cohesion relies on the functionality that the component provides.
· Incorrect grouping of functionality
· No clear separation between objects
· Tight coupling across layers
· Design for loose coupling between layers.
· Consider using abstraction to implement loose coupling between components.
· Consider using common interface definitions
· Use dependency inversion to decouple dependencies, depending on abstractions rather than concrete components.
· Divide your application functionality into logical layers; if you are dealing with customers you shouldn’t include your message binding properties on the same object.
· Design for high cohesion. If a component says “Customers” it should provide only customer functionality.
· While loose coupling requires more code, the benefits include a shortened dependency chain and simplify the building process.
Combine individual views into a composite view.
Inversion of Control
Populate any dependencies of objects on other objects or components that must be fulfilled before the object can be used by the client application.
Implement a common template view, and derive or construct views using the template view.
Transform the model data into a logical presentation without any specific formatting, and then convert that logical presentation into the actual formatting required.
Delegate business data-processing responsibilities to helper classes.
Data AccessSeparating the data access layer (DAL) is an important decision that improves the application maintainability and extensibility. This will allow you to easily change the repository or the logical structure of your data model without affecting the application functionality. It is recommended to implement an entity model to translate physical designs into business ready entities.
· Per-user authentication and authorization when not needed
· Chatty database calls interfaces
· Data access code embedded with business logic
· Avoid coupling your application model to the database schema. Use abstraction models like the entity framework.
· Enforce data integrity in the database, not through data layer code.
· Move business logic to the application layer, avoid long stored procedures as they make applications harder to migrate and control.
· Open connections as late as possible and release them as early as possible.
· Avoid accessing the database from different layers, the DAL should be the only component that knows anything about the repository.
Include a data access object within a domain entity.
Implement a mapping layer between objects and the database structure that is used to move data from one structure to another while keeping them independent.
Data Transfer Object
An object that stores the data transported between processes, reducing the number of method calls required.
A set of business objects that represents the entities in a domain and the relationships between them.
An object that represents a database query.
An in-memory representation of a data source that works with domain entities.
Row data gateway
An object that acts as a gateway to a single record in a data source.
Table data gateway
An object that acts as a gateway to a table or view in a data source and centralizes all of the select, insert, update, and delete queries.
Organize the business logic for each transaction in a single procedure, making calls directly to the database or through a thin database wrapper.
A single component that handles the business logic for all rows in a database table or view.
Exception ManagementIt is important to track all the application exceptions to make the system more reliable and to properly capture application defects. A crash can be very costly for customers and is not something that you want to re-experience in order to get more information. A proper exception management should provide you with enough information when the fault occurs, this should include as much information as possible in order to reproduce the scenario.
· Unstable state exposure
· Revealing sensitive information to the user
· Using exceptions to control logic flow
· Inaccurate/non-existence logging information
· Do not reveal sensitive information in exception messages and log files. I have seen many websites showing the full stack when an error occurs!
· Let exceptions flow if they are unexpected, catching everything without proper logging may provide a false end user experience that can lead to corrupted entries.
· Design an appropriate exception propagation strategy.
· Send the information back to a central repository when possible to analyze trends when large user based is expected.
· Log information on common repositories, like log files, event logs or external web services.
Prevent a service from exposing information about its internal implementation when an exception occurs
LayeringProper layering design allows you to separate the functionality into different areas of concern. This will help you to group functionality and components that will make your system more predictable and able to scale out. Layers should have a well defined communication flow, for example, layer A can talk with layer B but not the opposite scenario.
· Incorrect grouping of components within layers
· Not following layering and dependency rules
· Not considering physical boundaries
· They should be used as logical groups, for example, user interface, process layer, application layer, data layer.
· Components within a layer should be cohesive.
· Consider physical boundaries when designing layers
· Use interfaces to define each layer, this will allow proper communication and different deployment models.
· If you are running web applications consider using message-based interfaces to provide a stateless user interface.
· Provide a facade pattern to the process and application layers.
Creates a high-level unified interface to a set of operations or processes in a remote subsystem to make that subsystem easier to use, by providing a course-grained interface over fine-grained operations to minimize calls across the network.
The next part will complete the set of considerations, watch this space!