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.
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)".
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()
}
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)
}
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
}
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.
Also, instead of instanceof in the cast, we have implemented a smart cast that the compiler will handle nicely.
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
}
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
The Factory class does not describe the IDCard class that is actually generated, and the Product is generated by calling the Product and instance creation methods, so I learned that it is an advantage that there is no binding by a specific class name. That's right.
As I didn't mention much above, if Factory and Product are in the same package and IDCard and IDCardFactory are defined in different packages (for example, framework package and idcard package), there is no binding by specific class or package. I learned to express that "the framework package does not depend on the idcard package".
I learned the following points about Kotlin
protected
specification is different from Javapublic final
by defaultList
can be read only, mutableList
can be addedsmart cast
is convenient for castingIt 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