Skip to main content

12 posts tagged with "software"

View All Tags

Clean code: Write The Code You Want To Read (Part 2)

· 5 min read
Reda Jaifar
Lead Developer

author photo source

Functions

Functions constitute a centric component in the recent software programs, the reason why we should care a lot about all of their aspects from naming, length, composition, arguments and error handling.

Small

Yes "small" is the main rule a function should comply with, so it tell us what it does exactly because a function should do one thing, do it well and only.

To keep the function also short, [if, else, while, etc ...] statements should be only one line, and probably this line is function call:

fun bookTrain(bookingRequest: BookingRequest): Booking {
validBookingRequest(bookingRequest)
val booking = Booking.from(bookingRequest)
booking.status(BookingStatus.PENDING)
return booking
}

Single abstraction level

Or the principle of "Doing one thing", the idea is not about writing function with single line of code, or one step but writing it with the restriction to cover only one computation, see example below:

   fun validBookingRequest(bookingRequest: BookingRequest) {
if (bookingRequest.from == bookingRequest.to) {
throw InvalidBookingRequestException("departure and arrival stations are the same")
} else if (bookignRequest.stops > 5) {
throw InvalidBookingRequestException("more than 5 stops is not allowed")
}

}

The Step-down rule

We write code to be read, so writing functions in an order like a narrative text, if we have to put the functions of the above two examples, they should appear in the following order:

   fun bookTrain(bookingRequest: BookingRequest): Booking {
validBookingRequest(bookingRequest)
...

fun validBookingRequest(bookingRequest: BookingRequest) {
...

we can see clearly that the caller function is above the called one

Switch statements

While switch statement can easily impact badly you clean code, The key issue with switch statements is that they often lead to violations of the Single Responsibility Principle (SRP) and can make code harder to extend and maintain.

   fun calculateWashCost(vehicle: Vehicle): Money {
when (vehicle.type) {
CAR -> calculateCarWashCost(vehicle)
BUS -> calculateBusWashCost(vehicle)
MOTOCYCLE -> calculateMotoCycleWashCost(vehicle)
else -> {
throw InvalidVehiculeType(vehicle.type)
}
}
}

There many issues with this function above, first the function is large and each time new vehicle type will be added, it will grow even more. Second it violates the Single Responsibility Principle (SRP) because there is more one reason for it to change, but the worst probem is there will be more functions that will have the same structure:

  • CalculateParkingCost(vehicle: Vehicle): Money
  • CalculateCarbonTax(vehicle: Vehicle): Money

A solution proposed by Robert C.Martin is his book "Clean Code" is to hide the switch statement in an abstract factory, and the factory will use the switch statement to create the appropriate instances of the derivatives of Vehicle. And the various functions such as CalculateParkingCost, CalculateCarbonTax will be dispatched polymorphic through the Vehicle interface.


abstract class Vehicle {
abstract fun calculateWashCost(): Money
abstract fun calculateParkingCost(): Money
abstract fun calculateCarbonTax(): Money
}

abstract interface VehicleFactory {
abstract fun createVehicle(vehicle: Vehicle): Vehicle
}

class VehicleFactoryImpl() {
fun createVehicle(vehicle: Vehicle): Vehicle {
return when (vehicle.type) {
CAR -> Car(vehicle)
BUS -> Bus(vehicle)
MOTOCYCLE -> MotoCycle(vehicle)
else -> {
throw InvalidVehiculeType(vehicle.type)
}
}
}
}

Functions common patterns

Don't hesitate to make your function's name long if necessary in order to ensure a significant name. When it comes to function argument the ideal number is 3, then comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. The challenge with arguments resides in testing you can imagine the difficulty of writing all the test cases to ensure that all the various combinations of arguments work correctly. Have you ever heard about "Flag Argument"? Flag argument is an argument of type boolean where the function do a thing when it's true and another thing if it's false, these arguments violates the Single Responsibility Principle (SRP).

Argument Objects

If a function needs more than two or three arguments, there is probably a way to wrap some of them into an object, see the following example:

  fun deployApplication(applicationId: Int, cpu: Int, memory: Int, storage: Int, tag: String) {
// do something ...
}

We can reduce the number of argument by passing an object representing the infrastructure requirements, see example below

  fun deployApplication(applicationId: Int, infrastructureRequirements: InfrastructureRequirements, tag: String) {
// do something ...
}

Command Query Separation

The Command-Query Separation (CQS) principle states that a function should either perform an action (a command) or return data (a query), but not both. This makes the code more predictable, easier to test, and cleaner.

  // Query function: returns whether the withdrawal can happen (no state modification)
fun canWithdraw(balance: Int, amount: Int): Boolean {
return amount <= balance
}

// Command function: performs withdrawal by returning the new balance (state modification, no return of query data)
fun withdraw(balance: Int, amount: Int): Int {
return if (canWithdraw(balance, amount)) {
balance - amount // Returns the updated balance
} else {
balance // No changes if insufficient funds
}
}

fun main() {
var balance = 100

// Query if withdrawal is possible
if (canWithdraw(balance, 50)) {
// Command: Update the balance by performing withdrawal
balance = withdraw(balance, 50)
println("Withdrawal successful. New balance: $balance")
} else {
println("Insufficient funds")
}
}

Conclusion

Let's admit that functions are fundamental components of our code, so it's crucial to invest time and effort into defining them properly, including their names, arguments, and statements. Writing software is similar to any other form of writing—you begin by drafting your ideas, then refine them until they flow smoothly. Remember, we write code not just for execution, but also to be easily understood by others.


Clean code: Write The Code You Want To Read (Part 1)

· 6 min read
Reda Jaifar
Lead Developer

author photo source

Clean Code!

Why should I care?

We, software engineers almost spent more time reading code than writing new lines, how many times do we complain about someone else's code? Many factors can give us an idea about the quality of code and how much the writer cares about it. If you dislike reading bad code, you already made your first step toward writing good code if you care about your heritage. There are many good reasons to care about writing clean code, adding the artistic layer to your code is an inspiring reason for me to learn and apply the clean code rules and principles.

What clean code brings to me?

Clean code is what makes us professional programmers, someone with high-level ethics who cares about the present and the future of his code, he believes that lines of code can live for long and can be enhanced by others with ease and passion. Like a book author what makes him happy is how readers enjoy turning the pages of his book one after the other without realizing the time elapsed.

Clean code is about philosophy!

Clean code makes us more than a programmer, it helps us develop a good vision of the software we are building, caring about its growth, evolutionary, and enhancement. Clean code makes us a thinker about maintainability, design, and the ability of the software to cope with changes quickly and easily. Code is written to live but also to change and evolve.

We are authors

Yes, we programmers are authors, that said, we have readers, Indeed we are responsible for communicating well with readers. The next time we write a line of code, we'll remember we are authors, writing for readers who will judge our effort.

What clean code covers?

Naming

As a programmer the first step of writing code is choosing names, for variables, functions, classes, packages and source code files. While this seems easy and instinctive, choosing good names takes time but saves more than it takes.

Let's look at the following code snipped:

 d = Date.now();

The name "d" above has nothing to reveal, even tough it is a date object, but we cannot know the intention of usage, either its start date or end date. Note that even naming it startDate doesn't give it any sense, because we need to know as a reader what is the context of the start date. Hers is a suggestion for this example:

taskStartDate = Date.now();

Abbreviation

Abbreviation Is one of the most common mistakes concerning variable naming, as a programmer can you guess what this variable name below means?

msg

Can you know that msg may mean "message" or "most scored goal"? Personally, I don't want to spend time exploring many lines before or after this one to understand the context of this variable in case I need to make a change. The rule is to avoid any disinformation.

Distinction

Another issue with naming is the number-series such as (variable1, variable2), consider the following function:

public static void duplicateString(char a1[], char a2[]){
...
}

is it not more readable if we use "source" and "destination" as the names of the two arguments? I think yes, it is.

Adding noise words is another problem that impacts the cleanness of the code, you may want to specify that a variable is a String, so you name it: "emailContentString", Here the "String" is just redundant as is not part of the name but the type which has nothing to do with the meaning of the variable.

Word Sounding

As a programmer, there is a good chance that while we are writing code, our brain is pronouncing the text we type. when we cut the connection between our brain and the activity of writing, we usually type variable names that could be difficult to pronounce, and the consequences are multiple: other developers won't be able to retain them easily and these names will be demanding to discuss with the business analysts. While English is the most used natural language used to write code, using other languages such as French or Italian, apply the same rules regarding how easily the variables, functions, or classes names are pronounceable.

Are names accessible?

Each time I take over developing a new feature or fixing a bug that requires modifying a source code that not has been writing by me, I start by searching some keywords that I got from the context of the domain system. For Example when I was asked to fix a UI bug in a web application developed using ReactJS then I was trying to find the matching component in the source code, but it was not as easy as expected and I spent 30 minutes before finding the component named with a number prefix: 1CounterComponent. This is why choosing names that are straightforward to find is a very useful rule to follow.

Coding Conventions

Every programming language provides coding conventions regarding variables, functions, classes, and naming source code files. While the naming took a good part of these conventions, they also cover indentation, comments, declaration order, etc ... I don't hesitate to refer to these conventions. But during my modest experience, I came across some coding conventions from specific programming languages applied to another one. This is strongly discouraged or prohibited by the teams themselves.

Technical Vs Business Names

We write code to build software that will be solving a problem, For example: coding an application that computes taxes. Trying to be a good programmer implies differentiating technical things from business-related ones. whenever you code a technical concept don't try to use mainly a domain name, For example: declaring a variable that holds an instance of the HTTP client could have the following name: httpClient, but if we try to include the business-related usage we can name it: taxesRulesHttpClient as you can see in this case the domain doesn't bring any help instead is just making a technical thing harder.

A last note

Writing clean code requires a piece of cultural knowledge and good descriptive, communication, and writing skills, we can develop these skills by learning from communication experts either by reading books or taking courses on how to write, synthesis, and order ideas. Also evolving on the natural language we use to code. For example, if we write code in English, it will be helpful to learn more words, synonyms, sentences, etc...

So far I wanted to pay your attention to the importance of clean code, and how can impact the software's quality and maintenance, We covered mainly the naming concept in this part. Other articles will follow to cover other aspects concerned by clean code.


Introduction to software functional and behaviour testing

· 7 min read
Reda Jaifar
Lead Developer

author photo source

Functional Testing

What is a functional test ?

Functional tests are one of these software testing approaches or test types such as (unit tests, integration tests, load tests, penetration tests, ...) all with one mission to test that the software is compliant whether with business specification, technical requirements or other quality and usability metrics. But functional tests focus on ensuring that the software functions behave as expected by the business specifications, these tests don't interact with source code such as unit tests, but mainly with the software features. A functional test usually puts the system, the application or the software we want to test in an initial state where we provide the necessary elements to make the test executable such as storing a list of cars in the database, then we test the feature find a car for the period of (2nd march to 7th march), then we validate that the output matches the expected result.

Why do we need to write functional tests?

We need to write functional test to validate the features from a user perspective, hence we validate the following:

  • Feature is working as expected by the specifications
  • Usability: checks whether the feature is easily usable, for example, a button is freely reachable on the page.
  • Errors: when a subsystem is not responding, do we display an error message to the user to help him understand what's going on.

Functional testing style

A common form that functional testing take is the Given-When-Then, this approach coming from the BDD (Behaviour Driven Development) defines the structure of many testing frameworks such as Cucumber that we will cover in our example later in this article. The prime idea is to break down a scenario (test) into three sections:

  • Given: the given part defines the pre-conditions before challenging the system by executing or running a feature.
  • When: is do we want to do with the system, for example ( when I book a car)
  • Then: describes the expected result or output after the application or the software behaves in to respond to your action.

To simplify the idea, let's write an example for a rental car website using the Cucumber Tool (Framework):

Feature: User book a car Scenario: User requests to book a car from 1st March to 7th March 2022 Given I select a car from the available cars for the period (1st March to 7th March 2022) And I select GPS as an additional Option And I select Full Insurance When I book the car Then I should receive a confirmation

BDD: Behavior Driven Development

BDD combines the best practices of Test Driven Development TDD, Domain-driven Development (DDD), and Object Oriented Programming (OOPs) For an agile team, scoping a feature is a very important task, as the stakeholders are talking about the business requirements, the development team is more interested in the technical challenges, Here comes the BDD to provide a common language that allows efficient communication and feedback and then a perfect specification, development vision, and feature delivery.

BDD closes the gap between the business and the technical people by:

  • Encouraging collaboration across roles to build a shared understanding of the problem to be solved.
  • Working in a rapid and small iteration to promote the feedback and optimize the value delivery.
  • Producing documentation that is automatically checked against the software behavior.

There is a good chance that you're agile at your organization so you already plan your work in small increments of value like User Stories. In this case, BDD will help you to deliver your promises of agile on time. BDD does not replaces your processes but enhances them.

BDD and Functional Testing

Let's focus on the word Behaviour so functional testing of behavior testing is these tests your write to check your system or the software you're building how behaves. Functional testing can also be called behavior testing.

Behaviour Testing in action

To illustrate all these abstract notions explained briefly in this article, let's write a small application and its behavior tests using Kotlin programming language and Cucumber

  • Kotlin is a JVM programming language, like Java, Scala, or Groovy
  • Cucumber is a testing tool that supports Behavior Driven Development
  • Gherkin is a business readable language that helps you to describe business behavior without going into details of implementation

We will need the following to build this example:

  1. Java SE (Java 9 and higher are not yet supported by Cucumber)
  2. Maven - version 3.3.1 or higher
  3. IntelliJ IDEA (which will be used in this tutorial)
  1. Clone the project from github
git clone https://github.com/reda-jaifar/hands-on-kotlin.git
cd sportair
  1. Open the project in IntelliJ IDEA:

    • File -> Open… -> (Select the pom.xml)
    • Select Open as Project
  2. Verify Cucumber installation

mvn test

Now our environment is ready, let's write some scenarios for the following application:

SportAir is an application that indicates whether we can exercise outside or not based on the weather.

In Cucumber, an example is called a scenario. Scenarios are defined in .feature files, which are stored in the directory (or a subdirectory).

Create an empty file called src/test/resources/sportair/can_we_exercice_outtside.feature with the following content:

Feature: Can we exercise outside? Everybody wants to know if we can exercise in the air

Scenario: The weather is not convenient for exercising outside Given The temperature is 42 celsius When I ask whether I can exercise outside Then I should be told "Nope"

if you're using Intellij Idea Cucumber Plugin, you should see the keyword colored, below the meaning of each:

  • Feature: is a keyword that should be followed by the feature name, a good practice is to use the name of the file. The line that follows is a description that will be ignored by Cucumber execution parser.
    NB: We use a feature by file
  • Scenario: defines the name of a scenario, we can have as many scenarios as expected by a feature.
  • Given, When, Then: are the steps of the scenario. Refers to the definition above.
mvn test
The output should be something like the following:
Given The temperature is 42 # StepDefs.The temperature is(int)
When I ask whether I can exercise outside # StepDefs.I ask whether I can exercise outside()
Then I should be told nope # StepDefs.I should be told(String)

Scenario: The weather is convenient for exercising outside # sportair/can_we_exercice_outside.feature:9
Given The temperature is 24 # StepDefs.The temperature is(int)
When I ask whether I can exercise outside # StepDefs.I ask whether I can exercise outside()
Then I should be told of course # StepDefs.I should be told(String)

2 Scenarios (2 passed)
6 Steps (6 passed)
0m0.181s

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.403 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

Behavior Driven Testing Benefits

  • Helps document specification by the usage of non-technical language
  • Focuses on how the system should behave from both user and developer perspective
  • Gives high visibility of the system design
  • Helps to make the software or the system meet the user need

The figure below illustrates the process of BDD and how it can help to write down behavior tests.

BDD Process

This figure defines a step flow to help define and write down behavior tests


Software Architecture: The Implementation View

· 7 min read
Reda Jaifar
Lead Developer

author photo source

The 1+4 Model View The 4+1 view model describes an application’s architecture using four views, along with scenarios that show how the elements within each view collaborate to handle requests

Includes the result of the build process that can be run or deployed such as a Java JAR or Node.js Package. These artifacts interact with each other in the form of a composition or dependency relationship.

The Monolithic Architecture Style

Let's extract the definition of monolithic architecture from an example. Imagine you are invited to develop an enterprise application for managing music concerts ticketing, One of the requirements is to access the system from the browser and a mobile native application. SO the application will handle HTTP requests, execute a function and access a database to persist the data. One of the design options we may have is to create different components each one is responsible for a specific business logic (event subscription, payments, ticket editing ...). if we choose to develop with the java programming language and the spring framework, we'll have one application with many modules interconnected and coupled to accomplish the job. But what about the deployment? what type of build output will generate and how to deploy it into a production environment. The answer is we will generate a single Java WAR file. author

The monolithic representation of our example application (Music Event Application) where we can distinguish bounded functions of the system but all in one artifact

This is what monolithic architecture is about to define the output of your source code as one piece that you can easily:

  • Deploy (push or put into the production environment, or any other environment such as development or staging)
  • Scale (run multiple instances of the application in response to increasing traffic)
  • Debug (in case of non-normal behavior of the system you can explore the logs, check the config, and so on to find the error, all these things are on the same process)
  • Question: Now the system is up and running, but a new feature is required which needs to update the payment provider within our application, how can we achieve that?
  • Answer: we have to update the source code, re-build the whole application, think of a deployment strategy to ensure service continuity of our application.

In the context of our monolithic application, many drawbacks are rising while changing a small piece of the system:

  • Even though the change concern only one part of the system, this one becomes indivisible and decoupled, the build and deploy process is slower because all the source code should be re-build to generate the new artifact (Java WAR file)
  • The whole system is developed with one stack which limits the on-boarding of other developers with different backgrounds
  • Less re-usability of the components.
  • Increasing the artifact (build output) volume.
  • Reliability as one bug in the ticket editing component can cause the whole system to shut down.

In the next section, we discuss the alternative and how microservices address many of the drawbacks of monolithic and bring new added value but also some very challenging points to handle.

The Microservices Architecture Style

Microservices architecture style organizes the application as a set of loosely coupled, independently deployable services, Together these services deliver the functional and business features of the system we want to build. Let's continue with our Music Event Application example and try in the above illustration to define its microservices architecture:

author The Microservices representation of our example application (Music Event Application) where 3 services communicate through HTTP using REST

As we can observe in the illustration each service run in an independent process and also could have its database(recommended), Notice also how these services communicate to each other, in this example, I suggest using the REST API through HTTP, but this is not the only communication option we can have, there are more such as messaging using a message broker.

Let's tackle with further detail the microservices inter-communications in a dedicated article, so far and the rest of this document we will use REST as a reference.

What is a service?

As the word service is a most recurrent when we explore the microservice architecture, Here is a definition:

A service is an independent deployable application or software component that provides a set of functionalities accessible through an API. Service has its own logical architecture, Hexagonal architecture may fit many use-cases, In addition a service can be developed with its specific technology stack that may differ from other services' technology stacks in a microservices architecture

read more about Hexagonal Architecture and alternatives in this article

What is loosely coupled Services and why they should?

Two services are loosely coupled if changes in the design, implementation, or behavior in one won't cause change in others. In a Microservices architecture, the coupling will happen when a change in one enforces an almost immediate change to one or more microservices that collaborate with it directly or indirectly.

While designing Microservices architecture, to make the services the less coupling possible, consider the following points:

Database sharing

the data storage is a microservice implementation detail that should be hidden from its clients (usually other microservices). If Microservice A needs to access data of Microservice B, B should provide an API that A will use to consume the needed data

Code Sharing

By definition, microservices do not share codebase, but we may want to avoid redundancy by sharing dependency libraries and end up needing to update frequently in response to that libraries' client's change requests. So shared code should be as minimum as possible. A good practice that may seem strange at glance is to duplicate code so each service has its copy, so we need to update the library to match Service A requirements, Service B remains un-impacted

Synchronous Communication

In a Microservice architecture, services cooperate to accomplish the job, so they need to communicate either asynchronously or synchronously where the service caller expects a timely response from the callee service might even block while it waits. To address the potential response latency, we can integrate a caching mechanism or implement the circuit breaker pattern to avoid cascading failures. These two options could help remediate the system quickly, but for the long term, the best alternative is switching to asynchronous communication by using a messaging broker like Apache Kafka, So services can cooperate by publishing and consuming messages.

When it comes to designing the next-generation software, relying on a strong and reliable architecture helps a lot, In recent decades, much great software conquered the market and is serving millions of users while scaling up and down to reduce cost and energy or respond to an increasing number of requests. Microservices Architecture is part of other practices and engineering designs behind thanks to its benefits, below is a non-exhaustive list:

  • Independent development: microservices can be developed in isolation to accomplish a defined functionality
  • Independent deployment: microservices can be deployed individually and independently in any environment (cloud, on-premise, managed infrastructure)
  • Fault isolation: if one service fails, the system remains up and only the functionality provided by that stopped microservice will be impacted
  • Technology stack: different programming languages, frameworks, and technologies can be used to build the same software, usually a SaaS
  • Individually scaling: each service can scale as per need, is not necessarily to scale the whole system as is the case of monolithic based application

Despite the number of advantages Microservices Architecture is bringing, choosing it over Monolithic Architecture relies upon on the context, the application domain (banking, delivery, e-commerce, ...) and scope (either is a lightweight application or a complex evolving application), your organization software engineering capabilities and culture.


Software Architecture: The Logical View

· 5 min read
Reda Jaifar
Lead Developer

author photo source

The 1+4 Model View The 4+1 view model describes an application’s architecture using four views, along with scenarios that show how the elements within each view collaborate to handle requests

The layered architecture style

This is my first architecture style I've discovered 10 years ago thanks to my java enterprise application course teacher, Ths idea consist of organizing the elements of an application into layers. Those elements could be java classes grouped by the responsibility type they manage and respect the rule that each layer should depend only on the layer below it, Another version also tolerate that a layer can depends on the any of the layers below it.

Even though we can apply this architecture style to any of the 4 model view we've seen above, It is most likely to be used in the logical view as follows:

  • Presentation layer: groups classes & interfaces that handle the UI interactions, Such as desktop application UI that handles user interactions like Click, Press, etc...
  • Business logic layer: contains classes where we implement the business logic of the system. For example classes that calculate the shortest route for delivering merchandise from stock house to customer.
  • Persistence layer: contains interfaces and classes that interact with database or file system. For example classes that communicate with a MySQL database.

3 Tier Java Application Architecture In the above figure, we illustrate the 3 tier architecture for a java application, classes of the same layer are grouped using packages.Note that architecture is beyond any programming language, so for example in case of a C# application we group classes in namespaces instead of packages for java.

The years go by and the software development community began to recognize some drawbacks of N Tier architecture, below we list some of them:

  • Single Presentation Layer: With the evolution of the web and mobile applications, many systems provide the same functions, For example a desktop application for logistics providing the feature of calculating the shortest route and cost of a delivery, While the business logic remains the same, the interactions with the system are evolving with mobile and web users.
  • Single Persistence Layer: Modern systems needs to interact with many and/or different storage systems rather than one database.
  • Layer dependencies: As the business logic depends on the persistence one, we are prevented from testing the business logic in an isolation.

These disadvantages lead to an alternative architecture style we present next.

The Hexagonal Architecture Style

This architecture style organizes the logical view in a way that puts the business logic at the center. In contrast to the layered architecture that has a presentation layer, we have here one or more inbound adapters that handle requests from the outside by invoking the business logic. The same applied to the persistence layer, the application has or more outbound adapters that are invoked by the business logic and invoke external applications. The main characteristic of this architecture style is that the business logic doesn't depend on these adapters, instead they depend on it. The Business logic has one or more ports.A port defines a set of operations and is how the business logic interacts with what's outside it. For example in java these ports are a Java Interface. we distinguish inbound and outbound ports. An inbound port is an API exposed by the business logic, which enables it to be invoked by external applications, for example a REST API.An outbound port is how the business logic invokes external systems like Database Access Repositories.

Like the ports there are inbound and outbound adapters. An inbound adapter handles requests from the outside world by invoking an inbound port. For example in the case of a Java Web Application using Spring framework, An inbound adapter is a Rest Controller that will invoke inbound port exposed by the business logic. An outbound adapter implements an outbound port and handles requests from the business logic by invoking an external application or service.An example of an outbound adapter is an Event Publisher to Kafka or any other Event streaming system.

Hexagonal Architecture

The Figure above shows an example of the hexagonal architecture where the business logic has one or more adapters to communicate with external systems

Let me remind you that decoupling the business logic from the presentation and data access is the important benefit of the hexagonal architecture style. This is very useful also when it comes to testing as you can use TDD easily as you can test your business logic in an isolation.It also defines new model for the modern applications where the business logic can be invoked by multiple adapters each one of them invokes an external system.

The Hexagonal Architecture style is well fit to define the architecture of each service in a microservice architecture.

Both the layered and hexagonal architectures are a set of constraints and rules on how elements within the logical view are connected and how they communicate.


Software Architecture: The 4+1 view model

· 4 min read
Reda Jaifar
Lead Developer

author photo source

The software architecture of a computing system is the set of structures needed to reason about the system, which comprise software elements, relations among them, and properties of both. by SEI

We can decrypt the above definition as structuring a system as a whole recessed block into parts connected, complementary and modular. The more these parts are decoupled and can work independently, and communicate to each other effectively the more our architecture will fill its mission to ensure a maintainable, extensible and homogeneous system.

The 4+1 view model of software architecture

Like a building, there are different plans and maps that can describe different the different perspectives of that building, we have the electrical, plumbing, structural and others. This is exactly how the 4+1 view model defines software architecture in the paper published by Phillip Krutchen

The 1+4 Model View The 4+1 view model describes an application’s architecture using four views, along with scenarios that show how the elements within each view collaborate to handle requests

Each of the four views has a well-defined purpose as detailed below:

Logical View

It consists of the source code written by developers, in the context of an oriented programming language like Java, the elements are classes and packages, in addition to relationships between them such as inheritance, association, and composition...

Implementation View

Includes the result of the build process that can be run or deployed such as a Java JAR or Node.js Package. These interact with each other in the form or a composition or dependency relationship.

Process View

Refer to the process holding and running either in virtual machines or containers like docker, relations between them is called inter-process communication.

Deployment View

Represents the map of the physical or virtual machines where the system is executed and running, also describes the communication at level through the network. For example this view can be a VPC with all the routing configuration inside this network and between it and the internet.

Why an application architecture is relevant?

An application come to life with the purpose of solving a problem, to do so it needs to fulfill two types of requirements, Functional requirements that defines what the application should do, Previously defined in the form of specifications, with the agile edge we define them as user stories, use cases, or events. we can start coding immediately and produce an application that respond to these requirements without thinking about architecture. But when it come to develop a reliable, maintainable and extensible system, Architecture is our core activity because it helps us answer questions regarding how the system behaves with millions of users at the same time, security threats and delivery time. Architecture meets quality requirements.

Architecture Styles

I found the definition given by David Garlan and Mary Shaw in their publication titled An Introduction to Software Architecture an amazing reference to understand the concept of architecture styles and how it can be view in the field of computing systems.

An architectural style, then, defines a family of such systems in terms of a pattern of structural organization. More specifically, an architectural style determines the vocabulary of components and connectors that can be used in instances of that style, together with a set of constraints on how they can be combined. These can include topological constraints on architectural descriptions (e.g., no cycles). Other constraints—say, having to do with execution semantics—might also be part of the style definition.

Follow are the questions shared by these two pioneers in the discipline of software architecture, answering these questions will remarkably help define the architecture that fit for the system we're building:

Given this framework, we can understand what a style is by answering the following questions: What is the structural pattern,the components, connectors, and constraints? What is the underlying computational model? What are the essential invariants of the style? What are some common examples of its use? What are the advantages and disadvantages of using that style? What are some common specializations?

in the next part, let's explore some of the most known architecture styles Logical View


Few and permanent rather than many and intermittent

· 5 min read
Reda Jaifar
Lead Developer

author Photo by Rachen Buosa

This post's title is an old quote I've heard since my early edge, but I never gave it much attention or tried to go beyond this phase, just some words shared by older people in my family. Unfortunately, it took me years before I mind the importance of continuously complete small tasks and cut off with the idea of doing the whole job at once. Thanks to agility I'm changing my mind and acquiring new ways of working and producing. Before sharing with you why and how splitting any job or mission into small tasks helped me to achieve goals, I would like to share the pain encountered while trying to provide many efforts at once.

I remember the school-age when I was trying to prepare for my exams, I always adopt the same strategy by spending a whole day revising my courses, doing exercises, and once I got tired I close my books mark the material as completed. I often succeeded in my exams but many times I recognize that I could do better, but who cares, I wasn't obsessed about getting the highest score.

While I'm writing these lines, I remember the time when I want to get abs and being fit, I can't tell you that my motivation was something other than having the summer body. As a consequence, I start going to the gym and training in late April, But for 3 years consecutively, and contrary to my exam story, I've never reached my goal even though exercising 6 times per week for not less than two months. From these two stories shared above, I retain one lesson providing much effort in a short period may, or not work.

But what if I could change something to increase my chances to get a shaped body, maybe be coached by a professional! Yes, I did, maybe follow a restricted diet! Yes, I did, the only thing that I could do and not did it is starting my program earlier and going slowly but surely.

Few and permanent

A few years ago I've had the opportunity to discover agility at my university, then I worked on an agile project, 1 month after starting the project our web application was in production, users interacting with and we are having feedback, this is really amazing and so satisfying. I do believe that the key rules for such success were

  • defining small but valuable feature
  • continuously delivering

Breaking a big task down into small, more feasible ones helped me avoid procrastination and an overwhelmed workload. Here are some steps to follow for breaking a task down, but remember that you're the only one capable of doing that depending on the context, the knowledge, and priorities:

1 - Make sure you visualize the big picture, that means what the end product or make sure you visualize 2 - Think about the order, which one should be completed first, second, and so on... 3 - Define milestones: make a short plan which will help you stay on track. 4 - Complete your tasks early to have additional time for a final review

I do believe that permanent iteration pays in the end, with the adoption of a few concepts we gain confidence and progression:

  • Going slowly, how many times have we heard that? but Have we ever enjoyed it as much as we can. Going slowly means to me doing things at my pace while giving all my attention and concentration to do it the right way and achieve high quality. Consider coding a small program or write a report, try to do it rapidly and at once, then do it slowly over 3 times within 1 day, then compare your results, I have no doubt that quality will differ.
  • But Surely, yes make sure at any stage, you are performing with your best efforts, concentration, and passion.
  • While doing things over many periods, make sure at the end of each milestone you create something tangible, deliverable, and useful.
  • With dedicated attention to detail, because details make the difference.

How the rule of "few and permanent" affected my motivation and productivity:

  • When I started scheduling my job and tasks as few ones completed over many steps, I begin to feel more confident, and sure about my achievement. In my unconscious mind, I'm convinced that I'll reach the expected goal whatever how many iterations I'll go through.
  • My motivation and passion are often at the top, as completing tasks that are tangible, apparent, and useful. As a software engineer, I do love to deliver small features as soon as they can be deployed to production and being used by end-users, But this is certainly true in other fields of application.
  • As my tasks are small, they are completed early so I can get feedback on their useless then I'll iterate to improve and optimize, rather than reviewing a whole job with many comments and issues to handle.

We always need to remind that

Overwatering can kill flowers, a moderate and continuous one give them chances to grow up

is our scoping was successful?

· 5 min read
Reda Jaifar
Lead Developer

author

A new project is in the pipeline and we are ready to kick off this new challenge, Our team is ready and full of energy and enthusiasm. Scoping sessions are scheduled this week. The first session started with a short description of the project, making the focus on the business and strategic impact and how will help the company to accelerate its digital transformation in the perspective of developing new digital products and cloud-based offerings. It’s time to finish the workshop with one conclusion all team members share the same frustration regarding where we want to go. During the week these sessions succeeded one after the other and still having a blur vision, confusing features, and also an organization that we believe is not convenient to drive the boat to the shore.

Exploring the real value

As a product owner, I have to gather the maximum information about the customer business, their strategic goals, and where they want to land once the project takes off. I remember this quote from Dassault Systemes Dassault Systemes !

If we ask the right questions, we can change the world

Asking pertinent questions is crucial to understand the business and the desired value we expect to provide. For a successful scoping workshop, this job should be prepared before and these reflections and analysis at least started in order to keep the team members away from any frustration or defeatism.

Why The role of the Product Owner is very important at this stage?

The product owner is the guard of the vision and customer value, keeping the train on track requires a lot of effort regarding the business understanding and mapping this knowledge to user stories that designers, developers are easily able to take in charge and implement.

Based on our experience, our product owner iterated regularly over the backlog to refine the items and get rid of the irrelevant ones, each time he was approached to revise a business rule.

Specifications and requirements

What kind of format our documents should follow to write down the specifications and requirements and how many details we should draft? this question is indispensable to answer before starting, the more we give attention to what to write the more implementation will be easily taking into consideration all constraints and customer-specific requirements such as solution’s time responding, availability, number of future users. These notes help considerably when it comes to architecture design and technical stack decisions.

Deliverable frequency and type

While in agile project continuous delivery is at the heart of it and shouldn’t be part of discussions but the frequency of delivery and type of deliverable could be, The reason why a team should agree and state early these points.

The adoption of continuous improvement is totally appreciated while the business is evolving but we have to pay attention before investing in this area causes often lead to delivery postponed even contract issues.

Cost

Sometimes and due to technical choices such as licences, do not forget to include them in your budget estimation and let stakeholders know about them, When it comes to money transparency is the key to spread trust and avoid undesirable surprises. the rules are:

  • calculate an accurate budget and make sure all elements are included.
  • define a process that helps to keep the budget flexible regarding features without over budgeting.

Communication

Whatever the project scope or size, communication is a key to a successful customer value and team satisfaction, Defining communication channels, rules, and tools between stakeholders and project team can considerably impact project progression and target achieving. Communication also implies some values such as transparency about the team’s capabilities what we can and we cannot do, these kinds of statements should be communicated as soon as possibl to help the customer make the best decision.

In my point of view, I prefer to avoid the usage of multiple communication tools and formats with our stakeholders (telephone, email, video-conference, meetings…), this can help keep our exchanges simple, effective.

Regarding internal communication between team members, Personally, I have a lot of appreciation for meetings or face-to-face discussion believing that is the quick and right way to argue a decision or explain a point of view to convince my team-mates of any technical choice. Otherwise using a project management tool to track and monitor is still very useful in order to keep everyone updated and everything documented.

Flexibility and adaptation

Agile practices come to solves today’s project issues and pains, but at any stage, we should be wedged, In my opinion, we have to cope with challenges, involve the team in every decision, think differently and act like one. Scoping is the stage where we invite all involved people to the same boat with one goal is to reach the destination.

From small team to large one

· 5 min read
Reda Jaifar
Lead Developer

author

During the latest months, I’ve been asked to move from a small agile team to a large one, why? what changes should I cope with? what obstacles to tackle and what kind of achievements we accomplished? here are the experience story and the learned lessons

Small Agile team

I've been part of a small agile team of 4 developers, tech-lead, UX designer, Scrum master and a Product owner. Working with scrum method, I do believe that this team size was just perfect as the communication is too smoothly and decision making is quick and effective. We developers were using the git flow branching strategy. A new branch is created for each user story, commit added, pull request created and reviewed then merged into the master. Product owner manage easily his backlog. The scrum master scheduled perfectly our scrum sessions and these one were gainful in term of business understanding and story telling. Thanks to the great work of our UX/UI design integrating the UI and implementing the user experience is definitely optimal thanks to sketch software.

The team size was a key element to a successful journey, providing a great added value at the end of each sprint while delivering high-quality software with security standards-compliant.

Communication and collaboration

When is come to working together and collaborating with a team, communication is a key factor toward success. While this is easy for a small team as we are often setting around the same table or in the same open space we communicate orally and directly trying always to avoid emails and chat as much as we can, but for sure without omitting to give each one its private space and time to concentrate on his tasks with no disturbs. In the other hand and once the team getting larger we first obstacles we start to face is how to communicate and exchange, even harder for taking a decision. Another point is managing meetings which means to manege finding rooms especially as we are working in a co-working building then as we have to take into consideration each one is calendar. Now we are in the meeting room with more than 12 team-mates it took longer than expected, deviation and rarely we end up with a defined actions list assigned people.

I believe either we are a small or a large team there are the right tools and ways to communicate, We need just to avoid applying the ones that work fine for a small team in the context of a large team and vice versa.

Support and expertise

One of the greatest points when you are part of a small team, is that you know each member is scope of expertise which is very useful and effective when it comes to coordinate whether to change a piece of code, to integrate a new technology or document a feature. Unfortunately this advantage disappears along the way a team begins to extend and we start to be distributed which affects our knowledge about expertise mapping in the project and for sure consume more time to find the right source to support you.

I refer to Conway's law stating about organization structure footprint on their production:

Organizations which design systems ... are constrained to produce designs which are copies of the comminication structures of these organizations. "Melvin Conway"

In our organization we understood this quickly and thanks to our agile coach we reorganize our teams and introduced some practices to continue delivering added value feature continuously.

Single Point of Knowledge

As our team begin to grow and having many members than needed in an agile model, I observed in the lake of coordination, close collaboration, and effective communication, new single points of knowledge taking place in our organization as some people with or without attention monopolize and hold in their corner some specific knowledge or expertise which impacts the pace of productivity, innovation, and rotation. Contrarily to the case of a small team where the knowledge and responsibilities are well shared and all members have almost the same level of knowledge about the project which avoids the 'indispensable member' obstacle and lead to transparent and rapid rotation and delivery.

Team representative and interface

When I was part of a small team there was a member who keeps the team informed, knows the organization’s culture, and promotes best practices that make our entity inspiring. Often this role appears naturally cause the person playing it holds some qualities that help him representing the team, interfacing with management contrarily in the context of the old school team, a project manager take this responsibility. But can we have many representatives (Leaders) in the team? In my point of view, YES as each member has a different style therefore we can boost the team’s productivity and creativity. Shared leadership led also to reduce responsibilities stress, thrive solidarity. For the company we observed many advantages once we made the move to this model:

  • Share the the bigger picture with everyone.
  • give the company more options.
  • increase in decision making transparency.

Finally, the question is can this model succeed with a large team? From my experience, this can be a huge challenge for the management but also for immature teams who can considerably slow down the decision making.

I’ve been part of different teams small and large and I believe that adopting the right management style and establishing a transparent and honest relationship whether between team members or between teams and the management should always gain the upper hand.

Being the representative of your team is talking about your shared values and practices, defending your team's decisions and choices. But in any case shouldn't be a position that we take over.

A 2 months remote work experience

· 4 min read
Reda Jaifar
Lead Developer

author

March 2020 marked by many measures taken by the majority of countries in the five continents following covid-19. My company who already allowed their employees to work from home occasionally, Now they are obliged to continue working remotely for an undetermined time.

Despite many advantages remote work bring, there are some inconveniences to manage for good productivity and effective work.

Setup my home desk

As I'm working from home, I've never though about setting up any similar environment like the one at the office, I've just being lying on the couch the whole workday or sometime I change my position a trifle. Two weeks later I observed that my concentration and productivity is going down more and more, I tough having some tiredness, After exchanging with a colleague, He reveal its secret for keeping energy and effectiveness, I was surprised while hearing that setting up a similar work desk at home may highly help. I decided to take into consideration this point, Now I confirm how this changed my home working routine.

I'am 100% convinced that setting up a convenient desk at home can considerably help with commitment, concentration and effectiveness while working from home ☺️

We don't all have an isolated room!

Unfortunately living in Paris or any big city around the world has its disadvantage when it comes to spacious lodgement. For the parents with their children at home, for the friends sharing the same room, dealing with this limitation is a key point for relaxed home working without impacting our collaboration and performance. From my point of view, we can manage this issue by rotating our work hours and companies should tolerate this option letting parents working while their children are sleeping. Overall having a private room stay the best option for enhancing what has been mentioned about setting a home desk.

Effective communication

In the field of software engineering, Often discussing new technologies, good practice or some technical decision brainstorming may be held while we are sharing a coffee with team-mates in the cafeteria, or around a table in a meeting room, that means we have a face to face communication, In my case, I do love this way as it brings to me a smooth and flexible tools using my body language to explain and talk about a topic. Unfortunately while working from home this manner is no longer afford the same way we do at the office. But thanks to recent video-conference platforms we can continue relying on our communication habits taking into consideration some rules for en effective exchanging, follow the ones I’m using:

  • Turning my camera on during the meetings.
  • Wearing my usual clothes like in the office.
  • Using a virtual whiteboard instead of the real one to explain, share and design my ideas.
  • Turning my micro off when I'm not the speaker.
  • Summarizing your notes and sharing them with colleagues.
  • Video calls or chat over emails
  • Most important is to setup the rules with your team and colleagues to avoid disturbing each other.

Do not forget ourselves!

I noticed during the first weeks of my home working that I did not take rest and breaks regularly. So I used to schedule meeting right away, sometimes at lunch time, sometimes I chain them without any pause. Few time later I recognize a lack of concentration and it becomes very disturbing to see calls and meetings notification showing up. The conclusion is working remotely does not mean working continuously and do it so may substantially impact our physical and mental health, the reason why I decided to schedule my rest and breaks during the work day and stay away from work during these time slots.

While working from home, never forget to take rest and breaks during a workday as it protects us from health risks and mental disturbance.

So far so good

Being armed with the right tools and techniques helped me keeping a good mood with my team-mates, enhancing my productivity and enjoying my workday from home.

Wherever we are, let's do our job with love and passion.