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 selection of the structural elements and their interfaces by which the system is composed; behavior as specified in collaboration among those elements; composition of these 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 typically common recurring themes when explaining architecture. He identifies these themes as:
“The highest-level breakdown of something into its parts; the decisions that are Hard to change; there are multiple architectures in something; what is architecturally Significant can change over a system’s lifetime; and, ultimately, architecture boils Down to regardless of the important stuff is.”
Software application architecture is the process of defining and creating a solution that is well structured and meets each of the technical and operational requirements. The architecture should be able to take into account and improve upon the normal quality attributes such as for example performance, security, and manageability.
contemporary houses of the program architecture is how the major elements and components within an application are employed by, or connect to, other major elements and components within the application. Selecting data structures and algorithms or the implementation details of individual components are design concerns, they’re no architectural concerns but sometimes Design and Architecture concerns overlap.
Prior to starting the architecting of any software, there are several basic questions that people should strive to get answers for. They’re as follows:
How the users of the machine will be interacting with the machine?
How will the application be deployed into production and managed?
What are the various non-functional requirements for the application form, such as for example security, performance, concurrency, internationalization, and configuration?
How can the application be designed to be flexible and maintainable over time?
Do you know the architectural trends that might impact the application now or after it’s been deployed?
Goals of Software Architecture
Building the bridge between business requirements and technical requirements is the definitive goal of any software architecture. The goal of architecture is to identify certain requirements that affect the essential structure of the application. Good architecture reduces the business enterprise risks associated with building a technical solution while an excellent design is flexible enough to handle the changes which will occur over time in hardware and software technology, as well as in user scenarios and requirements. An architect must think about the overall effect of design decisions, the inherent tradeoffs between quality attributes (such as for example performance and security), and the tradeoffs necessary to address user, system, and business requirements.
Principles of Software Architecture
The basic assumption of any architecture ought to be the belief that the design will evolve as time passes and that certain cannot know everything one need to know up front. The look will generally need to evolve during the implementation stages of the application as one learn more, so when one tests the design against real world requirements.
Keeping the above statement at heart, let’s try to list down some of the Architectural principles:
The system should be built to change instead of building to last.
Model the architecture to investigate and reduce risk.
Use models and visualizations as a communication and collaboration tool.
The key engineering decisions ought to be identified and acted upon upfront.
Architects should consider using an incremental and iterative approach to refining their architecture. Start with baseline architecture to find the big picture right, and evolve candidate architectures as one iteratively ensure that you improve one’s architecture. Do not try to get it fine the first time-design as much as you can as a way to start testing the design against requirements and assumptions. Iteratively add details to the look over multiple passes to ensure 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 get 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 main assumptions that were made while architecting the machine?
Do you know the requirements both explicit and implicit this architecture is satisfying?
Do you know the key risks with this architectural approach?
What countermeasures are in place to mitigate key risks?
In what ways is this architecture an improvement over the baseline or the last candidate architecture?
When getting started off with Software design, one should remember 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 key 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 in charge of just a specific feature or functionality.
Principle of Least Knowledge: A component or object should not find out about internal information on other components or objects.
Don’t repeat yourself (DRY): The intent or implementation of any feature or functionality should be done at only one place. It will never be repeated in some other component or module
Minimize upfront design: This principle can be sometimes referred to as YAGNI (“You ain’t gonna require 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 when there is a possibility of the design evolving over time, one should avoid making a large design effort prematurely.
Keep design patterns consistent within each layer.
Do not duplicate functionality within an application.
Prefer composition to inheritance. If 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 also reduces the inheritance hierarchies, which can become very difficult to handle.
Establish a coding style and naming convention for development.
Maintain system quality using automated QA techniques during development. Use unit testing along with other automated Quality Analysis techniques, such as dependency analysis and static code analysis, during development
Not only development, also think about the operation of your application. Know what metrics and operational data are needed by the IT infrastructure to ensure the efficient deployment and operation of your application.
Application Layers: While architecting and designing the system, one needs to carefully consider the various layers into that your application will be divided. There are a few key considerations that require to be kept in mind while doing that:
Separate the areas of concern. Break the application into distinct features that overlap in functionality as little as possible. The main benefit of this approach is that a feature or functionality can be optimized independently of other features or functionality
Be explicit about how layers communicate with each other.
Abstraction ought to be used to implement loose coupling between layers.
Do not mix several types of components in exactly the same logical layer. For instance, the UI layer should not contain business processing components, but rather should contain components used to take care of user input and process user requests.
Keep carefully the data format consistent inside a layer or component.