Skip to content

Commit 6bd21e3

Browse files
committed
Added Proxy examples in README
1 parent 3b4dedd commit 6bd21e3

2 files changed

Lines changed: 132 additions & 3 deletions

File tree

README.md

Lines changed: 131 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Kotlin OOP and FP Design Patterns
3232
* [x] [Decorator](#decorator)
3333
* [x] [Facade](#facade)
3434
* [ ] [Flyweight](#flyweight)
35-
* [ ] [Proxy](#proxy)
35+
* [x] [Proxy](#proxy)
3636
* FP
3737
* [Monads](#monads)
3838
* [x] [Option/Maybe](#option)
@@ -550,13 +550,141 @@ Flyweight
550550
551551
**In progress**
552552

553-
Proxy
553+
[Proxy](/src/main/kotlin/oop/Proxy)
554554
------
555555

556556
> It provides a placeholder for another object to control access to it.
557557
> It is an extra level of indirection to support controlled or intelligent access.
558558
559-
**In progress**
559+
There are 3 types of Proxies
560+
561+
* [Protection Proxy](#protection-proxy) - Which control the access to an object.
562+
* [Virtual Proxy](#virtual-proxy) - Which prevents creating an object until it is really necessary to save resources.
563+
* [Remote Proxy](#remote-proxy) - Which duty is to create a correct request to ask a remote real object which may not be in our domain.
564+
565+
**Protection proxy**
566+
567+
### Example
568+
569+
```kotlin
570+
class Transaction(val amount: Double,
571+
val isInternational: Boolean)
572+
573+
interface Payment {
574+
fun pay(transaction: Transaction)
575+
}
576+
577+
class PaymentProtectionProxy(private val payment: Payment): Payment {
578+
override fun pay(transaction: Transaction) {
579+
if (transaction.isInternational) println("Payment is international, we do not allow it")
580+
else payment.pay(transaction)
581+
}
582+
}
583+
584+
class RealPayment(val initialAmount: Double): Payment {
585+
override fun pay(transaction: Transaction) {
586+
initialAmount -= transaction.amount
587+
println("Successful!")
588+
}
589+
}
590+
```
591+
592+
### Usage
593+
594+
```kotlin
595+
val account = RealPayment(100.0)
596+
val localBank = PaymentProtectionProxy(account)
597+
598+
localBank.pay(Transaction(3.15, true)) // It won't allow us to pay
599+
localBank.pay(Transaction(3.15, false)) // It will work
600+
```
601+
602+
**Virtual Proxy**
603+
604+
We can use kotlin's [lazy delegation](https://kotlinlang.org/docs/reference/delegated-properties.html#lazy)
605+
606+
### Example
607+
608+
```kotlin
609+
interface Screen {
610+
fun show()
611+
}
612+
613+
class VirtualScreen(val screenCreation: () -> Screen) : Screen {
614+
private val realScreen: Screen by lazy {
615+
screenCreation()
616+
}
617+
618+
override fun show() {
619+
realScreen.show()
620+
}
621+
}
622+
623+
class RealScreen : Screen {
624+
constructor() {
625+
// It gets really hungry in here
626+
}
627+
628+
override fun show() {
629+
println("¯\_(ツ)_/¯")
630+
}
631+
}
632+
```
633+
634+
### Usage
635+
636+
```kotlin
637+
val virtualScreen = VirtualScreen({ RealScreen() }) // We haven't created a RealScreen yet
638+
639+
// Several lines after...
640+
641+
virtualScreen.show() // RealScreen is needed now, so we create it
642+
643+
```
644+
645+
**Remote Proxy**
646+
647+
### Example
648+
649+
```kotlin
650+
// Client code
651+
652+
interface Message {
653+
fun writeInChannel(text: String, channel: String)
654+
}
655+
656+
class MessageProxy(private val outpuStream: OutputStream) : Message {
657+
override fun writeInChannel(text: String, channel: String) {
658+
outpuStream.write("Headers:$text:$channel:Goodbye")
659+
}
660+
}
661+
662+
// Server code
663+
664+
class ServerMessage(val channels: List<Channel>) : Message {
665+
override fun writeInChannel(text: String, channel: String) {
666+
channels.forEach {
667+
if (it == channel) {
668+
println("$text")
669+
}
670+
}
671+
}
672+
}
673+
674+
class Server {
675+
val channels = listOf("1", "2", "3")
676+
val messageHandler = ServerMessage(channels)
677+
678+
fun onClientMessage(request: String) {
679+
val (message, channel) = request
680+
.removePrefix("Headers:")
681+
.removeSuffix(":Goodbye")
682+
.split(":")
683+
684+
messageHandler.writeInChannel(message, channel)
685+
}
686+
}
687+
```
560688

561689
## Functional paradigm
562690

src/test/kotlin/oop/Proxy/MessageRemoteProxyTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class MessageRemoteProxyTest {
2121
assertThat(networkSimulationMessageServerObject.channel, `is`("myChannel"))
2222
}
2323

24+
2425
class MessageServerObjectMock(var message: String = "",
2526
var channel: String = "") : Message {
2627

0 commit comments

Comments
 (0)