Introduction
An architect in software development is like a blueprint designer for buildings, but instead of
buildings, they design software systems. Here’s a simple breakdown:
1. Purpose of Architecture:
• Architecture describes the structure of a software system. It’s like the foundation
and framework that guide how the system works.
2. Customer and Business Needs:
• A good architecture is designed based on the customer’s needs and the type of
business or domain the software is meant to serve. It focuses on solving real-
world problems.
3. Real-World Reflection:
• The best software architectures should reflect the real world in which the
software operates, ensuring that it is practical and useful.
4. Start with the Problem:
• Before deciding on specific technologies (like programming languages or
databases), you first need to understand the problem you are solving for the
user. The solution should come from that understanding.
5. Implementation Comes Last:
• Only after figuring out how to best solve the problem, you then choose the tools
or technologies (like which programming language or database) that will support
the solution.
In simple terms, software architecture is about understanding the problem, designing a
system that addresses it effectively, and then choosing the tools to build it.
Traditional vs Modern
Here's a simple breakdown of Traditional (Waterfall) vs. Modern (Agile) approaches:
Traditional (Waterfall) Approach:
• Big upfront design: The focus is on creating a complete, detailed design before
starting any development.
• Drawbacks:
• Complex designs that may not be flexible.
• Slow to develop because a lot of time is spent on planning and design before
any code is written.
• The design may not meet the user's true needs because it's done without
constant feedback.
• Rigid processes and lots of bureaucracy.
• Lack of flexibility and changes are hard to make once the design is done.
• Slow development due to centralized decision-making by architects.
Modern (Agile) Approach:
• Flexible design: Instead of settling on a complete design early, you build small pieces
of the system and release them regularly.
• Key Features:
• Build small, release often: Work in short cycles, getting feedback from users
early and often.
• Evolve based on feedback: Adjust the design based on what you learn.
• Experimentation: If you're unsure about something, try it out in small
experiments. If it works, keep it; if not, discard it.
• Adaptation: It's cheaper to rebuild and correct early mistakes than to stick with
a flawed design.
• Team involvement: Architects and developers work closely together, teaching
and coordinating to improve the process.
Key Differences:
• Waterfall: Big upfront design, slow, and hard to adapt.
• Agile: Flexible, iterative, and focused on learning and adapting quickly based on
feedback.
Conway’s Law
Conway's Law says that an organization's structure affects how its systems are designed. In
other words, the way a company is organized will shape how the software is built.
Key Points:
• Old Structure: Companies often have horizontal silos, where teams are divided by
skill (e.g., separate teams for coding, testing, etc.).
• Agile Structure: Instead, agile methods encourage cross-functional teams where
each team has all the skills needed to build a complete part of the system.
• These teams own a vertical slice of the system (i.e., they handle everything
from start to finish for a specific feature).
• Agile-friendly Architectures: The company should also design systems in a way that
supports these small, self-contained teams working independently.
Why It Helps:
• Faster Work: When teams have all the skills they need and can make decisions
independently, they can work more quickly and efficiently.
Domain-driven Design
Domain-Driven Design (DDD) is a way of organizing your code so that it directly reflects the
business problems you're trying to solve. Here’s the main idea broken down:
Key Concepts:
• Code should match the problem: The structure of your software should map to the
real-world business problem you're addressing, not just technical concerns.
• Avoid generic "N-Tiered" designs: In traditional systems, you often have layers like
presentation, business logic, and data access. But in DDD, those layers are too
general and don’t reflect the business itself.
• Unique solutions for unique problems: Each business problem requires a unique
architecture. This means your software design should be tailored to the specific needs
of the business.
• Modules reflect the business: The different parts (modules) of your software should
represent distinct parts of the business, not just technical divisions like databases or
servers.
• Bounded contexts: In DDD, a "bounded context" is a part of the business that can be
treated separately, like a department or specific process. Each context has its own
model of the problem and its own language.
• Clear communication within contexts: When people talk about a specific part of the
business, they use terms that make sense in that context. This helps avoid confusion
between different areas of the business.
The Goal:
Instead of trying to make a "one-size-fits-all" model (like in traditional methods), DDD
encourages designing systems that closely align with the real-world business needs. Each
part of the system focuses on solving a specific business problem.
Requirement gathering
Problem Statement
A problem statement is used during requirements gathering to describe:
• The user's problem that needs to be solved.
• The solution to that problem (the system or product you're building).
User Stories
A user story is a way to describe how the end user interacts with the system to achieve a
goal. It focuses on:
• What the user wants to do (the action or task).
• The value or benefit they get from doing it.
Important things about user stories:
• They describe the user's work, not the technical details or how the system works.
• They focus on real-world outcomes and solving actual problems that users face, not
just building software for the sake of it.
• They are refined over time to ensure they capture the most valuable and needed
features.
Key Point:
If your software doesn’t solve a real problem for a real user, it’s hard to see why anyone
would want to use it. User stories help you focus on providing value, rather than just creating
features.
Summary of the rest
Monoliths
• Monolithic systems are large applications with thousands of lines of code, often
structured as N-Tiered applications (divided into layers).
• Strengths: Everything is in one place, making it easier to manage at first.
• Challenges:
• The entire program can be hard to understand or maintain.
• Long testing and deployment cycles.
• Difficult to adapt to changes (agility is limited).
Microkernel (Plugin) Architectures
• The microkernel is a core system that provides essential features, while plugins
extend functionality.
• Strengths:
• Isolated components reduce dependency issues.
• Plugins are easier to maintain and debug.
• Challenges:
• Changes in the core kernel can affect plugins.
• Adding new functionality might require rewriting plugins.
• The system depends heavily on the kernel.
Message-Based Architectures
• This architecture uses a message bus to manage communication between
components that weren't originally designed to work together.
• Strengths:
• More maintainable than monolithic systems.
• Solves some problems faced by microkernel systems (like dependencies).
• Challenges:
• The system can become complex and slow.
• Messages need to be stored, replicated, and backed up.
Microservices and Miniservices
• Microservices are small, independent services that are:
• Small (few hundred lines of code),
• Autonomous (can be deployed and updated independently),
• Observable (easy to monitor).
• Strengths:
• Changes in one service don't affect the rest of the system.
• Quick changes and updates are possible.
• Challenges:
• Coordination between many small services can be complex.
REST (Representational State Transfer)
• REST is an architectural style for designing web services.
• Principles:
• Client-Server: The client and server are separate entities.
• Stateless: No session is stored on the server.
• Cacheable: Responses can be cached for better performance.
• Uniform Interface: A standard way to interact with the system.
• Layered System: Components interact through layers.
• Code on Demand (optional): The server can send executable code to the client.
• Common in web services: Often used with HTTP and JSON for communication
(using GET, POST, PUT, and DELETE methods).
Key Takeaways:
• Monolithic systems are large and rigid.
• Microkernel architectures isolate functionality into plugins.
• Message-based architectures manage communication via a bus.
• Microservices are small, independent services that can be deployed separately.
• REST provides a lightweight, stateless way to design web services.