I am experimenting with a basic proxy pattern in Swift playgrounds; I am not 100% familiar with it; but some videos are helping.
In my experiment, the subject, C
is called through a proxy to perform said actions
ie:
A - Proxy - C
However, in my experiments I find out I can just call C
itself directly, without even needing the proxy; so I am left wondering why bother with a proxy when I can call C
directly anyway?
So I decided to make the variables in C
private; but now I can't call them, or make modifications, and I am not sure how to resolve it.
I also tried a "decorator" pattern I found on stackoverflow to try to manipulate C
s variables, but still its marked private, so its not possible.
Also, the decorator pattern I found uses static
variables. This makes me think well, why not just write a static function that creates c
in memory, and then update the reference in proxy
to that of the results of the static function.
I guess what I'm mis-understanding here is what is the point of a proxy class if you can just call the subject (in this case C
) directly anyway?
Examples use Swift playground:
class A {
let proxy: Proxy = Proxy()
var funds: Int {
return self.proxy.funds
}
}
class Proxy {
private let c: C = C()
public var funds: Int {
return c.funds
}
private func canIGetFunds() -> Bool {
guard (self.funds > 0) else {
return false
}
return true
}
func subtractFunds(funds: Int = 0) {
if (canIGetFunds()) {
print ("you have enough funds")
willDebit(funds: funds)
}
else {
print ("Not enough funds")
}
}
private func willDebit(funds: Int = 0) {
self.c.funds -= funds
}
}
class C {
private (set) var funds: Int = 100
}
let a = A()
print (a.funds)
a.proxy.subtractFunds(funds: 50)
This code will throw up a compiler error on:
self.c.funds -= funds
because:
funds setter is inaccessible
the funds variable is indeed private
.
So, I tried a decorator too; code I found from stackoverflow (its not mine):
@propertyWrapper
struct Announced<T, U> {
private var announcedFunction: (T) -> U
var wrappedValue: (T) -> U { announcedFunction }
init(wrappedValue: @escaping (T) -> U) {
announcedFunction = { args in
let rv = wrappedValue(args)
print("In: \(args)")
print("Out: \(rv)")
return rv
}
}
}
extension Wallet {
@Announced static var add: ((Int, Int)) -> Int = { $0.0 + $0.1 }
@Announced static var subtract: ((Int, Int)) -> Int = { $0.0 - $0.1 }
}
Now here the add and subtract are static variables; and the contents of the closure are of course wrong because I make no reference to the actual Wallet variables -- I've only put it like this to help with discussion.
The way I got around it is to try to make the (Int, Int) take in a Wallet class, and then return a modified Wallet object where the add or subtract has been completed
So something like this:
@Announced static var subtract: ((w:Wallet, Int)) -> Wallet = {
let newWallet = Wallet()
newWallet.cash = w.cash
newWallet.cash -= $0.1
return newWallet
}
But if I do this pattern, I don't see why I don't just write a static function and disregard this decorator.
I've even tried making C
follow a delegate
pattern where the Wallet is a delegate of C and adds, subtracts funds; but this too has an issue in that you can call C
directly and because is its own delegate it has no reason to fail or throw up an error, etc.
So anyway, probably I'm just overcomplicating:
Whats the point of having a proxy if you can just call the subject directly and do your manipulation that way?
Is there a way to make the proxy pattern the only way you can call and make actions on the subject?
With thanks?
Aucun commentaire:
Enregistrer un commentaire