Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Ekon21 Microservices - SOLID Meets SOA

345 views

Published on

SOLID principles should better be applied when designing business objects, as soon as maintainability and modularity are needed. They bring uncoupling, abstraction and clean design to Object Oriented Programming. Microservices could be seen as SOLID principles applied to the Service Oriented Architecture. In respect to a classical monolith server, thanks to uncoupling and better granularity, you may enhance deployment, ease cooperation between dev teams, introduce Domain Driven Design and/or Event Driven Design, scale horizontally and still incorporate existing code and services.
After a quick and practical review of SOLID principles, we will see how they may apply to SOA, and how Microservices could be defined using the Open Source mORMot framework interface-based services, on Windows or Linux.

Published in: Software

Ekon21 Microservices - SOLID Meets SOA

  1. 1. Microservices - SOLID meets SOA Arnaud Bouchez - Synopse MICROSERVICES When SOLID Meets SOA
  2. 2. Microservices - SOLID meets SOA • Arnaud Bouchez – Delphi Expert • Various solutions (from Vatican to gaming industry) • IoT solution (RSI) • Real-time Monitoring solution (LiveMon) – Open Source • mORMot (SOA ORM MVC framework) • SynPDF SynMustache SynDB SynCrypto – Training and consultancy • Synopse one-man company
  3. 3. Microservices - SOLID meets SOA Microservices
  4. 4. Microservices - SOLID meets SOA SOLID meets SOA • Abstract via interface • SOLID Principles • Service Oriented Architecture • MicroServices • mORMot to the rescue
  5. 5. Microservices - SOLID meets SOA Abstract via interface • In Delphi OOP model – An interface defines a type that comprises abstract virtual methods – It is a declaration of functionality without an implementation of that functionality – It defines "what" is available, not "how" it is made available
  6. 6. Microservices - SOLID meets SOA Abstract via interface • Declaring an interface type ICalculator = interface(IInvokable) ['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}'] /// add two signed 32 bit integers function Add(n1,n2: integer): integer; end; • Naming convention: ICalculator • No visibility attribute: all published • No fields, just methods and properties • Unique identifier by GUID (Ctrl Shift G)
  7. 7. Microservices - SOLID meets SOA Abstract via interface Implementing an interface type TServiceCalculator = class(TInterfacedObject, ICalculator) protected fBulk: string; public function Add(n1,n2: integer): integer; procedure SetBulk(const aValue: string); end; function TServiceCalculator.Add(n1, n2: integer): integer; begin result := n1+n2; end; procedure TServiceCalculator.SetBulk(const aValue: string); begin fBulk := aValue; end; • ICalculator added to the “inheritance chain” • TCalculator implements a behavior
  8. 8. Microservices - SOLID meets SOA Abstract via interface • Using an interface function MyAdd(a,b: integer): integer; var Calculator: ICalculator; begin Calculator := TServiceCalculator.Create; result := Calculator.Add(a,b); end; • Strong typing • The variable defines a behavior (contract) • Path to abstraction
  9. 9. Microservices - SOLID meets SOA Abstract via interface • Using an interface function MyAdd(a,b: integer): integer; var Calculator: ICalculator; begin Calculator := nil; try Calculator := TServiceCalculator.Create; result := Calculator.Add(a,b); finally Calculator := nil; end; end; • The compiler generates some hidden code with automatic initalization/finalization
  10. 10. Microservices - SOLID meets SOA Abstract via interface • Using an interface function MyAdd(a,b: integer): integer; var Calculator: ICalculator; begin Calculator := nil; try Calculator := TServiceCalculator.Create; // inc(RefCount) result := Calculator.Add(a,b); finally Calculator := nil; // dec(RefCount); =0? -> Free end; end; • The compiler generates some hidden code with automatic reference counting (ARC)
  11. 11. Microservices - SOLID meets SOA Abstract via interface There is more than one way to do it type TServiceCalculator = class(TInterfacedObject, ICalculator) protected fBulk: string; public function Add(n1,n2: integer): integer; procedure SetBulk(const aValue: string); end; function TServiceCalculator.Add(n1, n2: integer): integer; begin result := n1+n2; end; procedure TServiceCalculator.SetBulk(const aValue: string); begin fBulk := aValue; end; • ICalculator does not enforce a single implementation class
  12. 12. Microservices - SOLID meets SOA Abstract via interface There is more than one way to do it type TAnotherServiceCalculator = class(TInterfacedObject, ICalculator) protected fBulk: string; public function Add(n1,n2: integer): integer; procedure SetBulk(const aValue: string); end; function TAnotherServiceCalculator.Add(n1, n2: integer): integer; begin result := n2+n1; // I’m a math genius! end; procedure TAnotherServiceCalculator.SetBulk(const aValue: string); begin fBulk := aValue; end; • ICalculator does not enforce a single implementation class
  13. 13. Microservices - SOLID meets SOA Abstract via interface • There is more than one way to do it procedure ResolveCalculator(out: ICalculator); … function MyAdd(a,b: integer): integer; var Calculator: ICalculator; begin ResolveCalculator(Calculator); result := Calculator.Add(a,b); end; • The variable defines a behavior (contract) • Resolve and inject the actual implementation • Path to abstraction we don’t know (and don’t need) which class is actually used
  14. 14. Microservices - SOLID meets SOA Abstract via interface • Abstraction is the key – Focus on contracts, not completion – Favor logic over implementation – Late binding/resolution – Local/remote execution (SOA) – Stub/mock tooling – Dependency Injection / Inversion Of Concern
  15. 15. Microservices - SOLID meets SOA SOLID Principles • Single responsibility principle • Open/closed principle • Liskov substitution principle (design by contract) • Interface segregation principle • Dependency inversion principle
  16. 16. Microservices - SOLID meets SOA SOLID Principles • Single responsibility – Object should have only a single responsibility • Open/closed – Entities should be open for extension, but closed for modification • Liskov substitution (design by contract) – Objects should be replaceable with instances of their subtypes without altering the correctness of that program • Interface segregation – Many specific interfaces are better than one • Dependency inversion – Depend upon abstractions, not depend upon concretions
  17. 17. Microservices - SOLID meets SOA SOLID Principles • Single Responsibility – When you define a class, it shall be designed to implement only one feature – The so-called feature can be seen as an "axis of change" or a "a reason for change"
  18. 18. Microservices - SOLID meets SOA SOLID Principles • Single Responsibility – One class shall have only one reason that justifies changing its implementation – Classes shall have few dependencies on other classes – Classes shall be abstracted from the particular layer they are running
  19. 19. Microservices - SOLID meets SOA • Single Responsibility – Splitting classes • Imagine a TBarCodeScanner class to handle a serial bar-code scanner • Later on, we want to implement USB support – First idea may be to inherit SOLID Principles
  20. 20. Microservices - SOLID meets SOA SOLID Principles • Single Responsibility – Splitting classes • Later on, the manufacturer updates its protocol To add new features, e.g. 3D scanning or coffee making – How do we implement this? – We have two “axis of change” so we would define two classes
  21. 21. Microservices - SOLID meets SOA SOLID Principles • Single Responsibility – Splitting classes • Later on, the manufacturer updates its protocol To add new features, e.g. 3D scanning or coffee making – We defined two classes, which will be joined/composed in actual barcode scanner classes
  22. 22. Microservices - SOLID meets SOA SOLID Principles • Single Responsibility – Compose classes TAbstractBarcodeScanner = class(TComponent) protected fProtocol: TAbstractBarcodeProtocol; fConnection: AbstractBarcodeConnection; ... constructor TSerialBarCodeScanner.Create( const aComPort: string; aBitRate: integer); begin fConnection := TSerialBarcodeConnection(aComPort,aBitRate); fProtocol := TBCP1BarcodeProtocol.Create(fConnection); end;
  23. 23. Microservices - SOLID meets SOA SOLID Principles • Single Responsibility – Do not mix GUI and logic – Do not mix logic and database – Do not couple your code to an OS • Check your uses statement – There should be no reference to the UI (e.g. Dialogs) in your business class – No dependency to DB libraries (this is a hard one) – No reference to WinAPI.Windows
  24. 24. Microservices - SOLID meets SOA SOLID Principles • Single Responsibility – Code smells • When abusing of FreeAndNil(); {$ifdef} … {$endif} uses unit1, unit2, unit3, … unit1000; • When you can’t find the right method in a class (mORMot may need some refactoring here)  • When unitary tests are hard to write
  25. 25. Microservices - SOLID meets SOA SOLID Principles • Open / Close principle – When you define a class or an interface • it shall be open for extension • but closed for modification
  26. 26. Microservices - SOLID meets SOA SOLID Principles • Open / Closed principle – Open for extension • Abstract class is overridden by implementations • No singleton nor global variable – ever • Rely on abstraction • if aObject is aClass then … it stinks! – Closed for modification • e.g. via explicitly protected or private members • RTTI is dangerous: it may open a closed door
  27. 27. Microservices - SOLID meets SOA SOLID Principles • Open / Closed principle – In practice • Define meaningful interface types – Following the Design By Contract principle • Define Value objects (DTOs) to transfer the data – With almost no methods, but for initialization – With public members, to access the value • Define Process objects to modify the data – With public methods, abstracted in the interface – With mostly private members
  28. 28. Microservices - SOLID meets SOA SOLID Principles • Open / Close principle type TAbstractBarcodeScanner = class(TComponent) protected fProtocol: TAbstractBarcodeProtocol; fConnection: AbstractBarcodeConnection; public property Protocol: TAbstractBarcodeProtocol read fProtocol; property Connection: AbstractBarcodeConnection read fConnection; ... • Protocol and Connection are read/only – They are injected by the overridden class constructor – So it will be Open for extension
  29. 29. Microservices - SOLID meets SOA SOLID Principles • Open / Close principle type TAbstractBarcodeScanner = class(TComponent) protected fProtocol: TAbstractBarcodeProtocol; fConnection: AbstractBarcodeConnection; public property Protocol: TAbstractBarcodeProtocol read fProtocol; property Connection: AbstractBarcodeConnection read fConnection; ... • Protocol and Connection are read/only – You could not change the behavior of a class – It is Closed for modification
  30. 30. Microservices - SOLID meets SOA SOLID Principles • Liskov substitution principle
  31. 31. Microservices - SOLID meets SOA SOLID Principles • Liskov substitution principle
  32. 32. Microservices - SOLID meets SOA SOLID Principles • Liskov substitution principle – If TChild is a subtype of TParent • then objects of type TParent may be replaced with objects of type TChild • without altering any of the desirable properties of that program (correctness, task performed, etc.)
  33. 33. Microservices - SOLID meets SOA SOLID Principles • Liskov substitution principle – If TChild is a subtype of TParent • You could be able to use any inherited or parent class – Tied to the Open / Closed principle • So when you inherit, you keep your contract you should not break any parent expectation
  34. 34. Microservices - SOLID meets SOA SOLID Principles • Liskov substitution principle – Tied to the Open / Closed principle • If you define a child, you should not modify the parent – Code-reusability of the parent implementation – You will be able to stub or mock an interface or a class • Allow correct testing of the whole system: even if all single unit/integration tests did pass, real system may not work if this principle was broken
  35. 35. Microservices - SOLID meets SOA SOLID Principles • Liskov substitution principle – Design by contract • Meyer's (Eiffel language) rule: “when redefining a routine [in a derivative], you may only replace its precondition by a weaker one, and its postcondition by a stronger one” • Define assertions at method level: – What does it expect, guarantee, and maintain? – About input/output values or types, side effects, invariants, errors/exceptions, performance… – Write comments and unit tests
  36. 36. Microservices - SOLID meets SOA SOLID Principles • Liskov substitution principle – Practical, not dogmatic LSP • “Parent” and “Child” are not absolute Depending on the context, you may define a specific level as the “highest” LSP abstract class » e.g. if you work on server side, you may need some server-only properties and methods » LSP idea is to be consistent about your contract, once the abstraction level is defined
  37. 37. Microservices - SOLID meets SOA SOLID Principles • Liskov substitution broken code if aObject is aClass then … case aObject.EnumeratedType of … function … abstract; without further override; unit parent; uses child1,child2,child3;
  38. 38. Microservices - SOLID meets SOA SOLID Principles • Interface segregation principle – Once an interface has become too 'fat' it shall be split into smaller and more specific interfaces so that any clients of the interface will only know about the methods that pertain to them – In a nutshell, no client should be forced to depend on methods it does not use
  39. 39. Microservices - SOLID meets SOA SOLID Principles • Interface segregation principle – Perfectly fits the SOA uncoupling pattern • Stateless Microservices for horizontal scaling – Allows to release memory and resources ASAP • Smaller objects have more bounded dependencies – Ease unit testing • Less coverage • Less coupling
  40. 40. Microservices - SOLID meets SOA SOLID Principles • Interface segregation principle – Excludes RAD • Logic implemented in TForm TDataModule where methods are procedural code in disguise • Put your logic behind interfaces and call them from your UI (over VCL and FMX) – Favors DDD • Segregation avoid domain leaking • Dedicated interfaces, e.g. for third party consumption
  41. 41. Microservices - SOLID meets SOA SOLID Principles • Dependency Inversion – High-level modules should not depend on low-level modules • Both should depend on abstractions – Following other SOLI(D) principles – Abstractions should not depend upon details • Details should depend upon abstractions – Business Logic should not depend on database – Application Layer should not depend on client technology
  42. 42. Microservices - SOLID meets SOA SOLID Principles • Dependency Inversion – In most conventional programming style: • You write low-level components (e.g. DB tables) • Then you integrate them with high-level components – But this limits the re-use of high-level code • In fact, it breaks the Liskov substitution principle • It reduces the testing abilities (e.g. need of a real DB)
  43. 43. Microservices - SOLID meets SOA SOLID Principles • Dependency Inversion may be implemented – Via a plug-in system • e.g. external libraries (for embedded applications) – Using a service locator • e.g. SOA catalog (SaaS/cloud) • class resolution from an interface type – Switch to Event Driven Design • e.g. using messages over a bus or Peer-To-Peer communication
  44. 44. Microservices - SOLID meets SOA Service Oriented Architecture Definition: A flexible set of design principles used during the phases of systems development and integration To package functionality as a suite of inter-operable services that can be used within multiple, separate systems from several business domains
  45. 45. Microservices - SOLID meets SOA Service Oriented Architecture – The SOA implementations rely on a mesh of uncoupled software services – Software Service: • A consumer asks a producer to act in order to produce a result • Invocation is (often) free from previous invocation (stateless), to minimize resource consumption
  46. 46. Microservices - SOLID meets SOA Service Oriented Architecture – The SOA implementations rely on a mesh of uncoupled software services – Those Services comprise • unassociated, loosely coupled units of functionality (each service implements one action) • that have no direct call to each other (via protocols, catalogs over a bus)
  47. 47. Microservices - SOLID meets SOA Service Oriented Architecture – The SOA implementations rely on a mesh of uncoupled software services Consumers Service Bus Publishers Client A Publisher 1 Publisher 2Client B Publisher 3Client C Service 1 Service 2 Service 3
  48. 48. Microservices - SOLID meets SOA Service Oriented Architecture – The SOA implementations rely on a mesh of uncoupled software services – Service composition Consumers Application Service Bus Application Publishers Business Service Bus Business Publishers Client A Composition Publisher Composition Service Publisher 1 Publisher 2 Publisher 3 Service 1 Service 2 Service 3
  49. 49. Microservices - SOLID meets SOA Service Oriented Architecture • Expects a top/down implementation – From n-Tier vertical Architecture • DB as Root • Business over DB – to Clean “onion” Architecture • Domain as Core • Persistence as a service
  50. 50. Microservices - SOLID meets SOA Microservices
  51. 51. Microservices - SOLID meets SOA Microservices
  52. 52. Microservices - SOLID meets SOA Microservices • How to avoid Just Smaller BBM™ ?
  53. 53. Microservices - SOLID meets SOA Microservices – SOLID principles meet SOA • Single responsibility principle • Open/closed principle • Liskov substitution principle (design by contract) • Interface segregation principle • Dependency inversion principle
  54. 54. Microservices - SOLID meets SOA Microservices – SOLID principles meet SOA • Single responsibility principle Services should have a single axis of change • Open/closed principle Services should be extendable, but not modifiable • Liskov substitution principle (design by contract) Services should be replaceable • Interface segregation principle Several smaller dedicated services • Dependency inversion principle Services focus on abstraction, not concretion
  55. 55. Microservices - SOLID meets SOA Microservices – SOLID principles meet SOA • Single responsibility principle Microservices should have a single axis of change • Open/closed principle Microservices should be extendable, not modifiable • Liskov substitution principle (design by contract) Microservices should be replaceable • Interface segregation principle Several smaller dedicated Microservices • Dependency inversion principle Microservices focus on abstraction, not concretion
  56. 56. Microservices - SOLID meets SOA Microservices – SOLID principles meeting SOA – Favor stateless calls, and/or event-driven – Implemented as stand-alone uncoupled nodes with their own persistence – Enhance scaling abilities – In-house Microservices focus on domain On-the-shelf SaaS can be used otherwise – Expects services discovery and/or balancing
  57. 57. Microservices - SOLID meets SOA Microservices • Most difficult is to define its own storage – We were used and told to start from the DB First task was to define SQL tables – SOLID expect uncoupled design-by-contract So each Microservice should have its own DB – Depending on the use-case, DB may be: • Classic Client-Server SQL • Local SQLite3 SQL or Object DB • NoSQL Client-Server store • Pure in-memory cache with no persistence
  58. 58. Microservices - SOLID meets SOA Microservices
  59. 59. Microservices - SOLID meets SOA Microservices • Each Microservice owns its persistence – Resulting in global Eventual Consistency may be still atomic (SQL) within the Microservice
  60. 60. Microservices - SOLID meets SOA Microservices • Client-To-Microservice Architecture
  61. 61. Microservices - SOLID meets SOA Microservices • Client-To-Microservice Architecture
  62. 62. Microservices - SOLID meets SOA Microservices • Clean Architecture via API layer
  63. 63. Microservices - SOLID meets SOA Microservices • Monolithic UI consuming Microservices
  64. 64. Microservices - SOLID meets SOA Microservices • Composite UI consuming Microservices
  65. 65. Microservices - SOLID meets SOA mORMot to the rescue
  66. 66. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services – Define your services contracts as interfaces type ICalculator = interface(IInvokable) ['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}'] /// add two signed 32 bit integers function Add(n1,n2: integer): integer; end; • ICalculator interface defines the contract • Add() method defines the operation – Handle any kind of parameters • Including classes, variants, dynamic arrays or records
  67. 67. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services Define your services contracts as interfaces • Following SOLID principles small dedicated interfaces consumed as abstract method calls with meaningful naming and types not polluted by the framework favoring explicit DTO defined as code • Run/test/debug/validate implementation locally
  68. 68. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services Implement the contract on server side type TServiceCalculator = class(TInterfacedObject, ICalculator) public function Add(n1,n2: integer): integer; end; function TServiceCalculator.Add(n1, n2: integer): integer; begin result := n1+n2; end; … and that’s all !
  69. 69. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services Host and publish the service Server.ServiceRegister( TServiceCalculator,[TypeInfo(ICalculator)],sicShared); will register the TServiceCalculator class to implement the ICalculator service with a single shared instance life time to any TSQLRestServer instance
  70. 70. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services Host and publish the service Server.ServiceDefine( TServiceCalculator,[ICalculator],sicShared); will register the TServiceCalculator class to implement the ICalculator service with a single shared instance life time to any TSQLRestServer instance
  71. 71. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services – Host and publish the service
  72. 72. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services Access the service from client side Client.ServiceDefine([ICalculator],sicShared); var I: ICalculator; begin if Client.Services['Calculator'].Get(I) then result := I.Add(10,20); end; • Register to any kind of TSQLRestClient • Execution will take place on the server side, using a “fake” class implementing ICalculator • Data is transmitted by representation as JSON (array of) values • Any server-side exception will be transmitted to the client
  73. 73. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services Access the service from client side if Client.Services['Calculator'].Get(I) then POST https://servername/restroot/calculator/add with { “n1”: 10, “n2”: 20 } as JSON body returns HTTP/1.1 200 { “result”: 30 } result := I.Add(10,20); • Data is transmitted by representation as JSON (array of) values • Input parameters as request body, output parameters in answer
  74. 74. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services Access the service from client side if Client.Services['Calculator'].Get(I) then POST https://servername/restroot/calculator/add with [10,20] as JSON body between Delphi clients returns HTTP/1.1 200 { “result”: 30 } result := I.Add(10,20); • Data is transmitted by representation as JSON (array of) values • Input parameters as request body, output parameters in answer
  75. 75. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services – Define your services contracts as interfaces – By changing one code line, run them • In-process - direct call in the same thread • Locally - using local loopback socket • Remotely - using HTTP/WebSockets connection
  76. 76. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services – Define your services contracts as interfaces – Test-Driven approach • Abstract from actual infrastructure (DB, network…) • Stub/mock dependencies for unit testing • Single process hosting for integrative system tests
  77. 77. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services – Integrated features • Convention-Over-Configuration REST / JSON from the ground up, with huge performance • Security, authentication, sessions, threads, low-level (text) logs + high-level (SQlite3) logs • WebSockets for EDD realtime interface callbacks • Rich data model, from strong types to TDocVariant
  78. 78. Microservices - SOLID meets SOA mORMot to the rescue • ORM/ODM for the persistence layer – Persistence agnosticism for MicroServices • ORM over local SQlite3 store • ORM over remote SQL databases • ODM over TObjectList • ODM over MongoDB Switching from one to another in a few lines of code, or through settings
  79. 79. Microservices - SOLID meets SOA mORMot to the rescue • ORM/ODM for the persistence layer – Persistence agnosticism for MicroServices • Aggregates mapped to TSQLRecord to write Repository services • Advanced ORM features – REST automated routing, optional remote proxying – Direct DB-to-JSON serialization (no TDataSet) – Built-in statement and JSON cache – Batch (Unit-Of-Work) writes with bulk SQL/NoSQL insertion – SQL logging/timing, Real-time replication, data sharding
  80. 80. Microservices - SOLID meets SOA mORMot to the rescue • mORMot distinctive features • REST and JSON from the ground up • Open Source 90 man-year development • From Delphi 6 to latest 10.2 FPC ready (for Linux/BSD server code) • Not RAD – expressive source code • Fully integrated SOA + ORM + MVC + …
  81. 81. Microservices - SOLID meets SOA mORMot to the rescue • Interface-based services – To be continued, including more code ;) with next session Microservices and Event Driven Systems
  82. 82. Microservices - SOLID meets SOA Microservices – SOLID meets SOA • Credits some pics taken from (even if Delphi stand-alone exe and whole mORMot design voids the need of containers) Free download https://goo.gl/VMbkYm code and samples at https://synopse.info
  83. 83. Microservices - SOLID meets SOA Microservices – SOLID meets SOA • Questions?

×