What is Software Architecture?
To understand software architecture, or simply architecture, let us discuss a requirement of real life. Let us assume there is a requirement of a one-floor building where in the future we can add some more floors, and also we will be able to change the room design of new or existing floors with easy-to-make partitions at any time. So these are the common requirements of the building, and also it must not be affected by earthquakes, meaning the building should be ready to face any situation easily. So these are nothing but attributes and behaviors of the building, and we can only achieve all this through with proper design. The design of the foundation is the most important part of any building design, and also as an end user or client, we always consider concepts such as Time, Budget, Flexibility, Maintainability, Reliability, Robustness etc. Whenever we need something in real life we generally ask the vendor questions like: How was this built? What would be the cost of maintaining it in the future? How long will it last? etc. And the vendor as a non-computer person will say, we have made it this way or that way, and this particular item is long-lasting and easy- to-maintain in the future. They will say so many thing to satisfy our questions. It means in a direct way, he was trying to explain about how this item was constructed or designed so that it meets the user requirements and also is easy to maintain in the future.
The underlying idea from the above point is that if anything is designed properly or structurally then this will produce a good product which will meet all the above criteria. So this is nothing but architecting the items in a well-planned way to meet the fundamental theory of the previously-mentioned words.
So in short, architecture is nothing but the process of defining a structured solution of anything which meets technical and non-technical operations of any business. In brief, it is just a design process on paper or in real implementation.
Goals of Architecture
There are various goals of architecture,
- Create outline or skeleton to implement a product
- Hide detail and inner complexity and show the structural detail
- Help developer to utilize common components or code
- Loosely coupled design of product
- Reduce redundant code by creating reusable components or library
- Solve well known issues which occurred while designing any application
- Easy to maintain product in support phase
- Satisfy the end user by providing cutting edge solutions
- Easy to adapt any business changes in future
There are various objectives and goals which we can achieve from good architecture.
There are some key design principals which help to achieve a good architectural product and they are,
- Separation of concern
Separation of concern is nothing but a style of implementation of code or business logic and UI in a clean way so that both should not mix together. It means business concerns or other key logic should be in a separate layer or file from UI design.
- Single Responsibility
As the name suggests, each module or component should be responsible for one and only one task.
- Least Knowledge
It means one component should not know the detail of other components.
- Do not Repeat
It means the same functionality should be repeated in multiple components. One functionality should be in one component.
- Minimize the Design
Only design what is required for the application and do not try to reinvent the wheel if something is already available. Try to use time tested reusable components if possible. This will minimize the testing effort and time for bug fixing which in turn is cost effective development and will meet the deadline easily.
The idea of these design principals is to hide the complexity of modules by componentizing the solution and providing easily adoptable components or functions which we may reuse with other applications as well. For example, distribute different areas of concern into different components such as Data Access, Business Logic, Exception Handling Mechanism, Email or SMS handling, File Operation, Services etc.
If we think at a high level of architecting the solution then we may come up with some ideas and they would be,
In Software development, practice is nothing but a general way of coding style or the way of writing a piece of code that it should not be repeated with other areas of the solution, or utilizing concepts of Object Oriented programming in our solution or delivering quality components. There are so many ideas which we follow as good design practice.
Fully utilize the concept of object oriented paradigms which help to solve known development issues and allow you to extend and maintain applications in a better way than the monolithic approach.
- Application Layer
Be specific abut what components we are going to develop as part of the solution and categorize them in layers that help to implement certain theories of best practices like Cohesion and Coupling.
- Use domain model or object to send and receive data across the layer whenever required so that the application will have the same format of data everywhere
- Based upon functionality of components, break them into different layers such as Data Access, Business Logic, Helper or Utility or Common, Domain, Service etc.
- Always use abstraction to achieve development of loosely coupled components.
Components should not depend upon details of other components and communication of each component should be specific about how they are going to talk with each other
Define the contract of each component for how other components can access the internal functionality of the component, module, or function; and the behavior of that functionality in terms of execution flow, behavior of pre and post condition, side effects, exceptions, performance characteristics, and other factors.
- System Quality
Delivering quality components is one key aspect of software development to meet the user requirement efficiently. To do so perform unit tests for each development to ensure the piece of code works fine followed by a thorough system testing or any other type of testing. Use automated QA tools during development to ensure that the correct operational data is provided by your application’s components and sub-systems.
When to Create Architecture
Historically, architectures are created in the design phase or early in the development of a system. If you’re using a waterfall development process, for example, creating the architecture is one of the very first things you do. You define the problem and then solve it with an architecture. If, instead, you’re using an iterative software development process, such as Unified Process or agile, the architecture is typically evolved and elaborated in the early iterations in parallel with some low-level design and coding. As iterations of the architectural development become stable and complete, the other steps, such as design and coding, can begin. Each iteration may include more refinement to the architecture in conjunction with further design and coding. Pattern A Pattern is an idea that has been useful in one practical context and may be in others. Pattern can be classified as an Architectural and Design Pattern.
- Architectural Patterns
Architectural Patterns define the physical or logical structure of the solution at the highest level. Architectural patterns require all the parts of the system that are touched by the pattern to participate in its design. It can be classified into various categories:
Distributes the system into two applications, where the client makes requests to the server. In many cases, the server is a database or any other application that serves as Server.
Decomposes application design or logic into reusable functional or logical components that expose well-defined properties or methods to interact with the components such as Grid, Button, Data Adapter etc.
- Domain Driven Design
Domain Driven Design is an OOPS approach to designing software applications by modeling a business domain and defining Business Objects based on Entities.
- Layered Architecture
Partitions the concerns of the application into stacked groups (layers) and are deployed on the same computer.
- Message Bus
An architecture style that prescribes the use of a software system that can receive and send messages using one or more communication channels, so that applications can interact without needing to know specific details about each other.
- N-Tier / 3-Tier
Distributes the functionality into separate parts in much the same way as the layered style, but with each part being a tier located on a physically separate computer.
Object Oriented design is the process of creating self-sufficient objects having a set of properties and methods which deals with the specific logic or functionality of an application and can also contain the set of data as part of functionality.
- Service-Oriented Architecture (SOA)
SOA is nothing but an Application that provides services to other applications independent of any platform or technology that exposes and consumes functionality as a service using contracts and messages.
- Design Patterns
Design Patterns are nothing but a process or methodology to apply or implement good architecture in a solution. In other words, Design Pattern is a subset of Architecture where we follow some programming patterns to prevent known development issues which in turn reduces the maintainability time.
“Pattern is a recurring design element.” Design Patterns are the solution of a known problem occuring during software development.
What Design Pattern is Not
- Patterns are not any framework
- It is not a universal problem solver
- It is not an algorithm
- Patterns are not exclusive to OOPS
Creating Your Own Design Pattern
Creating your own pattern is not hard but you need an idea to solve some specific problem that becomes the best solution of the given problem. Then get it reviewed, document it, and share it with your colleague so they can learn from what you have done.
Rule of Three
Any solution can be a design pattern that confirms the Rule of Three, which means something must be used at least three times to solve the same problem successfully before it can be called a design pattern.
Types of Design Patterns
There are three categories of design patterns which can be used as per the requirement and they are,
- Creational Patterns
This pattern provides a mechanism to create objects of the classes in a more efficient way.
Factory Pattern creates objects without exposing the creation logic to the client and refers to newly created objects using a common interface.
- Abstract Factory
Abstract Factory is nothing but a Factory of Factory, which create Factory objects based upon the interface without explicitly specifying classes. Each generated Factory can give the objects as per the Factory Pattern.
Builds a complex object by using simple objects and also step by step.
Allows us to create duplicate objects by cloning. This pattern is useful when the creation of an object is costly.
In this pattern only single class is involved and creates only a single object.
- Structural Patterns
This pattern provides a mechanism to deal with relationships of different entities in an easier way.
This pattern is something like a bridge between two independent interfaces in which one class joins the functionality of two independent interfaces.
Bridge Pattern separates an abstraction from its implementation so that the two can work independently.
Composite design patterns form a tree structure to represent part of as well as the whole hierarchy. This pattern creates a class which holds a group of its own objects and provides a way to modify its objects.
This is a kind of wrapper class implementation which allows a user to add new functionality to an existing object without changing the flow, this pattern acts as a wrapper to an existing class. The wrap class wraps the original implementation and provides additional features.
This pattern hides the inner complexity of a system and provides a simple method to deal with different sub systems. This pattern has a single class and its method provides delegates to different classes of methods.
Design wise it is a factory pattern with additional checks and in-memory storage to reduce the number of objects created. Before creating an object it checks if a previously created object exists, then it returns the same.
This design pattern represents functionality of other classes in which a proxy object holds the original object to interface its functionality to the outer world.
- Behavioral Patterns
This pattern provides a mechanism for how entities should talk to each other.
- Chain of Responsibility
This patterns creates requester and receiver objects which forms the chain. If one of the objects cannot handle the task then it passes to the next level of object, like a way of passing a request between a chain of objects.
A request will be encapsulated under object and passed to invoker which further finds the appropriate object which can execute the command request.
This pattern provides a way to evaluate language or expression. It is useful in parsing some syntax or expression.
Iterator pattern provides a way to implement iterator class which returns the objects from the Array collection without knowing the underlying detail in a sequential manner.
It reduces the communication complexity between multiple objects or classes. Where classes do not talk to each other directly, the mediator class handles all the communications between different classes.
This pattern is useful to maintain the state of object or application, which means it provides a way to capture and restore the state of the objects.
This pattern is useful where there is a one-to-many relationship between objects and if one object is modified, its dependent objects should be notified automatically.
This pattern changes the class behavior based on its state. It creates an objects which represents various states and a context object whose behavior varies as its state object changes.
This Pattern encapsulates various strategies and a context whose behavior varies as per its strategy object. The strategy object changes the executing algorithm of the context.
- Template Method
This pattern defines the abstract class and exposes a method which executes a set of methods in a defined way.
This pattern performs an operation on an element of object structure and also defines a new operation without changing the class hierarchy. So in this way the number of operations can vary as and when the visitor varies.
- Chain of Responsibility
I hope this article will help you to understand Architecture and Design Pattern properly. In the next article we will see the real implementation of each design pattern relating to a real world problem.