admin 管理员组

文章数量: 1184232

实用精短

分享:
kotlin学习练习网站-
kotlin资料网站-
设计模式网站-.html
引言:
设计模式的本质是让我们更好的运用面向对象有点,应对项目的后期的需求变更和变化
那么在学习和使用kotlin中结合以往的设计模式会怎么样呢?
以下不是抛开实际需求而是实战中运用到设计模式

主页目录:
策略模式
单例模式
工厂模式
代理模式
观察者模式
建造者模式
适配器模式
责任链模式
命令解释器模式
装饰模式
外观模式
状态模式
过滤器模式
访问者模式

策略模式Strategy功能:为不同的字符串处理提供不同的算法import java.text.DecimalFormat
import java.util.regex.Patterninterface ValueTransform {@Throws(NumberFormatException::class)fun transform(str:String?):String?
}inline fun String.vt(t:ValueTransform): String?{return t.transform(this)
}class NumberFromat(val len:Int):ValueTransform{override fun transform(str: String?): String? {return String.format("%0${len}d",Integer.valueOf(str))}
}
class TimerNumberFromat(val len:Int):ValueTransform{override fun transform(str: String?): String? {var sb=StringBuffer();val pattern = Patternpile("[\\d]++|[\\D]++")val matcher = pattern.matcher(str)fun isNumber(str: String):Boolean=Patternpile("[0-9]*").matcher(str).matches()while (matcher.find()) {var value=matcher.group()when(isNumber(value)){true -> sb.append(value.vt(NumberFromat(2)))else -> sb.append(value)}}return sb.toString()}
}
class GoldFormat(val len:Int):ValueTransform{override fun transform(str: String?): String? {var sb=StringBuffer(".")if(len<=0){return str?.toDouble()?.toInt().toString()}for(i in 0..len-1) {sb.append("0")}return DecimalFormat(sb.toString()).format(str?.toDouble())}}
fun main(args: Array<String>) {println("9->"+("9".vt(NumberFromat(2))))println("9->"+("9".vt(GoldFormat(2))))println("1989-9-1 1:4:15->"+("1989-9-1 1:4:15".vt(TimerNumberFromat(2))));
}
单例模式Singletonobject PrinterDriver {init {println("Initializing with object: $this")}fun print() = println("Printing with object: $this")
}fun main(args: Array<String>) {println("Start")PrinterDriver.print()PrinterDriver.print()
}
工厂模式Factory功能:减少项目变化所造成的影响/**抽象工厂*/
interface Plantclass OrangePlant : Plantclass ApplePlant : Plantabstract class PlantFactory {abstract fun makePlant(): Plantcompanion object {inline fun <reified T : Plant> createFactory(): PlantFactory = when (T::class) {OrangePlant::class -> OrangeFactory()ApplePlant::class  -> AppleFactory()else               -> throw IllegalArgumentException() as Throwable}}
}class AppleFactory : PlantFactory() {override fun makePlant(): Plant = ApplePlant()
}class OrangeFactory : PlantFactory() {override fun makePlant(): Plant = OrangePlant()
}fun main(args: Array<String>) {val plantFactory = PlantFactory.createFactory<OrangePlant>()val plant = plantFactory.makePlant()println("Created plant: $plant")
}
代理模式ProtectionProxy功能:通过代理禁止访问文件的密码interface File {fun read(name: String)
}class NormalFile : File {override fun read(name: String) = println("Reading file: $name")
}//Proxy:
class SecuredFile : File {val normalFile = NormalFile()var password: String = ""override fun read(name: String) {if (password == "secret") {println("Password is correct: $password")normalFile.read(name)} else {println("Incorrect password. Access denied!")}}
}fun main(args: Array<String>) {val securedFile = SecuredFile()securedFile.read("readme.md")securedFile.password = "secret"securedFile.read("readme.md")
}
观察者模式Observer功能:文本框内容变化时通知其他监听器发生变化import kotlin.properties.Delegatesinterface TextChangedListener {fun onTextChanged(newText: String)
}class PrintingTextChangedListener : TextChangedListener {override fun onTextChanged(newText: String) = println("Text is changed to: $newText")
}class TextView {var listener: TextChangedListener? = nullvar text: String by Delegates.observable("") { prop, old, new ->listener?.onTextChanged(new)}
}fun main(args: Array<String>) {val textView = TextView()textView.listener = PrintingTextChangedListener()textView.text = "Lorem ipsum"textView.text = "dolor sit amet"
}
建造者模式Build功能:创建一个可自定义各种样式的对话框import java.io.File// Let's assume that Dialog class is provided by external library.
// We have only access to Dialog public interface which cannot be changed.
/**建造*/
class Dialog() {fun showTitle() = println("showing title")fun setTitle(text: String) = println("setting title text $text")fun setTitleColor(color: String) = println("setting title color $color")fun showMessage() = println("showing message")fun setMessage(text: String) = println("setting message $text")fun setMessageColor(color: String) = println("setting message color $color")fun showImage(bitmapBytes: ByteArray) = println("showing image with size ${bitmapBytes.size}")fun show() = println("showing dialog $this")
}//Builder:
class DialogBuilder() {constructor(init: DialogBuilder.() -> Unit) : this() {init()}private var titleHolder: TextView? = nullprivate var messageHolder: TextView? = nullprivate var imageHolder: File? = nullfun title(init: TextView.() -> Unit) {titleHolder = TextView().apply { init() }}fun message(init: TextView.() -> Unit) {messageHolder = TextView().apply { init() }}fun image(init: () -> File) {imageHolder = init()}fun build(): Dialog {val dialog = Dialog()titleHolder?.apply {dialog.setTitle(text)dialog.setTitleColor(color)dialog.showTitle()}messageHolder?.apply {dialog.setMessage(text)dialog.setMessageColor(color)dialog.showMessage()}imageHolder?.apply {dialog.showImage(readBytes())}return dialog}class TextView {var text: String = ""var color: String = "#00000"}
}//Function that creates dialog builder and builds Dialog
fun dialog(init: DialogBuilder.() -> Unit): Dialog {return DialogBuilder(init).build()
}fun main(args: Array<String>) {val dialog: Dialog = dialog {title {text = "Dialog Title"}message {text = "Dialog Message"color = "#333333"}image {File.createTempFile("image", "jpg")}}dialog.show()
}
适配器模式Adapter/**适配器模式器模式-将开氏温度和摄氏温度换算*/
interface Temperature {var temperature: Double
}class CelsiusTemperature(override var temperature: Double) : Temperatureclass FahrenheitTemperature(var celsiusTemperature: CelsiusTemperature) : Temperature {override var temperature: Doubleget() = convertCelsiusToFahrenheit(celsiusTemperature.temperature)set(temperatureInF) {celsiusTemperature.temperature = convertFahrenheitToCelsius(temperatureInF)}private fun convertFahrenheitToCelsius(f: Double): Double = (f - 32) * 5 / 9private fun convertCelsiusToFahrenheit(c: Double): Double = (c * 9 / 5) + 32
}fun main(args: Array<String>) {val celsiusTemperature = CelsiusTemperature(0.0)val fahrenheitTemperature = FahrenheitTemperature(celsiusTemperature)celsiusTemperature.temperature = 36.6println("${celsiusTemperature.temperature} C -> ${fahrenheitTemperature.temperature} F")fahrenheitTemperature.temperature = 100.0println("${fahrenheitTemperature.temperature} F -> ${celsiusTemperature.temperature} C")
}
责任链模式ChainOfResponsibility功能:根据url来定义(跳转 打开或者自定义)功能 类似击鼓传花
enum class SchemeAction(var host: String, var action: (Map<String, String>) -> Unit) {OrderUI("scheme://order", {println("start order acitvity - parm=${it["id"]}")}),Evaluate("scheme://evaluate", {println("start evaluate acitvity ${it["id"]}")}),web("", {println("start web")});fun isMatching(url: String): SchemeAction? = when (true) {url.indexOf(host) == 0 -> thiselse -> null;}companion object {fun matching(url: String) {SchemeAction.values().forEach {var scheme = it.isMatching(url)scheme?.action?.invoke(paramToMap(url))scheme?.run { return }}}fun paramToMap(url: String): Map<String, String> = HashMap<String, String>().apply {var arr=url.split("\\?".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()if(arr.size==2){arr[1].split("&".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray().forEach {var parm=it.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()if(parm.size==2)this[parm[0]]=parm[1]}}}}}
fun main(args: Array<String>) {SchemeAction.matching("scheme://evaluate?id=5")SchemeAction.matching("")
}
命令解释器模式CommandandInterpreterPattern功能:给产品或者其他设计定义一种开放简单脚本用来编写剧情import java.util.*
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledThreadPoolExecutor
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.ReentrantLockclass TimeWait(val time: Long) : Runnable {companion object {val poolExecutor: ScheduledThreadPoolExecutor = ScheduledThreadPoolExecutor(10)}var keepOn = false;var lock = ReentrantLock()var condition = lock.newCondition()override fun run() {println("等待:" + time)poolExecutor.schedule({lock.lock()keepOn = truecondition.signalAll();lock.unlock()}, time, TimeUnit.MILLISECONDS)while (!keepOn) {lock.lock()condition.await()lock.unlock()}}
}
interface Interpreter {fun interpreter(command: String, commandArr: List<String>): Runnable?
}class SkillInterpreter : Interpreter {override fun interpreter(command: String, arr: List<String>): Runnable? {if (arr[0].equals("skill")) {return when (arr[2]) {"eat" -> Runnable { println("${arr[1]} skill ${arr[2]} (O ^ ~ ^ O)") }"ultimate" -> Runnable { println("${arr[1]} skill ${arr[2]}(╯‵□′)╯︵┴─┴") }else -> Runnable { }}}return null}
}class MoveInterpreter : Interpreter {override fun interpreter(command: String, arr: List<String>): Runnable? {if (arr[0].equals("move")) {return when (arr[3]) {"right" -> Runnable { println("${arr[1]} is >>move>>  ${arr[2]}") }"left" -> Runnable { println("${arr[1]} is <<move<<  ${arr[2]}") }else -> Runnable { }}}return null}
}class TimeInterpreter : Interpreter {override fun interpreter(command: String, arr: List<String>): Runnable? {if (arr[0].equals("wait")) {return TimeWait(arr[1].toLong())}return null}
}object ScriptProcessor {var service = Executors.newSingleThreadExecutor();var queueAction = LinkedList<Runnable>()var scripts= arrayListOf<Interpreter>()fun load(clazz:Class<out Interpreter>):ScriptProcessor{scripts.add(clazz.newInstance())return this}fun addAction(actuin: String): ScriptProcessor = apply {addAction(change(actuin))}fun addAction(actuin: Runnable): ScriptProcessor = apply { queueAction.add(actuin) }private fun change(action: String): Runnable {try {var arr = action.split(" ")for(script in scripts) {script.interpreter(action, arr)?.apply{ return this }}return Runnable { println("无效脚本:${action}") }} catch (e: Exception) {return Runnable { println("错误脚本:${action}") }}}fun start(): ScriptProcessor = apply {while (!queueAction.isEmpty()) {service.submit(queueAction.pollFirst())}}
}fun main(args: Array<String>) {ScriptProcessor.load(SkillInterpreter::class.java).load(MoveInterpreter::class.java).load(TimeInterpreter::class.java).addAction("skill k eat").addAction("wait 2000").addAction("wait ^%$%#$%").addAction("move k 5 right").addAction("wait 2500").addAction("mov k 5 left")//<-错误脚本.addAction("wait 1000").addAction("move k 5 left").addAction("wait 1000").addAction("skill k ultimate").start()
}
输入结果
等待:2000
错误脚本:wait ^%%
k is >>move>> 5
等待:2500
无效脚本:mov k 5 left
等待:1000
k is <<move<< 5
等待:1000
k skill ultimate(╯‵□′)╯︵┴─┴
装饰者模式Decirator功能:用类的方式创建html标签
类似的例子比如文字有颜色有粗体有斜体
饮料有冰 热 加糖 加椰果等等需求
这种需要大量组合的类open class TextBlock
{constructor(){}constructor(str:String){content=str}constructor(block:TextBlock){nextBlock=block}var content: String?=nullvar nextBlock:TextBlock?=nullopen fun outPrintln():String{return content?:"";}open fun link(textBlock: TextBlock):TextBlock{textBlock.nextBlock=thisreturn textBlock}
}
class ColorTextBlock:TextBlock
{constructor(color:String){}constructor(color:String,block:TextBlock){nextBlock=block}override fun outPrintln():String{return "<font color='#FF0000'>${nextBlock?.outPrintln()}</font>";}
}
class StrongTextBlock:TextBlock
{constructor(){}constructor(block:TextBlock){nextBlock=block}override fun outPrintln():String{return "<strong>${nextBlock?.outPrintln()?:""}</strong>";}
}class SmallTextBlock:TextBlock
{constructor(){}constructor(block:TextBlock){nextBlock=block}override fun outPrintln():String{return "<small>${nextBlock?.outPrintln()}</small>";}
}fun main(args: Array<String>) {ColorTextBlock("#FF0000",SmallTextBlock(TextBlock("文字"))).run { outPrintln() }//简写TextBlock("文字").link(SmallTextBlock()).link(StrongTextBlock()).link(ColorTextBlock("#FF0000")).run { outPrintln() }
}
外观模式Facade功能:包装一层,将原本不同的很复杂的接口(支付宝sdk和微信sdk)统一成一种import SimplePay.SimplePayListen
import SimplePay.pay
import java.util.*class AliPaySdk{interface AliPayListen{fun alipayStatusListn(code:Int)}fun pay(gold:String,listen:AliPayListen){listen.alipayStatusListn(0)}
}
class WeixinPaySdk{interface WeixinPayListen{fun alipayStatusListn(errCode:String)}fun pay(gold:String,listen:WeixinPayListen){listen.alipayStatusListn("susscess")}
}
object SimplePay
{const val PAY_TYPE_ALI=1const val PAY_TYPE_WEIXIN=2var aliPay=AliPaySdk()var weixinPay=WeixinPaySdk();interface SimplePayListen{fun alipayStatusListn(payType:Int,errorCode:Int,message:String)}fun pay(payType:Int,gold:Double,listen:SimplePayListen){when(payType){PAY_TYPE_ALI->{AliPaySdk().pay(gold.toString(),object:AliPaySdk.AliPayListen{override fun alipayStatusListn(code: Int) {var message:String=when(code){0->"成功"else->"失败"}listen.alipayStatusListn(PAY_TYPE_ALI,code,message)}})}PAY_TYPE_WEIXIN->{WeixinPaySdk().pay(gold.toString(),object:WeixinPaySdk.WeixinPayListen{override fun alipayStatusListn(errCode: String) {var code=0var message:String=when(errCode){"susscess"->{"成功"}else->{code=2;"失败"}}listen.alipayStatusListn(PAY_TYPE_ALI,code,message)}})}else->{throw RuntimeException("no pay method")}}}}
fun main(args: Array<String>) {SimplePay.pay(SimplePay.PAY_TYPE_ALI,1.0, object:SimplePayListen{override fun alipayStatusListn(payType: Int, errorCode: Int, message: String) {println("error code:${errorCode}  message:${message}")}})
}
状态模式模式State功能:为每一种状态定义不同的显示和点击事件class Order{var subscribeState:State = State(1,{println("ui->subscribeState")},{println("onclick->subscribeState")})var payState:State = State(2,{println("show state->payState") },{println("onclick->payState") })var finishState:State = State(3,{ println("show state->finishState")},{ println("onclick->finishState") })var status:State=subscribeStateinner class State(val status:Int,val onRefreshUI:()->Unit,val onClick:()->Unit)fun refreshUI(){println("refreshUI")status.onRefreshUI.invoke()}fun onClick(){println("onClick")status.onClick.invoke()}
}fun main(arr:Array<String>){var order=Order()order.status=order.finishStateorder.refreshUI()order.onClick()
}
过滤器模式Filter为不同的人群筛选复杂的贷款套餐业务import java.util.*inline fun <reified T> orFilter(vararg args: (t:T)->Boolean): (t:T)->Boolean = { t: T->var isCheck = false;args.forEach { isCheck =  it.invoke(t)||isCheck }isCheck
}
inline fun <reified T> andFilter(vararg args: (t:T)->Boolean): (t:T)->Boolean = {t: T->var isCheck = true;args.forEach { isCheck =   it.invoke(t)&&isCheck}isCheck
}inline fun <reified T> filter(list: List<T>, vararg arr:(t:T)->Boolean): List<T> {var iterator = list.listIterator()var resultList = arrayListOf<T>()while (iterator.hasNext()) {var value = iterator.next()var isCheck = true;for (filter in arr) {isCheck = filter.invoke(value)if (!isCheck) {break}}if (isCheck) {resultList.add(value)}}return resultList
}data class Person(val id: Int, val name: String, val sex: Int, val loan: Int)var manFilter = {t:Person->t.sex == 1}
var womenFilter = {t:Person->t.sex == 2}
var loan5Filter = {t:Person->t.loan>=5}
var loan6Filter = {t:Person->t.loan>=6}
var idFilter = {t:Person->t.id<=5}//查询前5幸运客户或者资金大于5的男性
var planA=orFilter(andFilter(manFilter, loan5Filter), idFilter)
//查询资金大于等于5并且是男性 或者资金大于等于6的女性
var planB=andFilter(orFilter(manFilter, loan5Filter), orFilter(womenFilter, loan6Filter))fun main(args: Array<String>) {var arr = arrayListOf<Person>()for (i in 1..10) {var person = Person(i, "张" + i, 1 + Random().nextInt(2), (Random().nextInt(10)));arr.add(person)}arr.forEach{println(it)}println("=====planA=======")filter(arr, planA).forEach {println(it)}println("=====planB=======")// println("=====Lambda======")filter(arr, planB).forEach {println(it)}println("==planA and planB==")filter(arr,planA,planB).forEach {println(it)}}
输入结果
Person(id=1, name=张1, sex=1, loan=5)
Person(id=2, name=张2, sex=1, loan=3)
Person(id=3, name=张3, sex=1, loan=6)
Person(id=4, name=张4, sex=2, loan=2)
Person(id=5, name=张5, sex=1, loan=7)
Person(id=6, name=张6, sex=2, loan=8)
Person(id=7, name=张7, sex=1, loan=4)
Person(id=8, name=张8, sex=1, loan=8)
Person(id=9, name=张9, sex=1, loan=1)
Person(id=10, name=张10, sex=2, loan=7)
=====planA=======
Person(id=1, name=张1, sex=1, loan=5)
Person(id=2, name=张2, sex=1, loan=3)
Person(id=3, name=张3, sex=1, loan=6)
Person(id=4, name=张4, sex=2, loan=2)
Person(id=5, name=张5, sex=1, loan=7)
Person(id=8, name=张8, sex=1, loan=8)
=====planB=======
Person(id=3, name=张3, sex=1, loan=6)
Person(id=5, name=张5, sex=1, loan=7)
Person(id=6, name=张6, sex=2, loan=8)
Person(id=8, name=张8, sex=1, loan=8)
Person(id=10, name=张10, sex=2, loan=7)
==planA and planB==
Person(id=3, name=张3, sex=1, loan=6)
Person(id=5, name=张5, sex=1, loan=7)
Person(id=8, name=张8, sex=1, loan=8)
访问者模式Visitor功能:打印遍历当前文件夹下 mp3 或者 图片文件import java.io.File
import java.io.FileFilter
import java.util.ArrayListclass MP3FileFilter : FileFilter {override fun accept(file:java.io.File?): Boolean {fun checkFileName():Boolean{ val name = file?.getName();return name!!.endsWith(".mp3") || name!!.endsWith(".mp4")}return when(true){file?.isDirectory->falsecheckFileName()->trueelse->false}}
}
class ImgFileFilter : FileFilter {override fun accept(file:java.io.File?): Boolean {fun checkFileName():Boolean{ val name = file?.getName();return name!!.endsWith(".jpeg") || name!!.endsWith(".png")}return when(true){file?.isDirectory->falsecheckFileName()->trueelse->false}}
}fun getAllFile(baseFile: java.io.File,filter:FileFilter): List<java.io.File> = ArrayList<java.io.File>().apply {if (baseFile.isFile() || !baseFile.exists()) {return this}val files = baseFile.listFiles()for (file in files) {if (file.isDirectory()) {getAllFile(file,filter)} else {if(filter.accept(file)) {this.add(file)}}}}fun main(args: Array<String>) {println(getAllFile(java.io.File("."),MP3FileFilter()));println(getAllFile(java.io.File("."),ImgFileFilter()));
}
输入结果
[]
[]

 

本文标签: 实用精短