Connectors are the mechanisms that allow interaction and collaboration between different software components. They are responsible for transmitting data and control between components, which is essential to achieve a cohesive and efficient software architecture. Connectors can also handle aspects such as data transformation and control coordination, especially in more complex systems.

There are different types of connectors, each with specific characteristics and purposes. Some of the most common connectors include:

  • Procedure Calls: This is probably the most common type of connector and is used when a component needs to invoke the functionality of another component.
  • Events: In event-based systems, a component (the sender) generates an event that one or more components (the receivers) can capture and respond to. This type of connector is essential in event-driven architectures.
  • Shared Databases: This connector is used when two or more components need to share information through a common database.
  • Message Queues: In distributed systems, message queues are used to enable components to communicate asynchronously.
  • Web Services or REST APIs: In microservices-based architectures, REST APIs are commonly used as connectors between different microservices.

It is crucial to choose the correct type of connectors to ensure that software components communicate and collaborate efficiently. The choice of connector depends on various factors, such as performance requirements, security, scalability, and specific characteristics of the system and its execution environment. Therefore, when designing software architecture, special attention should be given to the choice and design of connectors.

Procedure Calls

Procedure calls are a common form of interaction between software components. When using this type of connector, a component (the caller) executes a function or method belonging to another component (the callee).

The procedure call is a synchronous connection mechanism, which means that the calling component is blocked and waits until the called procedure has completed its execution and returned control. This style of interaction is common in many software architectures and is particularly prevalent in object-oriented programming.

A procedure call generally consists of:

  • Invocation: The calling component invokes a procedure of the called component, passing arguments if necessary.
  • Execution: The called component executes the procedure, which may involve performing calculations, manipulating data, or invoking other procedures.
  • Return: Once the procedure has finished executing, control is returned to the calling component. If the procedure is designed to return a value, this value is passed to the caller at the time of the return.

Procedure calls are a very direct and efficient method of connection. They allow for strong cohesion between components and provide a straightforward way to share data and functionality. However, they can also result in strong coupling between components, which may reduce the modularity and flexibility of the system. In particular, the use of synchronous procedure calls can lead to blocking and decreased responsiveness if not handled correctly.

Procedure Calls

 

Events

Events are another common form of interaction between software components. In an event-based model, a component (the sender) generates an event that represents a certain condition or change of state. Other components (listeners or subscribers) may be interested in that event and react to it.

Events are an asynchronous connection mechanism, which means that the sender does not block and does not wait for listeners to respond. Instead, it simply emits the event and then continues with its own execution. Listeners that are interested in the event will process it when they can.

An event generally consists of:

  • Emission: The sender generates an event, possibly including some data related to the event.
  • Broadcast: The event is broadcasted to all interested listeners. This can be done through an "event bus" that manages event delivery, or listeners can register directly with the sender to receive its events.
  • Handling: Each listener receives the event and decides what to do with it. This may involve executing some code in response to the event, updating its internal state, emitting its own events, or any combination of the above.

Events are a powerful and flexible way to connect components. They allow for loose coupling between the sender and listeners, which can increase the modularity and reusability of the system. Events also enable a reactive programming style, where components respond to changes rather than following a predetermined flow of control.

However, event-based systems can be more challenging to understand and debug than those using procedure calls since the flow of control is not linear, and it can be difficult to trace how and when events are handled. Issues may also arise if events are lost, delivered out of order, or handled inconsistently.

Events

 

Shared Databases

A shared database is a form of connection where two or more software components interact by sharing the same set of data, rather than doing so through procedure calls or events. The database acts as a common repository that any component can read from or write to.

For example, one component may be responsible for updating certain data in the database, while other components may read that data to carry out their own business logic. This is a common approach in enterprise software architectures, where different components often need to access and manipulate the same data.

One of the main advantages of this approach is that it can simplify the sharing of data between components since all can read and write to the same database. It can also provide a consistent and reliable way to manage data, especially if the database has features such as transactions and locking to ensure coherence and avoid race conditions.

However, sharing a database can also lead to problems. It can result in tight coupling between components since they all depend on the same database and possibly the same database schema. This can make it more challenging to change or evolve the database schema, as any change could affect all components using it.

Additionally, competition for database resources can arise, affecting the system's performance. If the database goes down, all components depending on it can also be affected.

Due to these issues, shared databases are typically used with caution and combined with other forms of connection, such as procedure calls and events. In particular, modern architectures like microservices often avoid sharing databases between different services, favoring approaches like APIs and events for data exchange.

Shared Databases

Message Queues

Message queues are a method of connection between software components that use a queue to store messages that need to be processed. Instead of sending a message directly from one component to another, the sender places the message in a queue, and the receiver extracts it from the queue to process it.

Message queues provide loose coupling between components and allow for asynchronous communication. This means that the sender and receiver do not need to be active at the same time for the message to be transmitted. Additionally, message queues can help manage load in high-traffic systems, as messages can accumulate in the queue to be processed when the system has the capacity to do so.

The main advantage of message queues is that they allow for loose coupling and asynchronous communication. This can make the system more scalable and resilient, as components can continue to function even if other components are down or busy. Additionally, message queues can help manage load and prevent the system from being overwhelmed during times of high traffic.

However, message queues also have their disadvantages. On one hand, they can introduce additional latency since messages must be placed in the queue and then extracted from it. Additionally, if a component places a large number of messages in the queue, it can become full and result in message loss. It can also be more challenging to trace the flow of application logic since messages are processed asynchronously.

Furthermore, the use of message queues may require additional infrastructure, such as a message queue server, and can complicate error handling, as errors can occur at any point in the message chain.

Message Queues

 

Web Services or REST APIs

REST APIs (Representational State Transfer) are a type of web service that provides an interface for interacting with a web server using the HTTP protocol. RESTful web services are built around standard HTTP methods such as GET, POST, PUT, and DELETE to perform operations on resources.

A resource in a RESTful web service is an abstraction of an entity in the system being designed. Each resource is uniquely identified by a URI (Uniform Resource Identifier). The key advantage of REST APIs is their simplicity. By using the HTTP protocol, they easily integrate with existing Internet infrastructure.

REST APIs offer several advantages. They are simple to use and understand, as they use standard HTTP methods. Being stateless, they allow requests to be processed independently of each other, which can facilitate scalability. Additionally, they can be used to connect software components running on different programming languages or platforms.

On the other hand, REST APIs also have some disadvantages. One of the most significant is that they are synchronous, meaning the client must wait for a response before proceeding. This can be problematic if requests are slow or if the server is overloaded. Additionally, being text-based (usually in JSON format), they may be less efficient than other options for transmitting large volumes of data or binary data.

Overall, REST APIs are a popular choice for connecting software components on the web due to their simplicity and ability to integrate with existing Internet infrastructure.

Web Services