Class, Objects
Abstraction
Refers to modelling complex problems into abstract entities using only relevant information ignoring the irrelevant ones. This helps in standardization of code and reducing complexity. Implementation details are hidden.
Achieved by Interfaces and abstract classes.
Example - IPatientService with Get Details whose Implementation can change
Encapsulation
Refers to wrapping data and behaviors into single unit with providing public interaction ways to access the data and hide actual data.
Helps in data integrity through validation and avoiding accidental changes
Achieved by class access Modifiers getters setters
Example Patient class for HIPAA get details for PHI
Inheritance
Refers to extending existing entities to create new speciliazed entities
Helps in achieving is a hierarchy relationship and reusability
Achieve using single inheritance virtual override
Example patient admin from user
Polymorphism
Refers to ability of entities taking different forms based on context
Helps in flexibility and generic coding
Achieve using overloading and overriding
Example search different for different filter scenarios- account number, name
Overloading vs Overriding
Overloading - Static, compile
Refers to existence of methods of same signature in same class. The correct behaviour is inferred by compiler using call parameters
Overriding- Dynamic, Runtime
Refers to existence of methods of same definition with virtual override in related class. The correct behaviour is resolved by runtime using actual object type
Overriding vs Hiding
Base method is virtual
Overriding with override
Hiding with new
Overriding is creating new specialised implementation for child class. Resolved using actual object type
Hiding is to hide base implementation from child class. Resolved using object reference type.
Like when base can’t be modified but child needs to redefine and version.
Why SOLID Principles
Write code with future and long term maintenance and refactoring in mind.
The principles helps in writing code thats easy to understand, debug and test.
Avoid code duplication and reliable runtime code.
Avoid major rewites. Just mock testing swap refactoring
Single Responsibility Principle
States that a class must have only one reason to change. That is only if it’s set responsibility needs modification
Helps in creating lean, focused and clean classes
Else there will be huge classes that changes for many reason requiring long scope testing
Example Orderservice should only do business logic. DB access delegated to repository and Notifications to separate class
Open Closed Principle
Entities are open for extension but closed for modification. The idea is that better to add than rewrite. Create new interface instead of conditions and pick using behavioural pattern like strategy
Helps in avoiding unnecessary testing and silent bugs being introduced in stable features.
Else stable features need redundant testing even by which silent bugs can move on and cause bad UX
Example Instead of adding new order processor for sample with if else, add sampleorderprocessor interface and it’s concrete. The order service can pick the appropriate order processor using strategy pattern.
Liskov Substitution Principle
States that derived class objects should be substitutible in place of base class without changing existing behaviour. Base class need not know about derived classes. Spilt into interface and Compose
Helps in safe polymorphism and writing reliable code
Else runtime exceptions or inconsistent behaviour due to silent logic fails missed at compile time
Example if orderservice gets orderprocessor and uses it to process order in handle method where billing is done. New order sample which can’t be billed and hence can’t be put in place of order processor as it doesn’t have bill customer method.
Spilt into interface and Compose.
Make billable interface with bill customer. Order processor interface with process order
Order Type processor implementing order processor and optionally billable
Interface Segregation Principle
States that a class shouldn’t be forced to implement interfaces it doesn’t use. Split the interfaces into focused contract and compose.
Helps in keeping classes lean and focused. The code is clean and easy to read and understand
Else dummy implementations leading to tech debt. Violates SRP
Example useractions split to patientactions, adminactions
Dependency Inversion Principle
A high level module shouldn’t directly depend on low level module, instead both should depend on abstractions
Helps in loose coupling and mock testing, swap implementation to refactor and adapt long term
Else tied to a specific implementation making it rigid and major rewrite for refactoring
Example OrderService gets IOrderRepository and IOrderRepository implements IOrderRepository. Then can change between sql server or Oracle.
What is REST
Representational State Transfer is architectural style for designing web apps using stateless communication with resource based approach
What is SOAP
Simple object access protocol is protocol to exchange structured information using XML and is envelope based
REST vs SOAP
Rest is architectural style for stateless communication only supporting multiple data exchange formats. It is flexible
Soap is protocol for only xml data exchange but can be stateful. It is strict.
Caching is natively supported in REST and not in SOAP. SOAP requires additional tooling
JSON vs XML
Both are data exchange formats
JavaScript object notation json is key value pairs that’s easy to read. It is light weight and uses less bandwidth
Extensible markup language is tag based and verbose hence uses more bandwidth. It is better for complex multivocab language
What is API
Application Programming Interface is contract that defines how softwares communicate. The rules of inputs and outputs
REST Constraints
Statelessness, Cacheability, Uniform Interface, Layered System, Client Server Architecture, Code on Demand (opt)
Statelessness
States Every request is independent of each other and contains all information required to process and respond
Helps horizontal scaling - more servers can be added without redesign. Server doesn’t need memory instead just extract. Caching is easier
Else server memory cost. Need to have sticky sessions to be reliable against server crash
Cacheability
States that explicit define what can be cached and what can’t
Helps in reducing repeated calculation and fetching unnecessarily and reduce latency
Else CPU cost for calculation, network trips for fetching, Infrastructure cost high
Uniform Interface
States to have consistent standardised communication using url based on resource, http methods and response codes and messages with no hardcoding
Helps in supporting multiple clients without rewriting api for each, app Versioning to support new clients without breaking old
Cross platforms
Else tightly coupled rigid code duplication tough learning curve
Layered Systems
Client doesn’t know if talking to intermediary like gatewar, proxy or final server. Each layer is independent and specific responsibility
Helps in modularity and adding more. Hiding implementation details and reducing security attack surface. Each layer can evolve independently. Add load balancer for scalability
Else fragile in high traffic, security loopholes, hard to maintain
Client Server Architecture
States that there must be separation of concerns between client and server. Client only handles UI and server handles business logic. Client shouldn’t directly access DB and do business logic. It sends request and gets response. Server processes and fetches data
Helps in scalability security and maintenance. Helps in cross platforms client support. Both evolve independently with parallel development
Else security issue in client directly accessing DB. Duplication of business logic and validation