饿汉模式在类初始化的时候就创建了对象,所以不存在线程安全问题。
局限性:
1、如果构造方法中有耗时操作的话,会导致这个类的加载比较慢;
2、饿汉模式一开始就创建实例,但是并没有调用,会造成资源浪费;
java模式下
public class ModelJavaTest {
private static ModelJavaTest mInstance = new ModelJavaTest();
public static ModelJavaTest getInstance(){
return mInstance;
}
}
Kotlin
class ModelKotlinTest {
object ModelKotlinTest{
}
}
java
class SingleJavaClass {
private volatile static SingleJavaClass instance;
public static SingleJavaClass getInstance() {
if (instance == null) {
synchronized (SingleJavaClass.class) {
if (instance == null) {
instance = new SingleJavaClass();
}
}
}
return instance;
}
}
kotlin
class SingKotlinClass {
companion object {
val instance: SingKotlinClass by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { SingKotlinClass() }
}
}
java
//水果抽象类
interface Fruit {
void showPrice();//水果价格
}
abstract class AbsFruit implements Fruit {
public float mPrice;
}
class Apple extends AbsFruit {
public Apple(float price) {
mPrice = price;
}
@Override
public void showPrice() {
System.out.println("apple price is " + mPrice);
}
}
class Banana extends AbsFruit {
public Banana(float price) {
mPrice = price;
}
@Override
public void showPrice() {
System.out.println("Banana price is " + mPrice);
}
}
class FruitFactory {
public static Fruit getApple() {
return new Apple(5.0f);
}
public static Fruit getBanana() {
return new Banana(8.0f);
}
public static void main(String[] args) {
Fruit apple = FruitFactory.getApple();
apple.showPrice();
}
}
kotlin
interface FruitKotlin {
val price: Float
fun showPrice()
}
class FruitFactoryKotlin {
companion object {
fun getApple() = AppleKotlin(5.0f)
fun getBanana() = BananaKotlin(8f)
}
}
class AppleKotlin(override val price: Float) : FruitKotlin {
override fun showPrice() {
println("apple price is $price")
}
}
class BananaKotlin(override val price: Float) : FruitKotlin {
override fun showPrice() {
println("banana price is $price")
}
}
builder模式也是一种常用的设计模式,常用于复杂对象的构建,例如 Android 中的 AlertDialog.
class Car(val color: String = "black", val factory: String = "Audi")
fun main() {
val redCar = Car(color = "red")//只关心颜色
val bmwCar = Car(factory = "BMW")//只关心品牌
}
apply函数时 kotlin 标准库的函数。我们先看看使用 apply 是如何构建对象
class Car2 {
var color = "black"
var factory = "Audi"
}
fun t() {
val newCar = Car2().apply {
factory = "BMW"
color = "red"
}
}
看一下 apply 函数 的实现
@kotlin.internal.InlineOnly
public inline fun T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
从源码中可以看出,apply 函数其实是类型 T 的扩展函数。参数是一个带接受者的 lambda 表达式,执行我传入的 block 后,会把当前实例返回。 kotlin 中,可以在任何对象上使用 apply 函数,不需要额外的支持。 apply 函数的一种使用方式就是创建一个对象实例并且按照正确的方式初始化他的一些属性。和 java 当中的 builder 模式死异曲同工的效果,但是使用起来要简洁很多。
interface Shape {
fun draw()
}
class Circle : Shape {
override fun draw() {
println("draw Circle")
}
}
fun Circle.redColor(decorator: Shape.() -> Unit) {
println("with red color extend")
decorator()
}
fun Shape.boldLine(decorator: Shape.() -> Unit) {
println("with bold line extend")
decorator()
}
fun t2() {
Circle().run {
boldLine {
redColor {
draw()
}
}
}
}
采用扩展函数的方式实现装饰者模式,没有中间的装饰类,代码简洁。但是只能装饰一个方法,对于多个方法都需要装饰的情况下,可能使用委托更为适合