【経緯】
『増補改訂版Java言語で学ぶデザインパターン入門』をKotlinでやってみるの第二回目です。
今回はAdapterパターンです。前回と違い長いのでサンプルコードと練習問題コードに分けました。
【サンプルコード】
Android JavaだとTableViewやらListViewやらで良く出てくるイメージ。
Adapterは適合するという意味。Wrapperパターンとも呼ばれる。(個人的にはWrapperと言われた方が馴染み深い)
互換性のないインターフェースを持つものの間の相違を埋めるようなパターンです。Adapterパターンは二つに分類されます。
1. クラスを継承(is a 関係)を使ったAdapterパターン
PrintBannerクラスでBannerクラスを継承、Printインターフェースのメソッドをoverrideで実装。
処理を行っているのはPrintBannerクラスということになります。
全然関係ない話ですが、Javaと違ってKotlinだとキーワードが消えるので慣れないと混乱しますね・・・。
open class Banner(title:String) {
var string:String = title
fun showWithParen() {
Log.d("Banner", "(" + string + ")")
}
fun showWithAster() {
Log.d("Banner", "*" + string + "*")
}
}
interface Print {
abstract fun printWeak()
abstract fun printStrong()
}
class PrintBanner(msg:String) : Banner(msg) , Print {
override fun printWeak() {
showWithParen()
}
override fun printStrong() {
showWithAster()
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var p:Print = PrintBanner("Hello")
p.printWeak()
p.printStrong()
}
}
(Hello)
*Hello*
2. インスタンスによる委譲(has a 関係)を使ったAdapterパターン
変わっているのはPrintBanner.ktだけ。Main.kt、Banner.kt、Print.ktは上記と同じなので省略します。
PrintBannerクラスではBannrクラスの継承は行わず、インスタンスを作成してクラスのメンバとして処理を行っています。
なので処理を行っているのはBannerクラスになります。
class PrintBanner(msg:String) : Print {
var banner:Banner = Banner(msg)
override fun printWeak() {
banner.showWithParen()
}
override fun printStrong() {
banner.showWithAster()
}
}
(Hello)
*Hello*
【練習問題コード】
Android Studio環境なのでAdapterパターンの実装よりもファイル操作系に引っかかりました。。。
interface FileIO {
fun readFromFile(fileName:String)
fun writeToFile(fileName: String)
fun setValue(key:String, value:String)
fun getValue(key:String) : String
}
import java.io.*;
import java.util.*
class FileProperties : Properties(), FileIO {
override fun writeToFile(fileName: String) {
store(FileOutputStream(fileName), "written by FileProperties")
}
override fun setValue(key: String, value: String) {
setProperty(key, value)
}
override fun readFromFile(fileName: String) {
load(FileInputStream(fileName))
}
override fun getValue(key: String): String {
return getProperty(key, "")
}
}
year=1999
# written by FileProperties
# Tue Aug 21 22:13:12 GMT+09:00 2018
day=21
month=4
year=2004