Showing posts with label Architecture. Show all posts
Showing posts with label Architecture. Show all posts

Sunday 5 April 2020

Protocol oriented programming




Protocol oriented programming(POP) is a paradigm that has come into the limelight with the advent of Swift. Different languages over different periods have had some flavor of POP in them, but there are some traits unique in the POP central to Swift, which gives them a measurable advantage over OOP. That is not to say that OOP is flawed and or POP is the knight in the shining armor. POP simply extends OOP with a few new additions that help in writing better code ergo, better systems
Contents
a. Existing system example
b. Problem with Inheritance
c. Enter protocols
d. Protocol Extensions
e. Protocols & Value types

1. Existing system example

Let’s take a simple example to see how OOP and POP work on the same problem. Consider that we are contracted to build a vehicle that can be driven. The requirement is we will be asked to build many vehicles that will have different colors, number of wheels, different engine capacity, etc. Coming from the OOP world, the core of the solution would be something like this


Everything works fine. SmallCarRaceCar both can be driven. They also can have their unique traits.(noOfSeats()nitroBoosterCapacity() etc). No paradigm maps the real world as efficiently as OOP, and hence we can apply principles of real-world like inheritance in object modeling. That’s the beauty of it.
However, the real world is far from perfect, and that seeps into its derivative like OOP. Consider the same example above. The customer has now contracted you to build the ability to have wipers for the existing category of vehicles. So now Vehicle can be modified to have the ability to wipe


Courtesy, inheritance, all the categories of vehicles created hitherto can wipe its screen. RaceCar or SmallCar can simply call wipe() and startDriving() safely in the rains! The customer is now happy and since you are so awesome in building systems he now asks for introducing a new class of vehicle, A two-wheeler known as a motorcycle. The first reaction would be to subclass Motorcycle from Vehicle. In this case, Vehicle would not be useful. Why? Semantically a motorcycle is a vehicle so we should be able to use the Vehicle class. But the problem is if a Motorcycle inherits from Vehicle it would also inherit the ability to wipe(). Needless and absurd as well! So if we don’t extend Motorcycle from Vehicle, all the complex logic and business rules which are available through Vehicle namely in startDriving() will not be available to a Motorcycle. We could simply argue that ignore the ability to wipe() in a Motorcycle, but that’s knowingly introducing an association in the system which is not required. So what’s wrong with our design?

OOPs, OOP has done it again!

A subclass may not need all the features from its parent class. A child who has a rich, alcoholic father will happily choose to inherit his wealth but would keep his distance from his father's drinking vice(hopefully!). Similarly, a subclass may not require all the traits of its superclass. Since most of the languages do not support multiple inheritances we cannot break the superclass features into multiple smaller classes and have the subclasses inherit from the required ones.


OOP does not do a great job when it comes to this.

2. Problem with Inheritance

Inheritance is a great mechanism to reuse code and build software, but it is not particularly great when it comes to a selective association. The class that gets inherited is imbibed in the DNA of the subclass whether it likes it or not. It’s like a mobile data plan which comes with a host of great features that you are interested in but also with a few meh! features which you would have rather not wanted if sold individually. But since it’s part of the package you can’t escape it.

3. Enter protocols

Protocols have been in existence since OOP itself and it offers another way of designing and modeling classes. Let’s consider the above example of vehicles and how we could design the same using protocols


As we can see, with protocols we have been able to break the dependency enforced by Inheritance on the class Motorcycle when it inherited Vehicle. Now any new category of Vehicle which does not require wipers won’t be burdened with the same. It simply does not conform to it. Don’t need it, don’t ask for it and so not burdened with it! For e.g. a scooter. The protocol used in Swift generally is implemented as an abstraction (virtual class, interface so on and so forth) in many other languages. Nothing really new there. Readers would have noticed here that the need to define the logic of driving is now on the concrete class which implements Vehicle i.e both RaceCar and SmallCar now has to define how to startDriving(). This can lead to the repetition of code and logic. Besides if protocols have been available in many other languages what’s so special about POP in Swift? The answer is Protocol extensions.

4. Protocol Extensions

The cornerstone for POP is protocol extension. Swift (v2.0 onwards) allows a protocol to have a generic behavior that can be overridden as well. This generic behavior allows every implementation to “inherit” this by default. If they don’t like the generic behavior, well, simple, change it i.e., override it.
For e.g. the above example can now be written as

This is exactly like inheritance with the extra association of startWiper() now broken down to a need basis. Every implementation of Vehicle now has the complex startDriving() logic available by default i.e it has “inherited” the same from the protocol. Plus motorcycle does not have any association with Wipers. Thus protocol extensions help implementation to have the ability to “inherit” from a protocol and keep the dependency to an atomic level. i.e A protocol should contain only those contracts which an implementation or concrete object has to implement. Otherwise, it exhibits a fat interface problem. For e.g., Vehicle was a fat interface because it contained startWiper() which was not required for all subclasses.
5. Protocols & Value types
Swift advocates using value types over reference types wherever applicable. The use cases, benefits of both are well documented and won’t be covered here in this post. Value types like structenum can extend Protocols as well thus extending the benefits of designing using Protocols to even value types. This is one of the main reasons why Apple evangelizes using protocols over classes.

Bottom Line

POP extends OOP to provide another level of abstraction which helps a developer to write better code and design reusable components. Everything has its place under the sun and OOP is certainly not to be totally replaced with POP. Only where required. The decision to use POP or OOP can be context-specific

Tuesday 31 March 2020

What is a Serverless Architecture



Todefine serverless architecture (SA hereafter), consider what it’s not. SA does not mean the absence of physical infrastructure or machine. SA actually is a term that is from the Enterprises standpoint.
Putting up a backend infrastructure involves time and continuous maintenance. Setting up physical machines or virtual devices, installing applications, versioning, provisioning, scaling, load balancing, fail-safe mechanism, access restrictions..the list is endless. Backend as Service(BaaS) or cloud computing, in general, alleviates much of this task by doing the heavy lifting and hence, unsurprisingly, its popularity in software development. But there exists no silver bullet for any problem.
BaaS/Cloud comes with its own challenges. Imagine a service running on any popular BaaS platform which handles ’N’ number of requests every ’M’ minutes. Let’s assume this results in CPU usage of 5 %. With this rate if you compare the time the service is processing over a period of 24 hours, then a week, month and so on… the cost of usage is extremely inefficient. Enter Function as a Service(FaaS) or Serverless architectures.
FaaS or SA enables an Enterprise to run “on need basis” server components which are
  • Ephemeral
  • Stateless
  • Auto scalable

1. Ephemeral

A Serverless Architecture essentially comprises of functions that run for a short duration and are triggered or invoked by an event either as a common HTTP request or time-bound (Timer). When such a request rises the FaaS platform kicks in, initializes (if not already) and the function is executed. Once the execution is done the system is closed till the next execution. Hence unlike conventional BaaS “always-on” setup, we have a “not always on” serverless architecture. Please note this process would vary from provider to provider

2. Stateless

SA is best suited for stateless executions. Since the server provisioning and infrastructure is now managed by the cloud provider, there is no guarantee that the state maintained by the previous invocation of the service will be retained. This does not mean that FaaS does not support stateful operations, but just states that any state needs to be handled outside of the FaaS instance. A very good example of a state full operation which is Serverless is uploading to S3 via AWS Lambda.

3. Autoscaling

The benefits of SA are huge when it comes to scaling. Horizontal scaling is automatic and handled by the underlying platform. If the incoming traffic is high on a particular point of time multiple instances of the FaaS is invoked. If there is a lull in the traffic the instances are automatically reduced. The platform even handles the underlying resource management and allocations

Implementation/Deployment

FaaS functions can be implemented across a wide variety of languages and they do not require coding to any specific framework or any library. For eg all major providers support languages like JS, Go, etc The code/function is written and is simply uploaded. With services like AWS lambda, the code can be written in the AWS console itself. There is zero configuration required. For small to mid-sized organizations like product startup, this is a significant thing


Pros
  1. FaaS is extremely economical when compared to an existing cloud infrastructure as we saw in the earlier example. The cost of running a FaaS setup is simply based on how often and how long it’s used.
  2. Since scaling is automatic and reliable, enterprises do not have to worry about the economy of provisioning new server instances or removing unused ones. Everything is provided by the service provider
  3. With the economies of scale taken care of, enterprises or developers can focus on building better solutions. Moreover reduced costs enables enterprises to innovate and test newer products with shorter development cycles
Cons
  1. FaaS is completely dependent on the service provider and hence issues on the providers end like an outage, downtime, maintenance, security will have a significant impact on the Enterprises service
  2. Since FaaS is essentially a stateless server, the onus for maintaining the state falls on the client. This can result in repetition of logic and data across multiple clients
  3. FaaS is essentially a temporal entity. Google Cloud Functions for example times out after one minute(can be extended also). AWS Lambda functions are for five minutes. Unlike an “always-on” instance of BaaS, FaaS run only for a short duration
Conclusion
Serverless architecture is simply a paradigm where the responsibility of setting up, scaling, provisioning server-side systems is delegated to another entity. It offers cost benefits, leaner development time which can have a cascading effect of benefits for an enterprise. At the same time, it simply cannot replace all the existing systems which are built on a different architecture model. What can be implemented as FaaS is context-dependent

Monday 9 March 2020

What are Microservices


Microservices are an architectural pattern that classifies and implements an application into a collection of independent services that have a high level of autonomy. Usually, each of these services would be related to a single business group. Since these services are mostly autonomous, they can be built using different tech stacks. Microservice modules can be scaled, unit tested & modified with minimal effects to other modules in the system unlike the traditional monolithic architecture which is a collection of all the functionalities/services in one place
Microservices extend the principle of Single responsibility by focussing on a single capability or business domain. Which could be department specific, a region-specific, or any other custom business requirement. By decoupling the same from other services, development teams can iterate, test, build, and deploy the same in faster development cycles. Thus it's a natural fit for the agile development process. Microservices and API gateways usually go hand in hand. The reason being Microservices can be based on different protocols and stacks and a great deal of autonomy.
Let’s take an example to see how Microservices can help design robust, scalable systems. Consider an e-Commerce application which includes several services ranging from product details, purchase, cart, payment, history, details, so on and so forth. If this system is built in a monolithic fashion, the entire code, infrastructure, and database are centralized. Among other issues with a centralized setup, The only real option to scale this during peak traffic is running multiple instances of the same server. Plus when it comes to fault tolerance, a failure in one part of the system affects the others as well. Additionally, if a particular service needs to be updated or changed, to update the same, the whole system has to be redeployed after making the change.

Microservices help in handling such issues by separating each module and making them independent with well defined public interfaces. Along with an API gateway, microservice can offer a single unified interface for clients by abstracting the complexity underneath. Moreover, the independent, autonomous modules offer backend developers a scalable architecture with each microservice having the freedom to use a different development stack altogether
It’s tempting to ask how does this differ from a Service Oriented Architecture(SOA). After all, SOA also stresses on distinct components interacting amongst each other. The main difference between SOA and Microservice is that Microservices aims at modularising the system by building independent, self compassed units, unlike an SOA which focusses on building components that aim to provide services to other components by means of a common communication protocol. By that virtue, Microservice can be considered a fine-grained version of SOA.

Benefits

1. Since microservices are independent units, they can be worked upon by multiple small teams. This reduces the delivery time period and increases deployment frequency
2. In the event of any service failure, it can easily be isolated and fixed without any impact on other services
3. Individual units can be easily integrated into CI/CD pipelines
4. Components can be scaled based on a need basis. This reduces the cost and time of scaling the entire system to support a few modules.

Challenges

1. Microservices comprise individual components that are distributed. So the drawbacks associated with distributed systems apply here as well like reliability, latency, bandwidth, etc
2. Determining the boundary of a component is a complex process and requires an understanding of code dependencies
3. Depending on the number of modules the complexity of a microservice might increase more than a monolithic architecture

Conclusion

Microservice architecture offers tangible benefits for an application that has different modules spread across different requirements. But the implementation of the same has to be weighed against the need and complexity of the domain. As with any architecture, one size does not fit all and hence Microservices as a solution needs to be evaluated before implementation.