Software Architecture and Design – Goals, Principles plus some Key Considerations

Philippe Kruchten, Grady Booch, Kurt Bittner, and Rich Reitman derived and refined a definition of architecture based on work by Mary Shaw and David Garlan (Shaw and Garlan 1996). Their definition is:

“Software architecture encompasses the set of significant decisions concerning the organization of a software system including the collection of the structural elements and their interfaces where the system is composed; behavior as specified in collaboration among those elements; composition of the structural and behavioral elements into larger subsystems; and an architectural style that guides this organization. Software architecture also involves functionality, usability, resilience, performance, reuse, comprehensibility, economic and technology constraints, tradeoffs and aesthetic concerns.”

In Patterns of Enterprise Application Architecture, Martin Fowler outlines some common recurring themes when explaining architecture. He identifies these themes as:

“The highest-level breakdown of a system into its parts; the decisions that are Hard to change; you can find multiple architectures in a system; what is architecturally Significant can change over a system’s lifetime; and, in the end, architecture boils Down to whatever the important stuff is.”

Software application architecture is the process of defining and coming up with a solution that is well structured and meets all the technical and operational requirements. The architecture should be able to consider and improve upon the normal quality attributes such as performance, security, and manageability.

The main focus of the program architecture is the way the major elements and components within an application are used by, or connect to, other major elements and components within the application. Selecting data structures and algorithms or the implementation information on individual components are design concerns, they are not an architectural concerns but sometimes Design and Architecture concerns overlap.

Before starting the architecting of any software, there are some basic questions that people should strive to get answers for. They are as follows:

How the users of the machine will be interacting with the system?

How will the application form be deployed into production and managed?

Do you know the various non-functional requirements for the application form, such as security, performance, concurrency, internationalization, and configuration?

How can the application be designed to be flexible and maintainable as time passes?

Do you know the architectural trends that may impact the application now or after it has been deployed?

Goals of Software Architecture

Building the bridge between business requirements and technical requirements is the main goal of any software architecture. The purpose of architecture is to identify certain requirements that affect the basic structure of the application. Good architecture reduces the business risks associated with creating a technical solution while an excellent design is flexible enough to handle the changes which will occur as time passes in hardware and software technology, in addition to in user scenarios and requirements. An architect must think about the overall aftereffect of design decisions, the inherent tradeoffs between quality attributes (such as for example performance and security), and the tradeoffs required to address user, system, and business requirements.

Principles of Software Architecture

The essential assumption of any architecture should be the belief that the look will evolve as time passes and that certain cannot know everything one need to know up front. The design will generally have to evolve through the implementation stages of the application as one learn more, and as one tests the look against real world requirements.

Keeping the above statement in mind, let’s try to list down a few of the Architectural principles:

The system should be built to change rather than building to last.

Model the architecture to analyze and reduce risk.

Use models and visualizations as a communication and collaboration tool.

The key engineering decisions ought to be identified and applied upfront.

Architects should consider using an incremental and iterative method of refining their architecture. Start with baseline architecture to have the big picture right, and evolve candidate architectures as one iteratively ensure that you improve one’s architecture. Usually do not try to get it fine the first time-design as much as you can so as to start testing the look against requirements and assumptions. Iteratively add details to the design over multiple passes to make certain that you get the big decisions right first, and then focus on the details. A standard pitfall is to dive in to the details too quickly and obtain the big decisions wrong by making incorrect assumptions, or by failing woefully to evaluate your architecture effectively.

When testing your architecture, consider the following questions:

What were the primary assumptions which were made while architecting the system?

What are the requirements both explicit and implicit this architecture is satisfying?

What are the key risks with this architectural approach?

What countermeasures are in place to mitigate key risks?

In what ways is this architecture a noticable difference over the baseline or the final candidate architecture?

Design Principles

When getting started off with Software design, one should bear in mind the proven principles and the principles that adheres to minimizes costs and maintenance requirements, and promotes usability and extensibility. The key principles of any Software Design are:

Separation of concerns: The main element factor to be considered is minimization of interaction points between independent feature sets to accomplish high cohesion and low coupling.

Single Responsibility principle: Each component or module should be independent in itself and responsible for only a specific feature or functionality.

Principle of Least Knowledge: An element or object should not find out about internal details of other components or objects.

Don’t repeat yourself (DRY): The intent or implementation of any feature or functionality should be done of them costing only one place. It will never be repeated in some other component or module

Minimize upfront design: This principle can be sometimes known as YAGNI (“You ain’t gonna need it”). Design only what’s necessary. Specifically for agile development, you can avoid big design upfront (BDUF). If the application form requirements are unclear, or if you have a possibility of the look evolving over time, one should avoid making a large design effort prematurely.

Design Practices

Keep design patterns consistent within each layer.

Do not duplicate functionality within an application.

Prefer composition to inheritance. When possible, use composition over inheritance when reusing functionality because inheritance increases the dependency between parent and child classes, thereby limiting the reuse of child classes. This reduces the inheritance hierarchies, which can become very difficult to handle.

Set up a coding style and naming convention for development.

Maintain system quality using automated QA techniques during development. Use reformas integrales valencia with other automated Quality Analysis techniques, such as dependency analysis and static code analysis, during development

Not only development, also consider the operation of your application. Determine what metrics and operational data are needed by the IT infrastructure to ensure the efficient deployment and operation of one’s application.

Application Layers: While architecting and designing the machine, one needs to carefully think about the various layers into which the application will be divided. There are some key considerations that require to be considered while doing that:

Separate the regions of concern. Break the application into distinct features that overlap in functionality less than possible. The main benefit of this approach is a feature or functionality could be optimized independently of other features or functionality

Be explicit about how layers communicate with one another.

Abstraction should be used to implement loose coupling between layers.

Do not mix various kinds of components in exactly the same logical layer. For example, the UI layer shouldn’t contain business processing components, but rather should contain components used to take care of user input and process user requests.

Keep the data format consistent inside a layer or component.