SlideShare ist ein Scribd-Unternehmen logo
1 von 94
Downloaden Sie, um offline zu lesen
Towards Functional Programming 🦄
through Hexagonal Architecture 🎯
Habla Computing + CodelyTV
Acercándonos a la Programación Funcional 🦄
a través de la Arquitectura Hexagonal 🎯
Habla Computing + CodelyTV
Text
#SCBCN18
Software Crafters Barcelona - VI Edition
Functional Programming intro based on Hexagonal Architecture
Who we are
@JavierCane@juanshac
Session goal
🤔

Rethinking time
Functional Programming intro based on Hexagonal Architecture
Reviewing different technics to solve the same problems with more modularity
👤
Domain
models
Contents
🗺Design principles
&Implementation details
🦄
Functional
Architectures
🎯
Hexagonal
Architecture
🏗
Layers
implementation
Functional Programming intro based on Hexagonal Architecture
⚡
Error
Handling
👤
Domain
models
Contents
🗺Design principles
&Implementation details
🦄
Functional
Architectures
🎯
Hexagonal
Architecture
🏗
Layers
implementation
Functional Programming intro based on Hexagonal Architecture
⚡
Error
Handling
🗺 Design principles > 🎯 Hexagonal Architecture
🛀 Clean Architectures
🤯 Ports & adapters
🚫
🗺 Design principles > 🎯 Hexagonal Architecture
Layers & dependency rule
Infrastructure
Application
Domain
🗺 Design principles > 🎯 Hexagonal Architecture
Layered Architecture
Presentation
Domain
Database
🗺 Design principles > 🎯 Hexagonal Architecture
Layered vs Hexagonal
Presentation
Domain
Database
Infrastructure
Application
Domain
🗺 Design principles > 🎯 Hexagonal Architecture
CONTROLLER
REPOS
MODELS
SERVICES
APPLICATION SERVICE
D
A
I
Request flow
IMPLEMENTATION
Acceptance test
Unit test Integration test
🗺 Design principles > 🎯 Hexagonal Architecture
Acceptance test
Unit test Integration test
CONTROLLER
REPOS
MODELS
SERVICES
APPLICATION SERVICE
D
A
I
Request flow
IMPLEMENTATION
🗺 Design principles > 🎯 Hexagonal Architecture
Port
Adapter
VideoPostController
VideoRepository
VideoVideoCreator
D
A
I
DoobieMySqlVideoRepo
Acceptance test
Unit test Integration test
Request flow example
🗺 Design principles > 🎯 Hexagonal Architecture
VideoPostController
VideoRepository
VideoVideoCreator
D
A
I
DoobieMySqlVideoRepo
Acceptance test
Unit test Integration test
Port
Adapter
🗺 Design principles > 🎯 Hexagonal Architecture
Request flow example
Domain Events, CQRS, and Event Sourcing as an optional further step
👤
Domain
models
Contents
🗺Design principles
&Implementation details
🦄
Functional
Architectures
🎯
Hexagonal
Architecture
🏗
Layers
implementation
Functional Programming intro based on Hexagonal Architecture
⚡
Error
Handling
👤
Domain
models
Contents
🗺Design principles
&Implementation details
🦄
Functional
Architectures
🎯
Hexagonal
Architecture
🏗
Layers
implementation
Functional Programming intro based on Hexagonal Architecture
⚡
Error
Handling
What is a functional architecture?
DSL1
DSL2
DSLN
…
🗺 Design principles > 🦄 Functional Architectures
A FUNCTIONAL LANGUAGE IS A DOMAIN-
SPECIFIC LANGUAGE FOR DEFINING
DOMAIN-SPECIFIC LANGUAGES
The DSLs of your application
• Infrastructure DSLs
• HTTP
• Databases
• Messaging
• Application-specific DSLs
• Use cases
• Repos
• …
HTTP
SERVICE DSL
SQL
REPO DSL
🗺 Design principles > 🦄 Functional Architectures
Are hexagonal and functional architectures like apples and oranges?
HTTP
SERVICE DSL
SQL
REPO DSL
CONTROLLER
SERVICE IMPL.
ORM
DB
ADAPTER/INTERP.
PORT/DSL
🗺 Design principles > 🦄 Functional Architectures
There are no exceptions • Everything is either a port or an adapter
• Every adapter implements a given port
• Adapters are implemented on top of other ports
VideoPostController
VideoRepositoryVideoRepoC
DoobieMySqlVideoRepo
VideoCreator
HTTP
🗺 Design principles > 🦄 Functional Architectures
🎯
🦄
VideoPostController
VideoRepository
VideoCreator
DoobieMySqlVideoRepo
VideoPostController
VideoRepositoryVideoRepoC
DoobieMySqlVideoRepo
VideoCreator
HTTP
🤔 Rethinking time
🗺 Design principles
🗺 Design principles > 🤔 Rethinking time
Final goals
• Decouple from infrastructure
• Testing easiness (test doubles when testing out use cases)
• Change tolerance
• ¡Same goals!
🗺 Design principles > 🤔 Rethinking time
Differences: More decoupling and indirection levels
• Controllers:
• Consistency (APIs for all DSLs) vs. Specific needs
• Conclusion: We need industry standards. PHP-FIG as example to follow
• Application Services:
• Consistency (APIs for all DSLs) vs. Specific needs
• Reuse use case APIs in clients (e.g. user clients)
👤
Domain
models
Contents
🗺Design principles
&Implementation details
🦄
Functional
Architectures
🎯
Hexagonal
Architecture
🏗
Layers
implementation
Functional Programming intro based on Hexagonal Architecture
⚡
Error
Handling
👤
Domain
models
Contents
🗺Design principles
&Implementation details
🦄
Functional
Architectures
🎯
Hexagonal
Architecture
🏗
Layers
implementation
Functional Programming intro based on Hexagonal Architecture
⚡
Error
Handling
🎯 OOP
👤 Domain models
final case class Video(
id: VideoId,
title: VideoTitle,
quality: VideoQuality
)
👤 Domain models > 🎯 OOP > Video Entity
object Video {
def apply(id: String, title: String, quality: Int): Video =
Video(
VideoId(id),
VideoTitle(title),
VideoQuality(quality)
)
}
final case class Video(
id: VideoId,
title: VideoTitle,
quality: VideoQuality
)
👤 Domain models > 🎯 OOP > Video Entity
object Video {
def apply(id: String, title: String, quality: Int): Video =
Video(
VideoId(id),
VideoTitle(title),
VideoQuality(quality)
)
}
final case class Video(
id: VideoId,
title: VideoTitle,
quality: VideoQuality
)
👤 Domain models > 🎯 OOP > Video Entity
object VideoQuality {
val maxQuality = 50
val minQuality = 0
}
final case class VideoQuality(value: Int) {
require(value <= maxQuality, s"Video quality value greater than $maxQuality")
require(value >= minQuality, s"Video quality value less than $minQuality")
def increase(): VideoQuality = {
if (value >= maxQuality) this
else copy(value + 1)
}
}
OOP: Data+Behaviour
👤 Domain models > 🎯 OOP > VideoQuality Value Object
object VideoQuality {
val maxQuality = 50
val minQuality = 0
}
final case class VideoQuality(value: Int) {
require(value <= maxQuality, s"Video quality value greater than $maxQuality")
require(value >= minQuality, s"Video quality value less than $minQuality")
def increase(): VideoQuality = {
if (value >= maxQuality) this
else copy(value + 1)
}
}
Behaviour
Simpler API
+ domain semantics
+ immutability
👤 Domain models > 🎯 OOP > VideoQuality Value Object
case class Video(
id: VideoId,
title: VideoTitle,
quality: VideoQuality
) {
def increaseQuality(): Video =
copy(quality = quality.increase())
}
VideoQualityIncreaser Video
increaseQuality()
Behaviour
Rich domain model - Tell don’t ask
👤 Domain models > 🎯 OOP > Video Entity
public final class Video {
private VideoId id;
private VideoQuality quality;
// …
public VideoQuality getQuality() {
return quality;
}
public void setQuality(
VideoQuality quality
) {
this.quality = quality;
}
}
VideoQualityIncreaser Video
getQuality()
increaseQuality()
setQuality()
Behaviour
👤 Domain models > 🎯 OOP > Video Entity
setQuality()
getQuality()
increaseQuality()
…Increaser Video
Behaviour
…Increaser Video
Behaviour
👤 Domain models > 🎯 OOP > Video Entity
increaseQuality()
🦄 Functional Programming
👤 Domain models
…Increaser Video
Behaviour
👤 Domain models > 🦄 FP > Video Entity
increaseQuality()
…Increaser
increaseQuality()
Behaviour Video
…
def increaser[V: VideoBehaviour](
video: V): V =
video.increaseQuality()
Increaser
increaseQuality()
LOGIC
VideoBehaviour
Rich domain layer - Tell don’t ask
Do not expose quality property
👤 Domain models > 🦄 FP > Video EntityTYPE CLASSES: API
trait VideoBehaviour[T]{
val maxQuality: Int
val minQuality: Int
def increaseQuality(thing: T): T
}
+Less coupling!
PlainVideo
👤 Domain models > 🦄 FP > Video Entitycase class PlainVideo(
id: VideoId,
title: VideoTitle,
quality: VideoQuality
)
copy(quality=…)
quality
increase
:VideoImpl
VideoBeh
INSTANTIATION
implicit object VideoImpl
extends VideoBehaviour[PlainVideo]{
val maxQuality = 100
val minQuality = 10
def increaseQuality(video: PlainVideo) =
video.copy(quality =
video.quality.increase)
}
Video
Behaviour
👤 Domain models > 🦄 FP > Video Entitycase class Video(
id: VideoId,
title: VideoTitle,
quality: VideoQuality){
def increaseQuality(): Video =
copy(quality = quality.increase())
}
increaseQuality()
:VideoImpl
implicit object VideoImpl
extends VideoBehaviour[Video]{
val maxQuality = Video.maxQuality
def increaseQuality(video: Video) =
video.increaseQuality
}
VideoBeh
INSTANTIATION
👤 Domain models > 🦄 FP > Video Entity
COMPOSITION
def plainVideoIncreaser(video: PlainVideo): PlainVideo =
increaser[PlainVideo](video)
def videoIncreaser(video: Video): Video =
increaser[Video](video)
🤔 Rethinking time
👤 Domain models
& Implementation > 👤 Domain models > 🤔 Rethinking time
Differences on Domain Modelling goals
• 🦄 FP Type classes: APIs with steroids
• Goal: Coupling to behaviours (not to state)
• Decouple behaviour and data
• Support rich domain layers
• 🎯 OOP: High cohesion (behaviour close to related data)
• Modularity because abstractions => More indirection levels (complexity)
• Goal: Rich domain models (data+behaviour)
INSTANTIATION
TYPECLASS: API
COMPOSITION
LOGIC
👤
Domain
models
Contents
🗺Design principles
&Implementation details
🦄
Functional
Architectures
🎯
Hexagonal
Architecture
🏗
Layers
implementation
Functional Programming intro based on Hexagonal Architecture
⚡
Error
Handling
👤
Domain
models
Contents
🗺Design principles
&Implementation details
🦄
Functional
Architectures
🎯
Hexagonal
Architecture
🏗
Layers
implementation
Functional Programming intro based on Hexagonal Architecture
⚡
Error
Handling
🎯 Hexagonal Architecture
🏗 Layers implementations
final class VideoPostController(creator: VideoCreator) {
def post(id: String, title: String): StandardRoute = {
creator.create(VideoId(id), VideoTitle(title))
complete(HttpResponse(Created))
}
}
VideoPostController - HTTP API Controller
VideoPostController
final class VideoPostController(creator: VideoCreator) {
def post(id: String, title: String): StandardRoute = {
creator.create(VideoId(id), VideoTitle(title))
complete(HttpResponse(Created))
}
}
VideoPostController - HTTP API Controller
VideoPostController
final class VideoCreator(
repository: VideoRepository,
publisher: MessagePublisher
) {
def create(id: VideoId, title: VideoTitle): Unit = {
val video = Video(id, title)
repository.save(video)
publisher.publish(VideoCreated(video))
}
}
VideoCreator - Application Service/Use case
VideoPostController VideoCreator
final class VideoCreator(
repository: VideoRepository,
publisher: MessagePublisher
) {
def create(id: VideoId, title: VideoTitle): Unit = {
val video = Video(id, title)
repository.save(video)
publisher.publish(VideoCreated(video))
}
}
VideoCreator - Application Service/Use case
VideoPostController VideoCreator
trait VideoRepository {
def all(): Future[Seq[Video]]
def save(video: Video): Future[Unit]
}
VideoRepository - Domain contract/Port
VideoPostController VideoRepositoryVideoCreator
DoobieMySqlVideoRepository - Infrastructure implementation/Adapter
VideoPostController VideoRepositoryVideoCreator
DoobieMySqlVideoRepo
final class DoobieMySqlVideoRepository(db: DoobieDbConnection)
(implicit ec: ExecutionContext) extends VideoRepository {
override def all(): Future[Seq[Video]] =
db.read(sql”SELECT…”.query[Video].to[Seq])
override def save(video: Video): Future[Unit] =
sql"INSERT INTO…”.update.run
.transact(db.transactor)
.unsafeToFuture().map(_ => ())
}
🦄 Functional Architectures
🏗 Layers implementations
trait VideoRepository {
def all(): Future[Seq[Video]]
def save(video: Video):
Future[Unit]
}
Domain contract/PortVideoRepository
?
trait VideoRepository {
def all(): cats.IO[Seq[Video]]
def save(video: Video):
cats.IO[Unit]
}
trait VideoRepository {
def all(): Seq[Video]
def save(video: Video): Unit
}
trait VideoRepository {
def all(): Seq[Video]
def save(video: Video): Unit
}
trait VideoRepository {
def all(): Future[Seq[Video]]
def save(video: Video):
Future[Unit]
}
trait VideoRepository {
def all(): cats.IO[Seq[Video]]
def save(video: Video):
cats.IO[Unit]
}
Domain contract/Port
infrastructure leaks
VideoRepository
?
trait VideoRepository[P[_]] {
def all(): P[Seq[Video]]
def save(video: Video): P[Unit]
}
TYPE (CONSTRUCTOR) CLASSES
VideoRepository
?
Domain contract/Port
Infrastructure implementation/Adapter
import scala.concurent.Future
final class DoobieMySqlVideoRepoFuture(
db: DoobieDbConnection[Future])(implicit
ec: ExecutionContext) extends VideoRepository[Future] {
override def all(): Future[Seq[Video]] =
db.read(sql"SELECT ...".query[Video].to[Seq])
override def save(video: Video): Future[Unit] =
sql"INSERT INTO ... ".update.run
.transact(db.transactor)
.map(_ => ())
}
VideoRepository
DoobieVideoRepoFuture
INSTANTIATION
Infrastructure implementation/Adapter
import scala.concurent.Future
final class DoobieMySqlVideoRepoFuture(
db: DoobieDbConnection[Future])(implicit
ec: ExecutionContext) extends VideoRepository[Future] {
override def all(): Future[Seq[Video]] =
db.read(sql"SELECT ...".query[Video].to[Seq])
override def save(video: Video): Future[Unit] =
sql"INSERT INTO ... ".update.run
.transact(db.transactor)
.map(_ => ())
}
VideoRepository
DoobieVideoRepoFuture
INSTANTIATION
Infrastructure implementation/AdapterVideoRepository
DoobieVideoRepoIO
import cats.effect.IO
final class DoobieMySqlVideoRepoIO(
db: DoobieDbConnection[IO]) extends VideoRepository[IO] {
override def all(): IO[Seq[Video]] =
db.read(sql"SELECT ...".query[Video].to[Seq])
override def save(video: Video): IO[Unit] =
sql"INSERT INTO ... ".update.run
.transact(db.transactor)
.map(_ => ())
}
INSTANTIATION
Infrastructure implementation/AdapterVideoRepository
DoobieVideoRepoIO
import cats.effect.IO
final class DoobieMySqlVideoRepoIO(
db: DoobieDbConnection[IO]) extends VideoRepository[IO] {
override def all(): IO[Seq[Video]] =
db.read(sql"SELECT ...".query[Video].to[Seq])
override def save(video: Video): IO[Unit] =
sql"INSERT INTO ... ".update.run
.transact(db.transactor)
.map(_ => ())
}
INSTANTIATION
Infrastructure implementation/AdapterVideoRepository
DoobieVideoRepo (GENERIC) INSTANTIATION
final case class DoobieMySqlVideoRepo[P[_]: Monad]()(
db: DoobieDbConnection[P]) extends VideoRepository[P] {
override def all(): P[Seq[Video]] =
db.read(sql"SELECT …”.query[Video].to[Seq])
override def save(video: Video): P[Unit] =
sql"INSERT …”.update.run
.transact(db.transactor)
.map(_ => ())
}
Infrastructure implementation/AdapterVideoRepository
DoobieVideoRepo (GENERIC) INSTANTIATION
final case class DoobieMySqlVideoRepo[P[_]: Monad]()(
db: DoobieDbConnection[P]) extends VideoRepository[P] {
override def all(): P[Seq[Video]] =
db.read(sql"SELECT …”.query[Video].to[Seq])
override def save(video: Video): P[Unit] =
sql"INSERT …”.update.run
.transact(db.transactor)
.map(_ => ())
}
🤔 Rethinking time
🏗 Layers implementations
Differences on layers implementation
• Same goal: Decouple from infrastructure
• 🦄 FP:
• One step forward to avoid infrastructure leaks
• Again, through type classes: a better API
• More complexity: monads, applicatives, etc.
& Implementation > 🏗 Layers > 🤔 Rethinking time
👤
Domain
models
Contents
🗺Design principles
&Implementation details
🦄
Functional
Architectures
🎯
Hexagonal
Architecture
🏗
Layers
implementation
Functional Programming intro based on Hexagonal Architecture
⚡
Error
Handling
👤
Domain
models
Contents
🗺Design principles
&Implementation details
🦄
Functional
Architectures
🎯
Hexagonal
Architecture
🏗
Layers
implementation
Functional Programming intro based on Hexagonal Architecture
⚡
Error
Handling
🎯 OOP
⚡Error Handling
object VideoQuality {
val maxQuality = 50
val minQuality = 0
}
final case class VideoQuality(value: Int) {
require(value <= maxQuality, s"Video quality value greater than $maxQuality")
require(value >= minQuality, s"Video quality value less than $minQuality")
def increase(): VideoQuality = {
if (value >= maxQuality) this
else copy(value + 1)
}
}
VO: Raise exceptions
for invalid states
⚡Error Handling > 🎯 OOP > Raise exceptions
final class VideoFinder(repository: VideoRepository)
(implicit ec: ExecutionContext) {
def find(id: VideoId): Future[Video] =
repository.search(id).map { videoOption =>
if (videoOption.isEmpty) throw VideoNotFound(id)
else videoOption.get
}
}
Imperativeness
⚡Error Handling > 🎯 OOP > Raise exceptions
trait VideoRepository {
def search(id: VideoId): Future[Option[Video]]
}
final class VideoGetController extends ApiController
{
protected function exceptions(): array
{
return [
VideoNotFound::class => Response::HTTP_NOT_FOUND,
];
}
// …
}
HTTP Mapping
⚡Error Handling > 🎯 OOP > Handle exceptions
🦄 Functional Architectures
⚡Error Handling
Imperativeness
⚡Error Handling > 🦄 FP > Raise errors
Declarativeness
+
final case class VideoFinderRepo[P[_]]()(
implicit repository: VideoRepository[P]
) extends VideoFinder[P] {
def find(id: VideoId)(implicit
E: MonadError[P, VideoFinderError]): P[Video] =
repository.search(id) flatMap { maybeVideo =>
maybeVideo.fold(E.raiseError[Video](VideoNotFound(id))){
video => video.pure[P]
}
}
}
⚡Error Handling > 🦄 FP > Raise errors
final case class VideoFinderRepo[P[_]]()(
implicit repository: VideoRepository[P]
) extends VideoFinder[P] {
def find(id: VideoId)(implicit
E: MonadError[P, VideoFinderError]): P[Video] =
repository.search(id) flatMap { maybeVideo =>
maybeVideo.fold(E.raiseError[Video](VideoNotFound(id))){
video => video.pure[P]
}
}
}
A functional signature doesn’t hide anything!
⚡Error Handling > 🦄 FP > Raise errors
TYPE CLASSES
trait MonadError[F[_], E] {
def raiseError[A](e: E): F[A]
def handleErrorWith[A](fa: F[A])(f: E => F[A]): F[A]
}
⚡Error Handling > 🦄 FP > Raise errors
final case class VideoFinderRepo[P[_]: Monad]()(
implicit repository: VideoRepository[P]
) extends VideoFinder[P] {
def find(id: VideoId)(implicit
E: MonadError[P, VideoFinderError]): P[Video] =
repository.search(id) flatMap { maybeVideo =>
maybeVideo.fold(E.raiseError[Video](VideoNotFound(id))){
video => video.pure[P]
}
}
}
⚡Error Handling > 🦄 FP > Raise errors
final case class VideoFinderRepo[P[_]: Monad]()(
implicit repository: VideoRepository[P]
) extends VideoFinder[P] {
def find(id: VideoId)(implicit
E: MonadError[P, VideoFinderError]): P[Video] =
repository.search(id) flatMap { maybeVideo =>
maybeVideo.fold(E.raiseError[Video](VideoNotFound(id))){
video => video.pure[P]
}
}
}
Imperativeness
⚡Error Handling > 🦄 FP > Raise errors
final case class VideoFinderRepo[P[_]: Monad]()(
implicit repository: VideoRepository[P]
) extends VideoFinder[P] {
def find(id: VideoId)(implicit
E: MonadError[P, VideoFinderError]): P[Video] =
val maybeVideo = repository.search(id) ;
if (videoOption.isEmpty) throw VideoNotFound(id)
else videoOption.get
}
Monadic programming is
imperative programming with steroids!
object FutureBasedController{
case class VideoController(
videoFinder: VideoFinder[Future]
)(implicit ec: ExecutionContext) extends Http4sDsl[Future] {
val service = HttpService[Future] {
case GET -> Root / "videos" / id =>
videoFinder.find(VideoId(id)) flatMap {
case video =>
Ok(video.asJson)
} recoverWith {
case error: VideoNotFound =>
NotFound(error.asJson)
}
}
}
}
⚡Error Handling > 🦄 FP > Raise errors
Future-based
HTTP Mapping
LOGIC
case class VideoController[P[_]: Effect](
videoFinder: VideoFinder[P]
) extends Http4sDsl[P] {
val service = HttpService[P] {
case GET -> Root / "videos" / id =>
videoFinder.find(VideoId(id)) flatMap {
case video =>
Ok(video.asJson)
} handleErrorWith {
case error: VideoNotFound =>
NotFound(error.asJson)
}
}
}
⚡Error Handling > 🦄 FP > Raise errors
Generic
HTTP Mapping
MonadError
API
LOGIC
🤔 Rethinking time
⚡Error Handling
Differences on Error handling
• 🦄 FP:
• FP tell no lies (or, rather, doesn’t hide anything): more robust contracts using
type system
• Declarative: more abstract about how the error will be raised (exceptions,
Option, Either, etc)
& Implementation > ⚡Error Handling > 🤔 Rethinking time
🍕Takeaways
🎯
🦄
VideoPostController
VideoRepository
VideoCreator
DoobieMySqlVideoRepo
VideoPostController
VideoRepositoryVideoRepoC
DoobieMySqlVideoRepo
VideoCreator
HTTP
🍕Takeaways
⚡ Exceptions
🏗 Monolithic interfaces
👤 Rich domain models
🍕Takeaways
⚡ Exceptions
🏗 Monolithic interfaces
👤 Rich domain models
🦄 TypeClasses
⚛ APIs with steroids
🧐 FP as a subsuming paradigm
ℹ More info
References
ℹ More info
👉Formación FP presencial 👈
hablapps.com
👉Cursos en vídeo online 👈
codely.tv/pro/cursos

Weitere ähnliche Inhalte

Was ist angesagt?

Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented programmingScott Wlaschin
 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1Philip Schwarz
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Scott Wlaschin
 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2Philip Schwarz
 
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
An Introduction to JUnit 5 and how to use it with Spring boot tests and MockitoAn Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockitoshaunthomas999
 
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"용근 권
 
Collections and its types in C# (with examples)
Collections and its types in C# (with examples)Collections and its types in C# (with examples)
Collections and its types in C# (with examples)Aijaz Ali Abro
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기Yongha Yoo
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionDmitry Sheiko
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJSSandi Barr
 
Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Scott Wlaschin
 
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Michel Schudel
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Scott Wlaschin
 
Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Scott Wlaschin
 
2 years with python and serverless
2 years with python and serverless2 years with python and serverless
2 years with python and serverlessHector Canto
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Scott Wlaschin
 

Was ist angesagt? (20)

Spring Core
Spring CoreSpring Core
Spring Core
 
Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented programming
 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)
 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
 
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
An Introduction to JUnit 5 and how to use it with Spring boot tests and MockitoAn Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
 
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
 
Collections and its types in C# (with examples)
Collections and its types in C# (with examples)Collections and its types in C# (with examples)
Collections and its types in C# (with examples)
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJS
 
Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)
 
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
 
React & GraphQL
React & GraphQLReact & GraphQL
React & GraphQL
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 
Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)
 
2 years with python and serverless
2 years with python and serverless2 years with python and serverless
2 years with python and serverless
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
 
Zio in real world
Zio in real worldZio in real world
Zio in real world
 
JPA and Hibernate
JPA and HibernateJPA and Hibernate
JPA and Hibernate
 

Ähnlich wie Towards Functional Programming through Hexagonal Architecture

Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...
Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...
Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...CodelyTV
 
Integrating Infrastructure as Code into a Continuous Delivery Pipeline | AWS ...
Integrating Infrastructure as Code into a Continuous Delivery Pipeline | AWS ...Integrating Infrastructure as Code into a Continuous Delivery Pipeline | AWS ...
Integrating Infrastructure as Code into a Continuous Delivery Pipeline | AWS ...Amazon Web Services
 
Customizing the Presentation Model and Physical Renderer in Siebel Open UI
Customizing the Presentation Model and Physical Renderer in Siebel Open UICustomizing the Presentation Model and Physical Renderer in Siebel Open UI
Customizing the Presentation Model and Physical Renderer in Siebel Open UITech OneStop
 
Modular Web Applications With Netzke
Modular Web Applications With NetzkeModular Web Applications With Netzke
Modular Web Applications With Netzkenetzke
 
Advanced #6 clean architecture
Advanced #6  clean architectureAdvanced #6  clean architecture
Advanced #6 clean architectureVitali Pekelis
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftOleksandr Stepanov
 
Django Introduction & Tutorial
Django Introduction & TutorialDjango Introduction & Tutorial
Django Introduction & Tutorial之宇 趙
 
Microservices Chaos Testing at Jet
Microservices Chaos Testing at JetMicroservices Chaos Testing at Jet
Microservices Chaos Testing at JetC4Media
 
Awesome html with ujs, jQuery and coffeescript
Awesome html with ujs, jQuery and coffeescriptAwesome html with ujs, jQuery and coffeescript
Awesome html with ujs, jQuery and coffeescriptAmir Barylko
 
Application Architecture April 2014
Application Architecture April 2014Application Architecture April 2014
Application Architecture April 2014Lars-Erik Kindblad
 
Getting started with Appcelerator Titanium
Getting started with Appcelerator TitaniumGetting started with Appcelerator Titanium
Getting started with Appcelerator TitaniumTechday7
 
Getting started with titanium
Getting started with titaniumGetting started with titanium
Getting started with titaniumNaga Harish M
 
Application Lifecycle Management in a Serverless World
Application Lifecycle Management in a Serverless WorldApplication Lifecycle Management in a Serverless World
Application Lifecycle Management in a Serverless WorldAmazon Web Services
 
“ASP.NET Core. Features and architecture”
“ASP.NET Core. Features and architecture” “ASP.NET Core. Features and architecture”
“ASP.NET Core. Features and architecture” HYS Enterprise
 
Streaming Tech Sweden 2019 - Serverless Media Processing
Streaming Tech Sweden 2019 - Serverless Media ProcessingStreaming Tech Sweden 2019 - Serverless Media Processing
Streaming Tech Sweden 2019 - Serverless Media ProcessingNaveen Mareddy
 
Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFXHendrik Ebbers
 
When Smalltalk Meets the Web
When Smalltalk Meets the WebWhen Smalltalk Meets the Web
When Smalltalk Meets the WebESUG
 
DDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVCDDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVCAndy Butland
 

Ähnlich wie Towards Functional Programming through Hexagonal Architecture (20)

Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...
Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...
Acercándonos a la Programación Funcional a través de la Arquitectura Hexag...
 
Integrating Infrastructure as Code into a Continuous Delivery Pipeline | AWS ...
Integrating Infrastructure as Code into a Continuous Delivery Pipeline | AWS ...Integrating Infrastructure as Code into a Continuous Delivery Pipeline | AWS ...
Integrating Infrastructure as Code into a Continuous Delivery Pipeline | AWS ...
 
Customizing the Presentation Model and Physical Renderer in Siebel Open UI
Customizing the Presentation Model and Physical Renderer in Siebel Open UICustomizing the Presentation Model and Physical Renderer in Siebel Open UI
Customizing the Presentation Model and Physical Renderer in Siebel Open UI
 
Modular Web Applications With Netzke
Modular Web Applications With NetzkeModular Web Applications With Netzke
Modular Web Applications With Netzke
 
Advanced #6 clean architecture
Advanced #6  clean architectureAdvanced #6  clean architecture
Advanced #6 clean architecture
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in Swift
 
Django Introduction & Tutorial
Django Introduction & TutorialDjango Introduction & Tutorial
Django Introduction & Tutorial
 
Microservices Chaos Testing at Jet
Microservices Chaos Testing at JetMicroservices Chaos Testing at Jet
Microservices Chaos Testing at Jet
 
Awesome html with ujs, jQuery and coffeescript
Awesome html with ujs, jQuery and coffeescriptAwesome html with ujs, jQuery and coffeescript
Awesome html with ujs, jQuery and coffeescript
 
Application Architecture April 2014
Application Architecture April 2014Application Architecture April 2014
Application Architecture April 2014
 
Getting started with Appcelerator Titanium
Getting started with Appcelerator TitaniumGetting started with Appcelerator Titanium
Getting started with Appcelerator Titanium
 
Getting started with titanium
Getting started with titaniumGetting started with titanium
Getting started with titanium
 
AWValuePitch, 7_12
AWValuePitch, 7_12AWValuePitch, 7_12
AWValuePitch, 7_12
 
Application Lifecycle Management in a Serverless World
Application Lifecycle Management in a Serverless WorldApplication Lifecycle Management in a Serverless World
Application Lifecycle Management in a Serverless World
 
“ASP.NET Core. Features and architecture”
“ASP.NET Core. Features and architecture” “ASP.NET Core. Features and architecture”
“ASP.NET Core. Features and architecture”
 
Streaming Tech Sweden 2019 - Serverless Media Processing
Streaming Tech Sweden 2019 - Serverless Media ProcessingStreaming Tech Sweden 2019 - Serverless Media Processing
Streaming Tech Sweden 2019 - Serverless Media Processing
 
Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFX
 
When Smalltalk Meets the Web
When Smalltalk Meets the WebWhen Smalltalk Meets the Web
When Smalltalk Meets the Web
 
DDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVCDDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVC
 
Html5 intro
Html5 introHtml5 intro
Html5 intro
 

Kürzlich hochgeladen

VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Bookingdharasingh5698
 
Block diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.pptBlock diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.pptNANDHAKUMARA10
 
Unit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfUnit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfRagavanV2
 
University management System project report..pdf
University management System project report..pdfUniversity management System project report..pdf
University management System project report..pdfKamal Acharya
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performancesivaprakash250
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordAsst.prof M.Gokilavani
 
AKTU Computer Networks notes --- Unit 3.pdf
AKTU Computer Networks notes ---  Unit 3.pdfAKTU Computer Networks notes ---  Unit 3.pdf
AKTU Computer Networks notes --- Unit 3.pdfankushspencer015
 
Generative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPTGenerative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPTbhaskargani46
 
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfKamal Acharya
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfJiananWang21
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Call Girls in Nagpur High Profile
 
Call Girls Wakad Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Wakad Call Me 7737669865 Budget Friendly No Advance BookingCall Girls Wakad Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Wakad Call Me 7737669865 Budget Friendly No Advance Bookingroncy bisnoi
 
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...Call Girls in Nagpur High Profile
 
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoorTop Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoordharasingh5698
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756dollysharma2066
 

Kürzlich hochgeladen (20)

VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
 
Block diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.pptBlock diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.ppt
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
 
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
 
NFPA 5000 2024 standard .
NFPA 5000 2024 standard                                  .NFPA 5000 2024 standard                                  .
NFPA 5000 2024 standard .
 
Unit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfUnit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdf
 
University management System project report..pdf
University management System project report..pdfUniversity management System project report..pdf
University management System project report..pdf
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
 
AKTU Computer Networks notes --- Unit 3.pdf
AKTU Computer Networks notes ---  Unit 3.pdfAKTU Computer Networks notes ---  Unit 3.pdf
AKTU Computer Networks notes --- Unit 3.pdf
 
Generative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPTGenerative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPT
 
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
 
Call Girls Wakad Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Wakad Call Me 7737669865 Budget Friendly No Advance BookingCall Girls Wakad Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Wakad Call Me 7737669865 Budget Friendly No Advance Booking
 
(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7
(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7
(INDIRA) Call Girl Meerut Call Now 8617697112 Meerut Escorts 24x7
 
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
 
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoorTop Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
Top Rated Call Girls In chittoor 📱 {7001035870} VIP Escorts chittoor
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
 
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
 

Towards Functional Programming through Hexagonal Architecture