SOLID Design Patterns

SOLID is a set of five design principles that can be used to create more robust, maintainable, and extensible software. The principles are:

  • Single Responsibility Principle: A class or module should have only one reason to change.
  • Open/Closed Principle: Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
  • Liskov Substitution Principle: Derived types should be substitutable for their base types.
  • Interface Segregation Principle: Clients should not be forced to depend on methods they do not use.
  • Dependency Inversion Principle / Inversion of Control: High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions.

Some real-life examples,

  • Single Responsibility Principle: A car is an example of a system that follows the SRP. The car has many different components, such as the engine, the transmission, the brakes, and the wheels. Each of these components has a single responsibility. For example, the engine’s responsibility is to provide power to the car. The transmission’s responsibility is to transfer power from the engine to the wheels.
  • Open/Closed Principle: A software application that allows users to customize their user interface is an example of a system that follows the OCP. The application can be extended to support new customization options without having to modify the existing code. This makes the application more flexible and adaptable to change.
  • Liskov Substitution Principle: A car is an example of a system that satisfies the LSP. A car can be replaced by a different car, such as a truck or a van, without affecting the rest of the system. This is because all cars have the same basic functionality, such as the ability to transport people and cargo.
  • Interface Segregation Principle: A software application that allows users to choose which features they want to use is an example of a system that follows the ISP. The application provides a number of different features, such as the ability to create documents, the ability to send emails, and the ability to edit spreadsheets. Users can choose which features they want to use, which makes the application more user-friendly and less overwhelming.
  • Dependency Inversion Principle / Inversion of Control: A software application that uses a database to store data is an example of a system that follows the DIP. The application does not depend on the specific database that is used. Instead, it depends on an interface that defines the methods that the database must implement. This allows the application to be used with any database that implements the interface.

GPG Key-Pair Encryption and Decryption cheat sheet

Create a new GPG key-pair

gpg --gen-key

Export your public key

gpg --export USER-ID

Import others public key

gpg --import FileName

Send encrypted message

gpg --recipient mahendra --encrypt filename

for creating ASCII ecrupted file
gpg --recipient mahendra --armor --encrypt filename

Read the encrypted message

gpg --decrypt file

Solving Method not implemented! gRPC Error

While working on grpc we might face this error, the solution is describe below.

_Rendezvous: <_Rendezvous of RPC that terminated with:
	status = StatusCode.UNIMPLEMENTED
	details = "Method not implemented!"
	debug_error_string = "{"created":"@1567057192.258984000","description":"Error received from peer ipv6:[::1]:50170","file":"src/core/lib/surface/call.cc","file_line":1052,"grpc_message":"Method not implemented!","grpc_status":12}">

Check your class where you are implementing the interfaces. In that class you need to have a method which implements the logic to handle that interface.

For example let’s take an example of a todo protobuf message

service Tasker{
    rpc CreateTask(Task) returns (CreateTaskResponse) {}
....
....

The protobuf file can be find here: https://github.com/userimack/grpc_todo_app/blob/master/protos/todo.proto

If we don’t implement the CreateTask interface we will get this error. So we need to add the logic to handle that interface.

For example:

class Tasker(todo_pb2_grpc.TaskerServicer):
    def CreateTask(self, request, context):
        // Logic goes here
        return todo_pb2.CreateTaskResponse(op_status=dummy_status, task=task)

That’s it. 🙂

Get all tags available for a docker images

Using the following small script we can get all the image tags available to us for pulling from docker hub public repository.
Code Snippet:
curl -sS 'https://registry.hub.docker.com/v2/repositories/mhausenblas/simpleservice/tags/' | jq '."results"[]["name"]' | sort

Here we are using a tool named jq and docker v2 api to get the image description and then using the jq we are parsing the tags. Hope you like the snippet.

Ternary Operators in Python

The example snippet given below can be used to create ternary operator in Python. The idea is to create a tuple or list and since False means 0 and True means 1 so we can use this to get the first or second value by comparing with our condition. Just replace your condition in place of any of the True or False.


In [1]: 1 == True
Out[1]: True

In [2]: 0 == False
Out[2]: True

In [3]: ('a', 'b')[False != True]
Out[3]: 'b'

In [4]: ('a', 'b')[True != True]
Out[4]: 'a'

Thanks for reading and I would love to hear your thoughts.