** Table of Contents ** One of the motives is to apply this pattern when you want to instantiate an object for the first time when you use an object that is costly to generate and initialize (when displaying it on the screen in a GUI application).
It is necessary to display 1000 images in a certain screen, but only 10 images can be displayed in the effective drawing area. Despite this, if you instantiate 1000 Graphics class objects at the time of initial display and load 1000 images, you will have to devote a lot of resources to processing that is not so related to the initial display.
It seems that this pattern is used to solve such problems. A Proxy is assigned to the area where the Graphics object is originally assigned, and the image is loaded only when it is time to display it.
To control access to an object, provide a surrogate or container for that object.
・ Proxy shadow warrior class -Abstract class of Subject Proxy class and RealSubject class ・ RealSubject real class
Now, implement the image drawing program as sample code. Since it is troublesome to actually instantiate 1000 pieces, the number of drawings at the time of initial display is set to 3.
Subject.kt
package proxy
interface Subject {
fun draw()
}
Image class A class that reads an instantiated instant image
Image.kt
class Image(private val filePath: String): Subject {
init {
loadImage(filePath)
}
override fun draw() {
println("${filePath}Draw")
}
private fun loadImage(filePath: String) {
println("${filePath}Read")
}
}
Now, let's use this Image class to initially display the screen.
Client.kt
package proxy
class Client {
private val initDrawNum = 3
init {
val imageList = getNonProxyImageList()
for (i in 0 until initDrawNum) {
imageList[i].draw()
}
}
private fun getNonProxyImageList(): ArrayList<Subject> {
val imageList = ArrayList<Subject>()
imageList.add(Image("./image/Apple.png "))
imageList.add(Image("./image/Mandarin orange.png "))
imageList.add(Image("./image/Peaches.png "))
imageList.add(Image("./image/Banana.png "))
imageList.add(Image("./image/Pineapple.png "))
imageList.add(Image("./image/Strawberry.png "))
return imageList
}
}
[out-put]
./image/Apple.Read png
./image/Mandarin orange.Read png
./image/Peaches.Read png
./image/Banana.Read png
./image/Pineapple.Read png
./image/Strawberry.Read png
./image/Apple.Draw png
./image/Mandarin orange.Draw png
./image/Peaches.Draw png
All the images have been loaded, although it is enough to display only three. Let's use the Proxy class.
Image Proxy class Once loaded, it is kept permanently, but it is better to implement a method to release the loaded image when it goes out of the effective drawing area.
However, it is annoying, so I will omit it this time.
ImageProxy.kt
package proxy
class ImageProxy(private val filePath: String): Subject {
var image: Image? = null
override fun draw() {
image?.let { unwrapImage ->
unwrapImage.draw()
} ?: run {
val tmpImage = Image(filePath)
tmpImage.draw()
image = tmpImage
}
}
}
Client class again. This time we will use the Proxy class.
Client.kt
package proxy
class Client {
private val initDrawNum = 3
init {
val imageList = getProxyImageList()
for (i in 0 until initDrawNum) {
imageList[i].draw()
}
}
private fun getProxyImageList(): ArrayList<Subject> {
val proxyImageList = ArrayList<Subject>()
proxyImageList.add(ImageProxy("./image/Apple.png "))
proxyImageList.add(ImageProxy("./image/Mandarin orange.png "))
proxyImageList.add(ImageProxy("./image/Peaches.png "))
proxyImageList.add(ImageProxy("./image/Banana.png "))
proxyImageList.add(ImageProxy("./image/Pineapple.png "))
proxyImageList.add(ImageProxy("./image/Strawberry.png "))
return proxyImageList
}
private fun getNonProxyImageList(): ArrayList<Subject> {
val imageList = ArrayList<Subject>()
imageList.add(Image("./image/Apple.png "))
imageList.add(Image("./image/Mandarin orange.png "))
imageList.add(Image("./image/Peaches.png "))
imageList.add(Image("./image/Banana.png "))
imageList.add(Image("./image/Pineapple.png "))
imageList.add(Image("./image/Strawberry.png "))
return imageList
}
}
[out-put]
./image/Apple.Read png
./image/Apple.Draw png
./image/Mandarin orange.Read png
./image/Mandarin orange.Draw png
./image/Peaches.Read png
./image/Peaches.Draw png
Now you can load as much as you want to display.
Recommended Posts