[GO] [Gang of Four] Design pattern learning --Proxy

Proxy --Proxy

** 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.

Purpose

To control access to an object, provide a surrogate or container for that object.

Component

・ Proxy shadow warrior class -Abstract class of Subject Proxy class and RealSubject class ・ RealSubject real class

Implementation

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.

Abstract class of Subject Proxy class and RealSubject class

Subject.kt


package proxy

interface Subject {
    fun draw()
}

RealSubject real class

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 class

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.

Proxy shadow warrior 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
    }
}

Output result

[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

[Gang of Four] Design pattern learning --Proxy
[Gang of Four] Design pattern learning --Singleton
[Gang of Four] Design Pattern Learning --Decorator
[Gang of Four] Design pattern learning --Visitor
[Gang of Four] Design pattern learning --Mediator
[Gang of Four] Design pattern learning --Iterator
[Gang of Four] Design pattern learning --Facade
[Gang of Four] Design pattern learning --Composite
[Gang of Four] Design pattern learning --Prototype
[Gang of Four] Design pattern learning --Memento
[Gang of Four] Design pattern learning --State
[Gang of Four] Design pattern learning --Builder
[Gang of Four] Design pattern learning --Strategy
[Gang of Four] Design pattern learning --Adapter
[Gang of Four] Design pattern learning --Observer
[Gang of Four] Design pattern learning --Command
[Gang of Four] Design pattern learning --Fly Weight
[Gang of Four] Design pattern learning --Abstract Factory
[Gang of Four] Design pattern learning --Chain of Responsibility
[Gang of Four] Design pattern learning --Template Method
Design Pattern #Proxy
Learn the design pattern "Proxy" in Python
Gang of Four (GoF) Patterns in Python
Design Pattern #Builder
Design Pattern #Adapter
Design Pattern #Decorator
Pattern recognition learning in video Part 1 Field of Pattern Recognition
Design Pattern #Facade
Design Pattern #Strategy
Learn the design pattern "Chain of Responsibility" in Python
Design Pattern #Factory Method
Deep learning 1 Practice of deep learning
Design Pattern #Template Method
Proxy pattern in Java