Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Software Architecture with Python
Software Architecture with Python

Software Architecture with Python: Design and architect highly scalable, robust, clean, and high performance applications in Python

Arrow left icon
Profile Icon Balachandran Pillai
Arrow right icon
$29.99 $43.99
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.5 (6 Ratings)
eBook Apr 2017 556 pages 1st Edition
eBook
$29.99 $43.99
Paperback
$54.99
Subscription
Free Trial
Renews at $19.99p/m
Arrow left icon
Profile Icon Balachandran Pillai
Arrow right icon
$29.99 $43.99
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.5 (6 Ratings)
eBook Apr 2017 556 pages 1st Edition
eBook
$29.99 $43.99
Paperback
$54.99
Subscription
Free Trial
Renews at $19.99p/m
eBook
$29.99 $43.99
Paperback
$54.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

Software Architecture with Python

Chapter 1. Principles of Software Architecture

This is a book on Python. At the same time, it is a book about software architecture and its various attributes, which are involved in a software development life cycle.

In order for you to understand and combine both aspects, which is essential to get maximum value from this book, it is important to grasp the fundamentals of software architecture, the themes and concepts related to it, and the various quality attributes of software architecture.

A number of software engineers, taking on senior roles in their organizations, often get very different interpretations of the definitions of software design and architecture, and the roles they play in building testable, maintainable, scalable, secure, and functional software.

Though there is a lot of literature in the field, which is available both in conventional book form and on the internet; very often, the practitioners among us get a confusing picture of these very important concepts. This is often due to the pressures involved in learning the technology rather than learning the fundamental design and architectural principles underlying the use of technology in building systems. This is a common practice in software development organizations, where the pressures of delivering working code often overpowers and eclipses everything else.

A book such as this one, strives to transcend the middle path in bridging the rather esoteric aspects of software development related to its architectural quality attributes to the mundane details of building software using programming languages, libraries, and frameworks—in this case, using Python and its developer ecosystem.

The role of this introductory chapter is to demystify these concepts, and explain them in very clear terms to the reader to prepare his/her for the path towards understanding the rest of this book. Hopefully, by the end of this book, the concepts and their practical details will represent a coherent body of knowledge to the reader.

We will now get started on this path without any further ado, roughly fitting this chapter into the following sections:

  • Defining software architecture
  • Software architecture versus design
  • Aspects of software architecture
  • Characteristics of software architecture
  • Why is software architecture important?
  • System versus Enterprise Architecture
  • Architectural quality attributes
    • Modifiability
    • Testability
    • Scalability/performance
    • Security
    • Deployability

Defining software architecture

There are various definitions of software architecture in the literature concerning the topic. A simple definition is given as follows:

Software architecture is a description of the subsystems or components of a software system, and the relationships between them.

The following is a more formal definition, from the Recommended Practice for Architectural Description of Software-Intensive Systems (IEEE) technology:

"Architecture is the fundamental organization of a system embodied in its components, their relationships to each other, and to the environment, and the principles guiding its design and evolution."

It is possible to get umpteen such definitions of software architecture if one spends some time searching on the web. The wordings might differ, but all the definitions refer to some core, fundamental aspects underlying software architecture.

Software architecture versus design

In the experience of the author, this question of the software architecture of a system versus its design seems to pop up quite often, in both online as well as offline forums. Hence, let us take a moment to understand this aspect.

Though both terms are often used interchangeably, the rough distinction of architecture versus design can be summarized as follows:

  • Architecture covers the higher level structures and interactions in a system. It is concerned with those questions that entail decision making about the skeleton of the system, involving not only its functional but also its organizational, technical, business, and quality attributes.
  • Design is all about the organization of parts or components of the system and the subsystems involved in making the system. The problems here are typically closer to the code or modules in question, such as these:
    • Which modules to split code into? How to organize them?
    • Which classes (or modules) to assign the different functionalities to?
    • Which design pattern should I use for class "C"?
    • How do my objects interact at runtime? What are the messages passed, and how is the interaction organized?

Software architecture is about the design of the entire system, whereas, software design is mostly about the details, typically at the implementation level of the various subsystems and components that make up those subsystems.

In other words, the word design comes up in both contexts, however, with the distinction that the former is at a much higher abstraction and at a larger scope than the latter.

There is a rich body of knowledge available for both software architecture and design, namely, architectural patterns and design patterns respectively. We will discuss both these topics in later chapters of this book.

Aspects of software architecture

In both the formal IEEE definition and the rather informal definition given earlier, we find some common, recurring themes. It is important to understand them in order to take our discussion on software architecture further:

  • System: A system is a collection of components organized in specific ways to achieve a specific functionality. A software system is a collection of such software components. A system can often be subgrouped into subsystems.
  • Structure: A structure is a set of elements that are grouped or organized together according to a guiding rule or principle. The elements can be software or hardware systems. A software architecture can exhibit various levels of structures depending on the observer's context.
  • Environment: The environment is the context or circumstances in which a software system is built, which has a direct influence on its architecture. Such contexts can be technical, business, professional, operational, and so on.
  • Stakeholder: A stakeholder is a person or groups of persons, who has an interest or concern in the system and its success. Examples of stakeholders are the architect, development team, customer, project manager, marketing team, and others.

Now that you have understood some of the core aspects of software architecture, let us briefly list some of its characteristics.

Characteristics of software architecture

All software architectures exhibit a common set of characteristics. Let us look at some of the most important ones here.

An architecture defines a structure

An architecture of a system is best represented as structural details of the system. It is a common practice for practitioners to draw the system architecture as a structural component or class diagram in order to represent the relationships between the subsystems.

For example, the following architecture diagram describes the backend of an application that reads from a tiered database system, which is loaded using an ETL process:

An architecture defines a structure

Example architecture diagram showing system structure

Structures provide insight into architectures, and provide a unique perspective to analyze the architecture with respect to its quality attributes.

Some examples are as follows:

  • The runtime structures, in terms of the objects created at runtime, and how they interact often determine the deployment architecture. The deployment architecture is strongly connected to the quality attributes of scalability, performance, security, and interoperability.
  • The module structures, in terms of how the code is broken down and organized into modules and packages for task breakdown, often has a direct bearing on the maintainability and modifiability (extensibility) of a system. This is explained as follows:
    • Code which is organized with a view to extensibility would often keep the parent classes in separate well-defined packages with proper documentation and configuration, which are then easily extensible by external modules, without the need to resolve too many dependencies.
    • Code which is dependent on external or third-party developers (libraries, frameworks, and the like) would often provide setup or deployment steps, which manually or automatically pull in these dependencies from external sources. Such code would also provide documentation (README, INSTALL, and so on) which clearly documents these steps.

An architecture picks a core set of elements

A well-defined architecture clearly captures only the core set of structural elements required to build the core functionality of the system, and which have a lasting effect on the system. It does not set out to document everything about every component of the system.

For example, an architect describing the architecture of a user interacting with a web server for browsing web pages—a typical client/server architecture—would focus mainly on two components: the user's browser (client) and the remote web server (server), which form the core elements of the system.

The system may have other components such as multiple caching proxies in the path from the server to the client, or a remote cache on the server which speeds up web page delivery. However, this is not the focus of the architecture description.

An architecture captures early design decisions

This is a corollary to the characteristics described previously. The decisions that help an architect to focus on some core elements of the system (and their interactions) are a result of the early design decisions about a system. Thus, these decisions play a major role in further development of the system due to their initial weight.

For example, an architect may make the following early design decisions after careful analysis of the requirements for a system:

  • The system will be deployed only on Linux 64-bit servers, since this satisfies the client requirement and performance constraints
  • The system will use HTTP as the protocol for implementing backend APIs
  • The system will try to use HTTPS for APIs that transfer sensitive data from the backend to frontend using encryption certificates of 2,048 bits or higher
  • The programming language for the system would be Python for the backend, and Python or Ruby for the frontend

Note

The first decision freezes the deployment choices of the system to a large extent to a specific OS and system architecture. The next two decisions have a lot of weight in implementing the backend APIs. The last decision freezes the programming language choices for the system.

Early design decisions need to be arrived at after careful analysis of the requirements and matching them with the constraints—such as organizational, technical, people, and time constraints.

An architecture manages stakeholder requirements

A system is designed and built, ultimately, at the behest of its stakeholders. However, it is not possible to address each stakeholder requirement to its fullest due to an often contradictory nature of such requirements. Following are some examples:

  • The marketing team is concerned with having a full-featured software application, whereas, the developer team is concerned with feature creep and performance issues when adding a lot of features.
  • The system architect is concerned with using the latest technology to scale out his/her deployments to the cloud, while the project manager is concerned about the impact such technology deployments will have on his/her budget. The end user is concerned about correct functionality, performance, security, usability, and reliability, while the development organization (architect, development team, and managers) is concerned with delivering all these qualities while keeping the project on schedule and within budget.
  • A good architecture tries its best to balance out these requirements by making trade-offs, and delivering a system with good quality attributes while keeping the people and resource costs within limits.
  • An architecture also provides a common language among the stakeholders, which allows them to communicate efficiently via expressing these constraints, and helping the architect zero-in on an architecture that best captures these requirements and their trade-offs.

An architecture influences the organizational structure

The system structures an architecture describes, quite often have a direct mapping to the structure of the teams that build those systems.

For example, an architecture may have a data access layer which describes a set of services that read and write large sets of data—it is natural that such a system gets functionally assigned to the database team, which already has the required skill sets.

Since the architecture of a system is its best description of the top-down structures, it is also often used as the basis for the task-breakdown structures. Thus, software architecture often has a direct bearing on the organizational structures that build it:

An architecture influences the organizational structure

System architecture for a search web application

The following diagram shows the mapping to the team structure which would be building this application:

An architecture influences the organizational structure

An architecture is influenced by its environment

An environment imposes outside constraints or limits within which an architecture must function. In the literature, these are often called architecture in context [Ref: Bass, Kazman]. Some examples are as follows:

  • Quality attribute requirements: In modern day web applications, it is very common to specify the scalability and availability requirements of the application as an early technical constraint, and capture it in the architecture. This is an example of a technical context from a business perspective.
  • Standards conformance: In some organizations where there is often a large set of governing standards for software, especially those in the banking, insurance, and health-care domains, these get added to the early constraints of the architecture. This is an example of an external technical context.
  • Organizational constraints: It is common to see that organizations which either have an experience with a certain architectural style or a set of teams operating with certain programming environments which impose such a style (J2EE is a good example), prefer to adopt similar architectures for future projects as a way to reduce costs and ensure productivity due to current investments in such architectures and related skills. This is an example of an internal business context.
  • Professional context: An architect's set of choices for a system's architecture, aside from these outside contexts, is mostly shaped from his/her set of unique experiences. It is common for an architect to continue using a set of architectural choices that he/she has had the most success with in his/her past, for new projects.

Architecture choices also arise from one's own education and professional training, and also from the influence of one's professional peers.

An architecture documents the system

Every system has an architecture, whether it is officially documented or not. However, properly documented architectures can function as an effective documentation for the system. Since an architecture captures the system's initial requirements, constraints, and stakeholder trade-offs, it is a good practice to document it properly. The documentation can be used as a basis for training later on. It also helps in continued stakeholder communication, and for subsequent iterations of the architecture based on changing requirements.

The simplest way to document an architecture is to create diagrams for the different aspects of the system and organizational architecture such as Component Architecture, Deployment Architecture, Communication Architecture, and the Team or Enterprise Architecture.

Other data that can be captured early include the system requirements, constraints, early design decisions, and rationale for those decisions.

An architecture often conforms to a pattern

Most architectures conform to certain sets of styles which have had a lot of success in practice. These are referred to as architectural patterns. Examples of such patterns are client-server, pipes and filters, data-based architectures, and others. When an architect chooses an existing pattern, he/she gets to refer to and reuse a lot of existing use cases and examples related to such patterns. In modern day architectures, the job of the architect comes down to mixing and matching existing sets of such readily available patterns to solve the problem at hand.

For example, the following diagram shows an example of a client-server architecture:

An architecture often conforms to a pattern

Example of client-server architecture

The following diagram describes another common architecture pattern, namely, the pipes and filters architecture for processing streams of data:

An architecture often conforms to a pattern

Example of pipe and filters architecture

We will see examples of architectural patterns later in this book.

Importance of software architecture

So far, we have discussed the fundamental principles of software architecture, and also seen some of its characteristics. These sections, of course, assumed that software architecture is important, and is a critical step of the software development process.

It is time to play devil's advocate, and look back at software architecture and ask some existential questions about it as follows:

  • Why software architecture?
  • Why is software architecture important?
  • Why not build a system without a formal software architecture?

Let us take a look at the critical insights that software architecture provides, which would otherwise be missing from an informal software development process. We are only focusing on the technical or developmental aspects of the system in the following table:

Aspect

Insight/Impact

Examples

Architecture selects quality attributes to be optimized for a system.

Aspects such as scalability, availability, modifiability, security, and so on of a system depend on early decisions and trade-offs while selecting an architecture. You often trade one attribute in favor of another.

A system that is optimized for scalability must be developed using a decentralized architecture where elements are not tightly coupled. For example: microservices, brokers.

Architecture facilitates early prototyping.

Defining an architecture allows the development organization to try and build early prototypes, which gives valuable insights into how the system would behave without having to build the complete system top down.

Many organizations build out quick prototypes of services—typically, by building only the external APIs of these services and mocking the rest of the behavior. This allows for early integration tests and figuring out interaction issues in the architecture early on.

Architecture allows a system to be built component-wise.

Having a well-defined architecture allows the reuse and assembly of existing, readily available components to achieve the functionality without having to implement everything from scratch.

Libraries or frameworks which provide ready-to-use building blocks for services.

For example: web application frameworks such as Django/RoR, and task distribution frameworks such as Celery.

Architecture helps to manage changes to the system.

An architecture allows the architect to scope out changes to the system in terms of components that are affected and those which are not. This helps to keep system changes to a minimum when implementing new features, performance fixes, and so on.

A performance fix for database reads to a system would need changes only to the DB and Data Access Layer (DAL) if the architecture is implemented correctly. It need not touch the application code at all. For example, this is how most modern web frameworks are built.

There are a number of other aspects which are related to the business context of a system, into which architecture provides valuable insights. However, since this is a book mostly on the technical aspects of software architecture, we have limited our discussion to the ones given in the preceding table.

Now, let us take on the second question:

Why not build a system without a formal software architecture?

If you've been following the arguments so far thoroughly, it is not very difficult to see the answer for it. It can, however, be summarized in the following few statements:

  • Every system has an architecture, whether it is documented or not
  • Documenting an architecture makes it formal, allowing it to be shared among stakeholders, making change management and iterative development possible
  • All the other benefits and characteristics of software architecture are ready to be taken advantage of when you have a formal architecture defined and documented
  • You may be still able to work and build a functional system without a formal architecture, but it would not produce a system which is extensible and modifiable, and would most likely produce a system with a set of quality attributes quite far away from the original requirements

System versus enterprise architecture

You may have heard the term architect used in a few contexts. The following job roles or titles are pretty common in the software industry for architects:

  • The Technical architect
  • The Security architect
  • The Information architect
  • The Infrastructure architect

You also may have heard the term System architect, perhaps the term Enterprise architect, and maybe, Solution architect also. The interesting question is: What do these people do?

Let us try and find the answer to this question.

An Enterprise architect looks at the overall business and organizational strategies for an organization, and applies architecture principles and practices to guide the organization through the business, information, process, and technology changes necessary to execute their strategies. The Enterprise architect usually has a higher strategy focus and a lower technology focus. The other architect roles take care of their own subsystems and processes. For example:

  • The Technical architect: The Technical architect is concerned with the core technology (hardware/software/network) used in an organization. A Security architect creates or tunes the security strategy used in applications to fit the organization's information security goals. An Information architect comes up with architectural solutions to make information available to/from applications in a way that facilitates the organization's business goals.

    These specific architectural roles are all concerned with their own systems and subsystems. So, each of these roles is a System architect role.

    These architects help the Enterprise architect to understand the smaller picture of each of the business domain they are responsible for, which helps the Enterprise architect to get information that will aid him in formulating business and organizational strategies.

  • The System architect: A System architect usually has a higher technology focus and a lower strategy focus. It is a practice in some service-oriented software organizations to have a Solution architect, who combines the different systems to create a solution for a specific client. In such cases, the different architect roles are often combined into one, depending on the size of the organization, and the specific time and cost requirements of the project.
  • The Solution architect: A Solution architect typically straddles the middle position when it comes to strategy versus technology focus and organizational versus project scope.

The following schematic diagram depicts the different layers in an organization–Technology, Application, Data, People, Process, and Business, and makes the focus area of the architect roles very clear:

System versus enterprise architecture

Enterprise versus System architects

Let's discuss the preceding diagram a bit to understand the picture it lays out.

The System architect is pictured on the bottom-left side of the diagram, looking at the system components of the enterprise. His/her focus is on the applications that power the enterprise, their data, and the hardware and software stack powering the applications.

The Enterprise architect, on the other hand, is pictured on the top, having a top-down view of the enterprise including the business goals and the people, and not just the underlying systems that power the organization. The vertical stack of business processes connect the technical components that power the organization with its people and business components. These processes are defined by the Enterprise architect in discussion with the other stakeholders.

Now that you have understood the picture behind Enterprise and System architecture, let us take a look at some formal definitions:

"Enterprise Architecture is a conceptual blueprint that defines the structure and behavior of an organization. It determines how the organization's structure, processes, personnel and flow of information is aligned to its core goals to efficiently achieve its current and future objectives."

"A system architecture is the fundamental organization of a system, represented by its structural and behavioral views. The structure is determined by the components of the system and the behavior by the relationships between them and their interaction with external systems."

An Enterprise architect is concerned with how the different elements in an organization and their interplay is tuned towards achieving the goals of the organization in an efficient manner. In this work, he/she needs the support of not just the technical architects in the organization, but also people managing the organization, such as project managers and human resource professionals.

A Systems architect, on the other hand, is worried about how the core system architecture maps to the software and hardware architecture, and the various details of human interactions with the components in the system. His/her concern never arises above the boundaries defined by the system and its interactions.

The following diagram depicts the different focus areas and scopes of the different architect roles that we've discussed so far:

System versus enterprise architecture

Scope and focus of various architect roles in a software organization

Architectural quality attributes

Let us now focus on an aspect which forms the main topic for the rest of this book–Architectural Quality Attributes.

In a previous section, we discussed how an architecture balances and optimizes stakeholder requirements. We also saw some examples of contradicting stakeholder requirements, which an architect seeks to balance, by choosing an architecture which does the necessary trade-offs.

The term quality attribute has been used to loosely define some of these aspects that an architecture makes trade-offs for. It is now the time to formally define what an Architectural Quality Attribute is:

"A quality attribute is a measurable and testable property of a system which can be used to evaluate the performance of a system within its prescribed environment with respect to its non-functional aspects"

There are a number of aspects that fit this general definition of an architectural quality attribute. However, for the rest of this book, we will be focusing on the following quality attributes:

  • Modifiability
  • Testability
  • Scalability and performance
  • Availability
  • Security
  • Deployability

Modifiability

Many studies show that about 80% of the cost of a typical software system occurs after the initial development and deployment. This shows how important modifiability is to a system's initial architecture.

Modifiability can be defined as the ease with which changes can be made to a system, and the flexibility with which the system adjusts to the changes. It is an important quality attribute, as almost every software system changes over its lifetime—to fix issues, for adding new features, for performance improvements, and so on.

From an architect's perspective, the interest in modifiability is about the following:

  • Difficulty: The ease with which changes can be made to a system
  • Cost: In terms of time and resources required to make the changes
  • Risks: Any risk associated with making changes to the system

Now, what kind of changes are we talking about here? Is it changes to code, changes to deployment, or changes to the entire architecture?

The answer is: it can be at any level.

From an architecture perspective, these changes can generally be captured at the following three levels:

  1. Local: A local change only affects a specific element. The element can be a piece of code such as a function, a class, a module, or a configuration element such as an XML or JSON file. The change does not cascade to any neighboring element or to the rest of the system. Local changes are the easiest to make, and the least risky of all. The changes can usually be quickly validated with local unit tests.
  2. Non-local: These changes involve more than one element. The examples are as follows:
    • Modifying a database schema, which then needs to cascade into the model class representing that schema in the application code
    • Adding a new configuration parameter in a JSON file, which then needs to be processed by the parser parsing the file and/or the application(s) using the parameter

    Non-local changes are more difficult to make than local changes, require careful analysis, and wherever possible, integration tests to avoid code regressions.

  3. Global: These changes either involve architectural changes from top down, or changes to elements at the global level, which cascade down to a significant part of the software system. The examples are as follows:
    • Changing a system's architecture from RESTful to messaging (SOAP, XML-RPC, and others) based web services
    • Changing a web application controller from Django to an Angular-js based component
    • A performance change requirement which needs all data to be preloaded at the frontend to avoid any inline model API calls for an online news application

    These changes are the riskiest, and also the costliest, in terms of resources, time and money. An architect needs to carefully vet the different scenarios that may arise from the change, and get his/her team to model them via integration tests. Mocks can be very useful in these kinds of large-scale changes.

The following table shows the relationship between Cost and Risk for the different levels of system modifiability:

Level

Cost

Risk

Local

Low

Low

Non-local

Medium

Medium

Global

High

High

Modifiability at the code level is also directly related to its readability:

"The more readable a code is, the more modifiable it is. Modifiability of a code goes down in proportion to its readability."

The modifiability aspect is also related to the maintainability of the code. A code module which has its elements very tightly coupled would yield to modification much less than a module which has a loosely coupled elements—this is the Coupling aspect of modifiability.

Similarly, a class or module which does not define its role and responsibilities clearly would be more difficult to modify than another one which has well-defined responsibility and functionality. This aspect is called Cohesion of a software module.

The following table shows the relation between Cohesion, Coupling, and Modifiability for an imaginary module A. Assume that the coupling is from this module to another module B:

Cohesion

Coupling

Modifiability

Low

High

Low

Low

Low

Medium

High

High

Medium

High

Low

High

It is pretty clear from the preceding table that having higher Cohesion and lower Coupling is the best scenario for the modifiability of a code module.

Other factors that affect modifiability are as follows:

  • Size of a module (number of lines of code): Modifiability decreases when size increases.
  • Number of team members working on a module: Generally, a module becomes less modifiable when a larger number of team members work on the module due to the complexities in merging and maintaining a uniform code base.
  • External third-party dependencies of a module: The larger the number of external third-party dependencies, the more difficult it is to modify the module. This can be thought of as an extension of the coupling aspect of a module.
  • Wrong use of the module API: If there are other modules which make use of the private data of a module rather than (correctly) using its public API, it is more difficult to modify the module. It is important to ensure proper usage standards of modules in your organization to avoid such scenarios. This can be thought of as an extreme case of tight Coupling.

Testability

Testability refers to how much a software system is amenable to demonstrating its faults through testing. Testability can also be thought of as how much a software system hides its faults from end users and system integration tests—the more testable a system is, the less it is able to hide its faults.

Testability is also related to how predictable a software system's behavior is. The more predictable a system, the more it allows for repeatable tests, and for developing standard test suites based on a set of input data or criteria. Unpredictable systems are much less amenable to any kind of testing, or, in extreme case, not testable at all.

In software testing, you try to control a system's behavior by, typically, sending it a set of known inputs, and then observing the system for a set of known outputs. Both of these combine to form a testcase. A test suite or test harness, typically, consists of many such test cases.

Test assertions are the techniques that are used to fail a test case when the output of the element under the test does not match the expected output for the given input. These assertions are usually manually coded at specific steps in the test execution stage to check the data values at different steps of the testcase:

Testability

Representative flowchart of a simple unit test case for function f('X') = 'Y'

The preceding diagram shows an example of a representative flowchart for a testable function "f" for a sample input "X" with expected output "Y".

In order to recreate the session or state at the time of a failure, the record/playback strategy is often used. This employs specialized software (such as Selenium), which records all user actions that led to a specific fault, and saves it as a testcase. The test is reproduced by replaying the testcase using the same software which tries to simulate the same testcase; this is done by repeating the same set and order of UI actions.

Testability is also related to the complexity of code in a way very similar to modifiability. A system becomes more testable when parts of it can be isolated and made to work independent of the rest of the system. In other words, a system with low coupling is more testable than a system with high coupling.

Another aspect of testability, which is related to the predictability mentioned earlier, is to reduce non-determinism. When writing test suites, we need to isolate the elements that are to be tested from other parts of the system which have a tendency to behave unpredictably so that the tested element's behavior becomes predictable.

An example is a multi-threaded system, which responds to events raised in other parts of the system. The entire system is probably quite unpredictable, and not amenable to repeated testing. Instead, one needs to separate the events subsystem, and possibly, mock its behavior so that those inputs can be controlled, and the subsystem which receives the events becomes predictable and hence, testable.

The following schematic diagram explains the relationship between the testability and predictability of a system to the Coupling and Cohesion between its components:

Testability

Relation of testability and predictability of a system to coupling and cohesion

Scalability

Modern-day web applications are all about scaling up. If you are part of any modern-day software organization, it is very likely that you have heard about or worked on an application that is written for the cloud, which is able to scale up elastically on demand.

Scalability of a system is its capacity to accommodate increasing workload on demand while keeping its performance within acceptable limits.

Scalability in the context of a software system, typically, falls into two categories, which are as follows:

  • Horizontal scalability: Horizontal scalability implies scaling out/in a software system by adding more computing nodes to it. Advances in cluster computing in the last decade have given rise to the advent of commercial horizontally scalable elastic systems as services on the web. A well-known example is Amazon Web Services. In horizontally scalable systems, typically, data and/or computation is done on units or nodes, which are, usually, virtual machines running on commodity systems known as virtual private servers (VPS). The scalability is achieved "n" times by adding n or more nodes to the system, typically fronted by a load balancer. Scaling out means expanding the scalability by adding more nodes, and scaling in means reducing the scalability by removing existing nodes:
    Scalability

    Example deployment architecture showing horizontally scaling a web application server

  • Vertical scalability: Vertical scalability involves adding or removing resources from a single node in a system. This is usually done by adding or removing CPUs or RAM (memory) from a single virtual server in a cluster. The former is called scaling up, and the latter, scaling down. Another kind of scaling up is increasing the capacity of an existing software process in the system—typically, by augmenting its processing power. This is usually done by increasing the number of processes or threads available to an application. Some examples are as follows:
    • Increasing the capacity of an Nginx server process by increasing its number of worker processes
    • Increasing the capacity of a PostgreSQL server by increasing its number of maximum connections

Performance

Performance of a system is related to its scalability. Performance of a system can be defined as follows:

"Performance of a computer system is the amount of work accomplished by a system using a given unit of computing resource. Higher the work/unit ratio, higher the performance."

The unit of computing resource to measure performance can be one of the following:

  • Response time: How much time a function or any unit of execution takes to execute in terms of real time (user time) and clock time (CPU time).
  • Latency: How much time it takes for a system to get its stimulation, and then provide a response. An example is the time it takes for the request-response loop of a web application to complete, measured from the end-user perspective.
  • Throughput: The rate at which a system processes its information. A system which has higher performance would usually have a higher throughput, and correspondingly higher scalability. An example is the throughput of an e-commerce website measured as the number of transactions completed per minute.

Performance is closely tied to scalability, especially, vertical scalability. A system that has excellent performance with respect to its memory management would easily scale up vertically by adding more RAM.

Similarly, a system that has multi-threaded workload characteristics and is written optimally for a multicore CPU, would scale up by adding more CPU cores.

Horizontal scalability is thought of as having no direct connection to the performance of a system within its own compute node. However, if a system is written in a way that it doesn't utilize the network effectively, thereby producing network latency issues, it may have a problem scaling horizontally effectively, as the time spent on network latency would offset any gain in scalability obtained by distributing the work.

Some dynamic programming languages such as Python have built-in scalability issues when it comes to scaling up vertically. For example, the Global Interpreter Lock (GIL) of Python (CPython) prevents it from making full use of the available CPU cores for computing by multiple threads.

Availability

Availability refers to the property of readiness of a software system to carry out its operations when the need arises.

Availability of a system is closely related to its reliability. The more reliable a system is, the more available it is.

Another factor which modifies availability is the ability of a system to recover from faults. A system may be very reliable, but if the system is unable to recover either from complete or partial failures of its subsystems, then it may not be able to guarantee availability. This aspect is called recovery.

The availability of a system can be defined as follows:

"Availability of a system is the degree to which the system is in a fully operable state to carry out its functionality when it is called or invoked at random."

Mathematically, this can be expressed as follows:

Availability = MTBF/(MTBF + MTTR)

Take a look at the following terms used in the preceding formula:

  • MTBF: Mean time between failures
  • MTTR: Mean time to repair

This is often called the mission capable rate of a system.

Techniques for Availability are closely tied to recovery techniques. This is due to the fact that a system can never be 100% available. Instead, one needs to plan for faults and strategies to recover from faults, which directly determines the availability. These techniques can be classified as follows:

  • Fault detection: The ability to detect faults and take action helps to avert situations where a system or parts of a system become unavailable completely. Fault detection typically involves steps such as monitoring, heartbeat, and ping/echo messages, which are sent to the nodes in a system, and the response measured to calculate if the nodes are alive, dead, or are in the process of failing.
  • Fault recovery: Once a fault is detected, the next step is to prepare the system to recover from the fault and bring it to a state where the system can be considered available. Typical tactics used here include Hot/Warm Spares (Active/Passive redundancy), Rollback, Graceful Degradation, and Retry.
  • Fault prevention: This approach uses active methods to anticipate and prevent faults from occurring so that the system does not have a chance to go to recovery.

Availability of a system is closely tied to the consistency of its data via the CAP theorem which places a theoretical limit on the trade-offs a system can make with respect to consistency versus availability in the event of a network partition. The CAP theorem states that a system can choose between being consistent or being available—typically leading to two broad types of systems, namely, CP (consistent and tolerant to network failures) and AP (available and tolerant to network failures).

Availability is also tied to the system's scalability tactics, performance metrics, and its security. For example, a system that is highly horizontally scalable would have a very high availability, since it allows the load balancer to determine inactive nodes and take them out of the configuration pretty quickly.

A system which, instead, tries to scale up may have to monitor its performance metrics carefully. The system may have availability issues even when the node on which the system is fully available if the software processes are squeezed for system resources, such as CPU time or memory. This is where performance measurements become critical, and the system's load factor needs to be monitored and optimized.

With the increasing popularity of web applications and distributed computing, security is also an aspect that affects availability. It is possible for a malicious hacker to launch remote denial of service attacks on your servers, and if the system is not made foolproof against such attacks, it can lead to a condition where the system becomes unavailable or only partially available.

Security

Security, in the software domain, can be defined as the degree of ability of a system to avoid damage to its data and logic from unauthenticated access, while continuing to provide services to other systems and roles that are properly authenticated.

A security crisis or attack occurs when a system is intentionally compromised with a view to gaining illegal access to it in order to compromise its services, copy, or modify its data, or deny access to its legitimate users.

In modern software systems, the users are tied to specific roles which have exclusive rights to different parts of the system. For example, a typical web application with a database may define the following roles:

  • user: End user of the system with login and access to his/her private data
  • dbadmin: Database administrator, who can view, modify, or delete all database data
  • reports: Report admin, who has admin rights only to those parts of database and code that deal with report generation
  • admin: Superuser, who has edit rights to the complete system

This way of allocating system control via user roles is called access control. Access control works by associating a user role with certain system privileges, thereby decoupling the actual user login from the rights granted by these privileges.

This principle is the Authorization technique of security.

Another aspect of security is with respect to transactions where each person must validate the actual identity of the other. Public key cryptography, message signing, and so on are common techniques used here. For example, when you sign an e-mail with your GPG or PGP key, you are validating yourself—The sender of this message is really me, Mr. A—to your friend Mr. B on the other side of the e-mail. This principle is the Authentication technique of security.

The other aspects of security are as follows:

  • Integrity: These techniques are used to ensure that data or information is not tampered with in anyway on its way to the end user. Examples are message hashing, CRC Checksum, and others.
  • Origin: These techniques are used to assure the end receiver that the origin of the data is exactly the same as where it is purporting to be from. Examples of this are SPF, Sender-ID (for e-mail), Public Key Certificates and Chains (for websites using SSL), and others.
  • Authenticity: These are the techniques which combine both the Integrity and Origin of a message into one. This ensures that the author of a message cannot deny the contents of the message as well as its origin (himself/herself). This typically uses Digital Certificate Mechanisms.

Deployability

Deployability is one of those quality attributes which is not fundamental to the software. However, in this book, we are interested in this aspect, because it plays a critical role in many aspects of the ecosystem in the Python programming language and its usefulness to the programmer.

Deployability is the degree of ease with which software can be taken from the development to the production environment. It is more of a function of the technical environment, module structures, and programming runtime/languages used in building a system, and has nothing to do with the actual logic or code of the system.

The following are some factors that determine deployability:

  • Module structures: If your system has its code organized into well-defined modules/projects which compartmentalize the system into easily deployable subunits, the deployment is much easier. On the other hand, if the code is organized into a monolithic project with a single setup step, it would be hard to deploy the code into a multiple node cluster.
  • Production versus development environment: Having a production environment which is very similar to the structure of the development environment makes deployment an easy task. When the environments are similar, the same set of scripts and toolchains that are used by the developers/DevOps team can be used to deploy the system to a development server as well as a production server with minor changes—mostly in the configuration.
  • Development ecosystem support: Having a mature tool-chain support for your system runtime, which allows configurations such as dependencies to be automatically established and satisfied, increases deployability. Programming languages such as Python are rich in this kind of support in its development ecosystem, with a rich array of tools available for the DevOps professional to take advantage of.
  • Standardized configuration: It is a good idea to keep your configuration structures (files, database tables, and others) the same for both developer and production environments. The actual objects or filenames can be different, but if the configuration structures vary widely across both the environments, deployability decreases, as extra work is required to map the configuration of the environment to its structures.
  • Standardized infrastructure: It is a well-known fact that keeping your deployments to a homogeneous or standardized set of infrastructure greatly aids deployability. For example, if you standardize your frontend application to run on 4 GB RAM, Debian-based 64-bit Linux VPS, then it is easy to automate deployment of such nodes—either using a script, or by using elastic compute approaches of providers such as Amazon—and to keep a standard set of scripts across both development and production environments. On the other hand, if your production deployment consists of heterogeneous infrastructure, say, a mix of Windows and Linux servers with varying capacities and resource specifications, the work typically doubles for each type of infrastructure decreasing deployability.
  • Use of containers: The user of container software, popularized by the advent of technology such as Docker and Vagrant built on top of Linux containers, has become a recent trend in deploying software on servers. The use of containers allows you to standardize your software, and makes deployability easier by reducing the amount of overhead required to start/stop the nodes, as containers don't come with the overhead of a full virtual machine. This is an interesting trend to watch for.

Summary

In this chapter, we learned about software architecture. We saw the different aspects of software architecture, and learned that every architecture comprises a system, which has a structure working in an environment for its stakeholders. We briefly looked at how software architecture differs from software design.

We went on to look at various characteristics of software architecture such as how a software architecture defines a structure, picks a core set of elements, and connects stakeholders.

We then addressed the important question of the importance of software architecture to an organization, and why it is a good idea to have a formal software architecture defined for your software systems.

The distinction of different roles of architects in an organization was discussed next. We saw the various roles system architects play in an organization, and how an Enterprise architect's focus is different from that of the System architect. The focus of strategy and technology breadth versus technology depth was clarified with illustrations.

We then discussed the elements of the main theme of this book—Architectural Quality Attributes. We defined what a quality attribute is, and then looked, in quite some detail, at the quality attributes of Modifiability, Testability, Scalability/Performance, Security, and Deployability. While going into the details of these attributes, we discussed their definitions, techniques, and how they relate to each other.

With this chapter serving as the base, we are now ready to take on these quality attributes, and then discuss in detail the various tactics and techniques to achieve them using the Python programming language. That forms the rest of this book.

In the next chapter, we'll start with one of the very first quality attributes we discussed in this chapter, namely, Modifiability and its associated attribute, Readability.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Identify design issues and make the necessary adjustments to achieve improved performance
  • Understand architectural quality attributes from the perspective of a practicing engineer and architect using Python
  • Learn architectural principles and how they can be used to provide accountability and rationale for architectural decisions

Description

This book starts by explaining how Python fits into an application's architecture. As you move along, you will get to grips with architecturally significant demands and how to determine them. Later, you’ll gain a complete understanding of the different architectural quality requirements for building a product that satisfies business needs, such as maintainability/reusability, testability, scalability, performance, usability, and security. You will also use various techniques such as incorporating DevOps, continuous integration, and more to make your application robust. You will discover when and when not to use object orientation in your applications, and design scalable applications. The focus is on building the business logic based on the business process documentation, and understanding which frameworks to use and when to use them. The book also covers some important patterns that should be taken into account while solving design problems, as well as those in relatively new domains such as the Cloud. By the end of this book, you will have understood the ins and outs of Python so that you can make critical design decisions that not just live up to but also surpassyour clients’ expectations.

Who is this book for?

This book is for experienced Python developers who want to become architects of enterprise-grade applications or software architects who would like to leverage Python to create effective application blueprints.

What you will learn

  • Build programs with the right architectural attributes
  • Use Enterprise Architectural Patterns to solve scalable problems on the Web
  • Understand design patterns from a Python perspective
  • Optimize performance testing tools in Python
  • Deploy code in remote environments or on the Cloud using Python
  • Secure architecture applications in Python

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Apr 28, 2017
Length: 556 pages
Edition : 1st
Language : English
ISBN-13 : 9781786467225
Category :
Languages :

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want

Product Details

Publication date : Apr 28, 2017
Length: 556 pages
Edition : 1st
Language : English
ISBN-13 : 9781786467225
Category :
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 158.97
Python Data Structures and Algorithms
$48.99
Python GUI Programming Cookbook, Second Edition
$54.99
Software Architecture with Python
$54.99
Total $ 158.97 Stars icon

Table of Contents

11 Chapters
1. Principles of Software Architecture Chevron down icon Chevron up icon
2. Writing Modifiable and Readable Code Chevron down icon Chevron up icon
3. Testability – Writing Testable Code Chevron down icon Chevron up icon
4. Good Performance is Rewarding! Chevron down icon Chevron up icon
5. Writing Applications that Scale Chevron down icon Chevron up icon
6. Security – Writing Secure Code Chevron down icon Chevron up icon
7. Design Patterns in Python Chevron down icon Chevron up icon
8. Python – Architectural Patterns Chevron down icon Chevron up icon
9. Deploying Python Applications Chevron down icon Chevron up icon
10. Techniques for Debugging Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.5
(6 Ratings)
5 star 33.3%
4 star 16.7%
3 star 33.3%
2 star 0%
1 star 16.7%
Filter icon Filter
Top Reviews

Filter reviews by




Bhuvneshwar Chouksey Nov 06, 2018
Full star icon Full star icon Full star icon Full star icon Full star icon 5
#DeepThought#Coding Skills#Lib Overriding#Giving Confidence to create your own module using existing available functionality with extra features#For R&D Guys #Maturity is very HIGH#Papar Quality Ultimate#All d Best guys for creating better Future.
Amazon Verified review Amazon
David Q Mertz May 09, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Anand PIllai touches on a really encyclopedic range of topics with clarity and precision. I'm accustomed to reading books on programming, but this one (as its title fairly indicates) is a different sort of beast. There are definitely very informative chapters on Python programming topics, but the emphasis here is on overall development and engineering practices, and as such serves as a great reference text for software development groups and managers.The many architecture challenges faced by large Python projects are addressed in Anand's book (I confess I've been his colleague and friend for over a decade, hence on first-name terms). It touches on concurrency and parallelism issues, on testing frameworks and best practices, on good documentation practice, on security, and on performance analysis, as well as more topics. It's a long book; but even at such length, any one book must be a guide to the issues that need to be considered rather than in depth documentation of all the relevant tools and libraries. Anand gives you enough to know where to look further, and to evaluate the overall trade-offs among approaches.A challenge in a book like this—which Anand does not wholly overcome—is that any sample code which can be shown on a page or two is automatically somewhat "toy code." As a result, much of the code is somewhat unrealistic to real-world large codebases, and in many cases of necessity represents less than ideal coding choices. Nonetheless, his surrounding text presents well the larger points we are meant to draw from code samples, and these points apply equally, or better, to large projects.
Amazon Verified review Amazon
kracekumar May 09, 2017
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
The book Software Architecture with Python explains various aspects of software architecture like testability, performance, scaling, concurrency and design patterns.The book has ten chapters. The first chapter speaks about different architect roles like solution architect, enterprise architect, technical architect what is the role of an architect and difference between design and architecture. This chapter is theory but worth to know the differences as a software developer.The book covers two lesser spoken topics debugging and code security which I liked. There is very few literature available on debugging. The author has provided real use cases of different debugging tips and tools for Python without picking sides. The book has some good examples on overflow errors in Python.My favorite chapter in the book is 'Writing Applications that scale'. The author explains all the available concurrency primitives like threading, multiprocess, eventlet, twisted, gevent, asyncio, queues, semaphore, locking etc . The author doesn't stop by explaining how to use them but paves the path to figuring out how to profile the code, find out where the bottleneck lies and when to use which concurrency primitives. This chapter is the longest in the book and deluged with examples and insights. The author's approach of using `time` command to measure the performance rather than sticking with wall-clock time gives the developer understanding of where programming is spending most of the time.The book covers vital details on implementing Python Design Patterns and how Python's dynamic nature brings joy while creating the creational, structural and design pattern. The showcased examples teach how Python metaclass works and it's simplicity.The book is indeed a long read and solid one in size and content. Having said that book is pretty hands on and loaded with trivial and non-trivial examples. I won't be surprised if half the book covers the code snippets. The author hasn't shied away from skipping code snippets while explaining any concept. The book introduces a plethora of tools for developing software, and at the same time references required literature and resources.
Amazon Verified review Amazon
sh Apr 04, 2018
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
This book is easy to read and understand, as long as you have an understanding of Python. The example code illustrates the point the author is trying to convey. The main problem, and the reason I deducted 2 stars, is there are a lot of typos. Every 2 or 3 pages, has some sort of typo. There are also some bugs in the code examples (i.e. setting a variable with a value, and then referencing the value instead of the variable name). There is even at least one code example where all of the code is left-justified, so it makes the code technically incorrect without any indentation.
Amazon Verified review Amazon
Paul Hoffman Jul 01, 2017
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
The book is a bit light on usable Python content. It feels like the book started off as "Software Architecture" and then the author plugged in Python at the end.If you're used to well-produced books, this one might set your teeth on edge. The book could use a much better copyedit than what it got, the artwork is amateurish, and the page layout looks like it was chosen to make the book longer.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

How do I buy and download an eBook? Chevron down icon Chevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website? Chevron down icon Chevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook? Chevron down icon Chevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see www.packtpub.com/support and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to www.packtpub.com/account
  • To contact us directly if a problem is not resolved, use www.packtpub.com/contact-us
What eBook formats do Packt support? Chevron down icon Chevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks? Chevron down icon Chevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook? Chevron down icon Chevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.