[GO] I wrote a design pattern in kotlin Prototype

To learn the concept of Interface and the reusability of objects, which are important in object orientation ["Introduction to design patterns learned in Java language"](https://www.amazon.co.jp/%E5%A2%97% E8% A3% 9C% E6% 94% B9% E8% A8% 82% E7% 89% 88Java% E8% A8% 80% E8% AA% 9E% E3% 81% A7% E5% AD% A6% E3% 81% B6% E3% 83% 87% E3% 82% B6% E3% 82% A4% E3% 83% B3% E3% 83% 91% E3% 82% BF% E3% 83% BC% E3% 83% B3% E5% 85% A5% E9% 96% 80-% E7% B5% 90% E5% 9F% 8E-% E6% B5% A9 / dp / 4797327030 / ref = sr_1_1? __mk_ja_JP =% E3% 82% AB % E3% 82% BF% E3% 82% AB% E3% 83% 8A & keywords = java% E8% A8% 80% E8% AA% 9E% E3% 81% A7% E5% AD% A6% E3% 81% B6 % E3% 83% 87% E3% 82% B6% E3% 82% A4% E3% 83% B3% E3% 83% 91% E3% 82% BF% E3% 83% BC% E3% 83% B3% E5 I learned about% 85% A5% E9% 96% 80 & qid = 1559563427 & s = gateway & sr = 8-1) and decided to write in Java and then in kotlin. This time I will write about Prototype.

What is Prototype?

A pattern that is based on a class when creating an instance, but copies an existing instance and replicates it as another instance.

There are merits in the following cases.

  1. When there are too many types to put together in a class
  1. When it is difficult to instantiate from a class
  2. If you want to separate the framework and the instance to be generated

In addition, the sample code provides a pattern to create a new instance based on the prototype instance.

Product interface

An instance of a subclass that inherits the Product class in the interface that inherits Cloneable is the class to be copied.

In Kotlin it will be java.lang.NoClassDefFoundError if Cloneable is implemented in the Product interface. Apparently it can't be implemented in the interface, and it is the class that inherits Cloneable. We also confirmed that it can be implemented in the case of a subclass of an abstract class that inherits Cloneable.

Reference: Design pattern with Kotlin Prototype 06 Design Model-kotlin-Recovery Prototype

Product.java


interface Product extends Cloneable {
	public abstract void use(String s);
	public abstract Product createClone();
}

Product.kt


interface Product {
    fun use(s: String)
    fun createClone(): Product
}

For Product abstract class

Product.kt


abstract class Product(): Cloneable {
    abstract fun use(s: String)
    abstract fun createClone(): Product
}

Manager class

It is a class that duplicates an instance using createClone, and if you register it, it will be a class that can be duplicated at any time.

HashMap can be obtained by either showcase.get () or showcase []. In kotlin, val a: String = null will result in a compile error, and Null is not allowed by default. If you specify?, Null can be handled. Also, if the specified p is Null, createClone will not be executed and Null will be returned.

Reference: [Kotlin] [Java] Kotlin Java comparison memo [Null Safety] Kotlin Java Comparison Memo Correct Null Safety Usage Try "Introduction to Design Patterns Learned in Java Language" with Kotlin (Prototype)

@htsign Thank you for your review. Originally I wanted to declare a variable p of type Product outside the block of the try statement in the subclass of Product I assigned Null and specified? , But I modified it to delay initialization using lateinit and modified it so that it does not handle Null. So the createClone () of the Product interface also returns the return value from Product? To Product.

Manager.java


class Manager {
	private HashMap showcase = new HashMap();
	public void register(String name, Product proto) {
		showcase.put(name, proto);
	}
	public Product create(String protoname) {
		Product p = (Product)showcase.get(protoname);
		return p.createClone();
	}
}

Manager.kt


class Manager {
    private var showcase: MutableMap<String, Product> = mutableMapOf()
    fun register(name: String, proto: Product){
        showcase.put(name, proto)
    }
    fun create(protoname: String): Product?{
        val p = showcase[protoname] as Product
        return p?.createClone()
    }
}

Fix Manager.kt


class Manager {
    private var showcase: MutableMap<String, Product> = mutableMapOf()
    fun register(name: String, proto: Product){
        showcase.put(name, proto)
    }
    fun create(protoname: String): Product{
        val p = showcase[protoname] as Product
        return p.createClone()
    }
}

MessageBox class

This class displays a character string surrounded by a border. The Cloneable mentioned earlier needs to be implemented in a subclass of Product. Also, since the clone method can only be called from your own class (and subclass), if you want to duplicate at the request of another class (Manager), call clone with another method such as createClone (). It is necessary.

MessageBox.java


class MessageBox implements Product {
	private char decochar;
	public MessageBox(char decochar) {
		this.decochar = decochar;
	}
	public void use(String s) {
		int length = s.getBytes().length;
		for (int i = 0; i < length + 4; i++) {
			System.out.print(decochar);
		}
		System.out.println("");
		System.out.println(String.format("%s %s %s", decochar, s, decochar));
		for (int i = 0; i < length + 4; i++) {
			System.out.print(decochar);
		}
		System.out.println("");
	}
	public Product createClone(){
		Product p = null;
		try {
			p = (Product)clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return p;
	}
}

MessageBox.kt


class MessageBox(private val d: Char): Product, Cloneable{
    override fun use(s: String){
        val length = s.toByteArray().size
        for (i: Int in 1..length + 4) print(d)
        println("")
        println("%s %s %s".format(d, s, d))
        for (i: Int in 1..length + 4) print(d)
        println("")
    }
    override fun createClone(): Product?{
        var p: Product? = null
        try {
            p = clone() as Product
        }catch (e:CloneNotSupportedException){
            e.printStackTrace()
        }
        return p
    }
}

Modified MessageBox.kt


class MessageBox(private val d: Char): Product, Cloneable{
    override fun use(s: String){
        val length = s.toByteArray().size
        for (i: Int in 1..length + 4) print(d)
        println("")
        println("%s %s %s".format(d, s, d))
        for (i: Int in 1..length + 4) print(d)
        println("")
    }
    override fun createClone(): Product{
        lateinit var p: Product
        try {
            p = clone() as Product
        }catch (e:CloneNotSupportedException){
            e.printStackTrace()
        }
        return p
    }
}

UnderlinePen class

This class is displayed by underlining the character string.

UnderlinePen.java


class UnderlinePen implements Product {
	private char ulchar;
	public UnderlinePen(char ulchar) {
		this.ulchar = ulchar;
	}
	public void use(String s) {
		int length = s.getBytes().length;
		System.out.println(String.format("\"%s\"", s));
		System.out.print(" ");
		for (int i = 0; i < length; i++) {
			System.out.print(ulchar);
		}
		System.out.println("");
	}
	public Product createClone() {
		Product p = null;
		try {
			p = (Product)clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return p;
	}
}

UnderlinePen.kt


class UnderLinePen(ulchar: Char): Product, Cloneable{
    private val u = ulchar
    override fun use(s: String) {
        val length = s.toByteArray().size
        println("\"%s\"".format(s))
        print(" ")
        for (i: Int in 1..length) print(u)
        println("")
    }

    override fun createClone(): Product? {
        var p: Product? = null
        try {
            p = clone() as Product
        }catch (e: CloneNotSupportedException){
            e.printStackTrace()
        }
        return p
    }
}

Fixed Underline Pen.kt


class UnderLinePen(ulchar: Char): Product, Cloneable{
    private val u = ulchar
    override fun use(s: String) {
        val length = s.toByteArray().size
        println("\"%s\"".format(s))
        print(" ")
        for (i: Int in 1..length) print(u)
        println("")
    }

    override fun createClone(): Product {
        lateinit var p: Product
        try {
            p = clone() as Product
        }catch (e: CloneNotSupportedException){
            e.printStackTrace()
        }
        return p
    }
}

Main class

PrototypeSample.java


public class PrototypeSample {
	public static void main(String[] args) {
		Manager manager = new Manager();
		UnderlinePen upen = new UnderlinePen('~');
		MessageBox mbox = new MessageBox('*');
		MessageBox sbox = new MessageBox('/');
		manager.register("strong message", upen);
		manager.register("warning box", mbox);
		manager.register("slash box", sbox);
		
		Product p1 = manager.create("strong message");
		Product p2 = manager.create("warning box");
		Product p3 = manager.create("slash box");
		p1.use("Hello, World.");
		p2.use("Hello, World.");
		p3.use("Hello, World.");
	}
}

PrototypeSample.kt


fun main(args: Array<String>) {
    val manager = Manager()
    val upen = UnderLinePen('~')
    val mbox = MessageBox('*')
    val sbox = MessageBox('/')
    manager.register("strong message", upen)
    manager.register("warning box", mbox)
    manager.register("slash box", sbox)

    val p1 = manager.create("strong message")
    val p2 = manager.create("warning box")
    val p3 = manager.create("slash box")
    p1?.use("Hellow, World.")
    p2?.use("Hellow, World.")
    p3?.use("Hellow, World.")
}

Modified Prototype Sample.kt


fun main(args: Array<String>) {
    val manager = Manager()
    val upen = UnderLinePen('~')
    val mbox = MessageBox('*')
    val sbox = MessageBox('/')
    manager.register("strong message", upen)
    manager.register("warning box", mbox)
    manager.register("slash box", sbox)

    val p1 = manager.create("strong message")
    val p2 = manager.create("warning box")
    val p3 = manager.create("slash box")
    p1.use("Hellow, World.")
    p2.use("Hellow, World.")
    p3.use("Hellow, World.")
}

Execution result


   "Hello, World."
    ~~~~~~~~~~~~~
   *****************
   * Hello, World. *
   *****************
   /////////////////
   / Hello, World. /
   /////////////////

Class diagram

image.png

Impressions

I also investigated why + clone is necessary in the first place (Reference: About Java clone () method) Inherited I learned that the clone method was designed to copy the instance as it is because it behaves unintentionally when creating an instance in a subclass or the like.

reference

It was very easy to read and understand by referring to the following.

How to write Java String # getBytes in Kotlin? Design pattern with Kotlin Prototype 06 Design Model-kotlin-Recovery Prototype [Kotlin] [Java] Kotlin Java comparison memo [Null Safety] Kotlin Java Comparison Memo Correct Null Safety Usage Try "Introduction to Design Patterns Learned in Java Language" with Kotlin (Prototype)

Also, the following blog explained in detail about clone (), which was a great learning experience. About the Java clone () method

Recommended Posts

I wrote a design pattern in kotlin Prototype
I wrote a design pattern in kotlin Factory edition
I wrote a design pattern in kotlin Builder edition
I wrote a design pattern in kotlin Singleton edition
I wrote a design pattern in kotlin Adapter edition
I wrote a design pattern in kotlin, Iterator edition
I wrote a design pattern in kotlin Template edition
Learn the design pattern "Prototype" in Python
A memo that I wrote a quicksort in Python
I wrote a class in Python3 and Java
I wrote a Japanese parser in Japanese using pyparsing.
Prototype pattern in Java
I wrote python in Japanese
I wrote a script to get a popular site in Japan
I wrote a script that splits the image in two
I get a UnicodeDecodeError in mecab-python3
I get a KeyError in pyclustering.xmeans
I wrote Gray Scale in Pytorch
I wrote the queue in Python
I wrote the stack in Python
I studied about design patterns (personal memo) Part 3 (Prototype pattern, Builder pattern)
I wrote a function to load a Git extension script in Python
I wrote a script to extract a web page link in Python
I wrote a code to convert quaternions to z-y-x Euler angles in Python
I want to print in a comprehension
Learn the design pattern "Flyweight" in Python
Learn the design pattern "Memento" in Python
Learn the design pattern "Proxy" in Python
Learn the design pattern "Command" in Python
Learn the design pattern "Visitor" in Python
Learn the design pattern "Mediator" in Python
Learn the design pattern "Decorator" in Python
[Gang of Four] Design pattern learning --Prototype
I wrote the selection sort in C
Learn the design pattern "Iterator" in Python
[Python] I forcibly wrote a short Perlin noise generation function in Numpy.
Learn the design pattern "Strategy" in Python
Learn the design pattern "Composite" in Python
Learn the design pattern "State" in Python
I wrote Project Euler 1 in one liner.
Learn the design pattern "Adapter" in Python
I started Node.js in a virtual environment
I created a password tool in Python.
I wrote FizzBuzz in python using a support vector machine (library LIVSVM).
I wrote the sliding wing in creation.
I wrote a graph like R glmnet in Python for sparse modeling in Lasso
[Fundamental Information Technology Engineer Examination] I wrote a linear search algorithm in Python.
I wrote a PyPI module that extends the parameter style in Python's sqlite3 module
Learn the design pattern "Abstract Factory" in Python
Delete data in a pattern with Redis Cluster
Learn the design pattern "Template Method" in Python
I tried playing a typing game in Python
Learn the design pattern "Factory Method" in Python
I wrote "Introduction to Effect Verification" in Python
[Memo] I tried a pivot table in Python
I wrote a script to upload a WordPress plugin
I wrote the hexagonal architecture in go language
I tried adding a Python3 module in C
[PyTorch] I was a little lost in torch.max ()
Create a loop antenna pattern in Python in KiCad
I made a Caesar cryptographic program in Python.