[GO] I wrote a design pattern in kotlin Factory edition

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

What is Factory

Template pattern is designed so that the superclass defines the processing framework (similar shared processing) and the subclass defines the specific content. While it was a pattern, it is a design pattern that defines the framework for instantiation. The following will implement the framework of instance creation and the subclass that actually "creates an ID card (instance)".

Product class

This class is an abstract class that defines "product", and the use method is defined on the premise that the product is "used". Also, abstraction can force it to be "used" as a product role. (I felt the intention.)

In kotlin, even if you do not specify Unit as void, the type of the function that does not specify the return value will be Unit. It was also pointed out that it is redundant in the IDE.

Reference: Knowing Kotlin type ~ Part 1 ~

Product.java


abstract class Product {
	public abstract void use();
}

Product.kt


abstract class Product {
    abstract fun use()
}

Factory class

Here, we will implement the framework for instantiation. The point is that "creating a product" and "registering with a product" are left to the implementation of the subclass, but the procedure in the create method can read the intention that "the definition is decided" as final in the Factory class. I will.

The difference between Kotlin and java protected is that Java can be accessed from a subclass or a class in the same package, while Kotlin can be accessed only from a subclass. Here we use kotlin protected, which can only be accessed by subclasses.

Reference: Relationship between kotlin and java access modifiers

Also, in Java, it is a public final create method, but kotlin is default and is a public final method, so it is not specified.

Factory.java


abstract class Factory {
	public final Product create(String owner) {
		Product p = createProduct(owner);
		registerProduct(p);
		return p;
	}
	protected abstract Product createProduct(String owner);
	protected abstract void registerProduct(Product product);
}

Factory.kt


abstract class Factory {
    fun create(owner: String): Product {
        val p = createProduct(owner)
        registerProduct(p)
        return  p
    }
    protected abstract fun createProduct(owner: String): Product
    protected abstract fun registerProduct(product: Product)
}

IDCard class

We will define a subclass as an actual product that inherits the Product class.

Define ʻinit` when initializing the constructor with kotlin.

Reference: [Kotlin] How to write a constructor

IDCard.java


class IDCard extends Product {
	private String owner;
	public IDCard(String owner) {
		System.out.println(owner + "Make a card.");
		this.owner = owner;
	}
	public void use() {
		System.out.println(owner + "Use the card.");
	}
	public String getOwner() {
		return owner;
	}
}

IDCard.kt


class IDCard (private val owner: String): Product() {
    init { println(owner + "Make a card.") }
    override fun use() = println(owner + "Use the card.")
    fun getOwner() = owner
}

IDCardFactory class

Inherit the Factory class, which is the framework for instantiation, and implement specific processing. The createProduct method that creates an instance and actually creates the product, and the registerProduct method that realizes registration in the owners field are implemented.

In Kotlin, List seems to be read only and uses mutableList that can be added.

Reference: Kotlin and List

Also, Kotlin does not use new when instantiating.

Reference: Kotlin Grammar-Classes, Inheritance, Properties

Also, instead of instanceof in the cast, we have implemented a smart cast that the compiler will handle nicely.

Reference: where Java programmers tend to trip over Kotlin

IDCardFactory.java


class IDCardFactory extends Factory {
	private List<String> owners = new ArrayList<String>();

	@Override
	protected Product createProduct(String owner) {
		return new IDCard(owner);
	}

	@Override
	protected void registerProduct(Product product) {
		owners.add(((IDCard)product).getOwner());
	}
	
	public List<String> getOwners() {
		return owners;
	}
}

IDCardFactory.kt


class IDCardFactory: Factory() {
    private var owners: MutableList<String> = mutableListOf()
    override fun createProduct(owner: String) = IDCard(owner)
    override fun registerProduct(product: Product) {
        if(product is IDCard) owners.add(product.getOwner()) //smart cast
    }
    fun getOwners() = owners
}

Main class

I will create an ID card.

FactorySample.java


public class FactorySample {
	public static void main(String[] args) {
		Factory factory = new IDCardFactory();
		Product card1 = factory.create("Sato");
		Product card2 = factory.create("Suzuki");
		Product card3 = factory.create("Tanaka");
		card1.use();
		card2.use();
		card3.use();
		((IDCardFactory)factory).getOwners().stream().forEach(System.out::println);
	}
}

FactorySample.kt


fun main(args: Array<String>){
    val factory = IDCardFactory()
    val card1 = factory.create("Sato")
    val card2 = factory.create("Suzuki")
    val card3 = factory.create("Tanaka")
    card1.use()
    card2.use()
    card3.use()
    factory.getOwners().forEach(System.out::println)
}

Execution result


Make Sato's card.
I will make a Suzuki card.
Make Tanaka's card.
I will use Sato's card.
I will use Suzuki's card.
I will use Tanaka's card.
Sato
Suzuki
Tanaka

Class diagram

image.png

Impressions

  1. If you do not specify a return value, void ʻUnit` is specified by default, so you do not need to define it.
  2. The protected specification is different from Java
  3. Method definition is public final by default
  4. Use ʻinit` to initialize the constructor
  5. List can be read only, mutableList can be added
  6. Do not use new when instantiating
  7. smart cast is convenient for casting

reference

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

Knowing Kotlin type ~ Part 1 ~ Relationship between kotlin and java access modifiers [Kotlin] How to write a constructor Kotlin and List Kotlin Grammar-Classes, Inheritance, Properties Where Java programmers tend to trip over Kotlin

Recommended Posts

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
I wrote a design pattern in kotlin Prototype
A memo that I wrote a quicksort in Python
Learn the design pattern "Abstract Factory" in Python
I wrote a class in Python3 and Java
Learn the design pattern "Factory Method" in Python
I wrote a Japanese parser in Japanese using pyparsing.
Design Pattern #Factory Method
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 a function to load a Git extension script in Python
I wrote Fizz Buzz in Python
I wrote Gray Scale in Pytorch
I wrote a script to extract a web page link in Python
I wrote the queue in Python
I participated in AtCoder (ABC169 edition)
I wrote the stack in Python
I wrote a code to convert quaternions to z-y-x Euler angles in Python
[Python] I forcibly wrote a short Perlin noise generation function in Numpy.
I wrote FizzBuzz in python using a support vector machine (library LIVSVM).
Learn the design pattern "Builder" in Python
I want to print in a comprehension
Learn the design pattern "Flyweight" in Python
I made a payroll program in Python!
Learn the design pattern "Observer" 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 "Bridge" in Python
Learn the design pattern "Mediator" in Python
Learn the design pattern "Decorator" in Python
I wrote the selection sort in C
Learn the design pattern "Iterator" in Python
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 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
[Gang of Four] Design pattern learning --Abstract Factory
When I get a chromedriver error in Selenium
Delete data in a pattern with Redis Cluster
Learn the design pattern "Template Method" in Python
I want to create a window in Python
I tried playing a typing game in Python
[Gang of Four] Design pattern learning --Factory Method
I wrote "Introduction to Effect Verification" in Python