设计模式--kotlin&java

一、前言

二、单例模式

饿汉模式

java

java 复制代码
//单例模式 -- 饿汉式
public class Singleton {
    //随着对象的创建就去new 
    private static Singleton mInstance = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance(){
        return mInstance;
    }
}

kotlin

Kotlin 复制代码
object Singleton {

}

总结:

饿汉模式在类被初始化时就在内存中创建了对象,以空间换时间的方式创建对象,不存在线程安全问题,对象只要类被初始化就会被创建,比较占内存

懒汉模式

最初模型

java

Kotlin 复制代码
//单例模式 -- 懒汉式
public class Singleton {
    //只有使用的时候才去new对象,更加高效,
    private static Singleton mInstance ;

    private Singleton() {
    }

    
    public static Singleton getInstance(){
        if (mInstance == null){
            //会出现多线程并发问题
            mInstance = new Singleton();
        }
        return mInstance;
    }
}

kotlin

Kotlin 复制代码
//懒汉式
//构造函数私有化
class Singleton private constructor() {

    companion object {
        private var instance: Singleton? = null
            get() {
                if (field == null) {
                    field = Singleton()
                }
                return field
            }

        fun get(): Singleton {
            return instance!!
        }
    }
}

总结:

  • 在方法被调用时才会创建这个对象,以时间换空间
  • 存在风险:多线程并发调用时,实例可能创建多份
解决懒汉式在多线程下的并发问题 -- 加锁

java

Kotlin 复制代码
//单例模式 -- 懒汉式
public class Singleton {
    private static Singleton mInstance;

    private Singleton() {
    }

    //解决懒汉式多线程并发问题,但是会出现效率低的问题,每次获取都要经过同步锁的判断
    public static synchronized Singleton getInstance(){
        if (mInstance == null){
            mInstance = new Singleton();
        }
        return mInstance;
    }   
}

kotlin

Kotlin 复制代码
class Singleton private constructor() {

    companion object {
        private var instance: Singleton? = null
            get() {
                if (field == null) {
                    field = Singleton()
                }
                return field
            }

        @Synchronized
        fun get(): Singleton {
            return instance!!
        }
    }
}

总结:

  • 通过Synchronized关键字来修饰静态方法,保证多个线程并发调用时只有一个线程进入到方法内部,当一个线程调用时,其他线程被阻隔在方法外边,来保证实例的唯一性
  • 解决了懒汉式多线程并发问题,但是会出现并发调用效率低的问题,每次获取都要经过同步锁的判断,
解决每次获取都要经过同步锁判断导致的线程低的问题 -- 双重检验

java

java 复制代码
//单例模式 -- 懒汉式
public class Singleton {
    private volatile static Singleton mInstance;

    private Singleton() {
    }

   //既保证了线程安全,效率也是比较高,但是会出现指令重排序问题
    public static Singleton getInstance() {
        if (mInstance == null) {
            synchronized (Singleton.class) {
                if (mInstance == null) {
                    mInstance = new Singleton();
                }
            }
        }
        return mInstance;
    }
}

kotlin

Kotlin 复制代码
class Singleton private constructor() {

    companion object {
        val INSTANCE: Singleton by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            Singleton()
        }
    }
}

总结:

  • 提效,第一个判空,是在instance创建的情况下避免进入同步代码块,提供程序并发效率
  • 保证唯一性,当多个线程并发访问对象时,会遇到同步代码块,只能有一个线程执行,其他线程必须等待当前线程完成之后才能继续执行
  • 但是需要增加一个volatile关键字

volatile关键字禁止重排序:

多线程进入到getInstance之后,线程A在自己的工作线程里面创建了自己的实例,此时还未同步到主存中,A已经跳出了代码块,是否了锁,当B线程进行代码块,获得了同步代码块的执行时间,判断instance==null,这时B线程还是会去创建这个实力,所以它并不能百分百的保证实例的唯一性,内存空间会被重排,加上volatile关键字来保证实例的可见性,防止指令重排序

静态内部类模式

java

java 复制代码
//静态内部类
public class singleton {
    private static class singletonProvider {
        private static singleton instance = new singleton();
    }

    private singleton() {
    }

    public static singleton getInstance() {
        return singletonProvider.instance;
    }
}

kotlin

Kotlin 复制代码
class Singleton {

    companion object {
        val instance = SingletonProvider.holder
    }

    private object SingletonProvider {
        val holder = singleton()
    }
}

总结:

推荐使用,既能保证线程安全,又能保证实例的唯一性,还能实现单例延时的实例化,外部类加载时并不会立即加载内部类,内部类不被加载也就不会实例化instance,因此不会占用空间,只有调用getInstance,访问singletonProvider.instance时,才会去实例化SingletonProvider,才会创建Singleton的实例

三、装饰器模式

java

java 复制代码
/**
 * 抽象组件
 */
public interface Animal {
    void eat();
}

/**
 * 被装饰者组件
 */
public class Panda implements Animal {
    @Override
    public void eat() {
        System.out.println("吃什么?");
    }
}

/**
 * 抽象装饰器
 */
public abstract class Food implements Animal{
    Animal animal;

    public Food(Animal animal) {
        this.animal = animal;
    }

    @Override
    public void eat() {
        animal.eat();
    }
}

/**
 * 具体装饰器
 */
public class BarrotFood extends Food{

    public BarrotFood(Animal animal) {
        super(animal);
    }

    @Override
    public void eat() {
        super.eat();
        System.out.println("可以吃胡萝卜");
    }
}

/**
 * 具体装饰器
 */
public class BambooFood extends Food{

    public BambooFood(Animal animal) {
        super(animal);
    }

    @Override
    public void eat() {
        super.eat();
        System.out.println("可以吃竹子");
    }
}

public class Client {
    public static void main(String[] args) {
        Panda panda = new Panda();

        BarrotFood barrotFood = new BarrotFood(panda);
        BambooFood bambooFood = new BambooFood(barrotFood);
        bambooFood.eat();
    }
}

/**
 * 测试类
 */
public class Client {
    public static void main(String[] args) {
        Panda panda = new Panda();

        BarrotFood barrotFood = new BarrotFood(panda);
        BambooFood bambooFood = new BambooFood(barrotFood);
        bambooFood.eat();
    }
}

Kotlin

Kotlin 复制代码
fun Panda.bamboo(decorator:()->Unit){
    eat()
    println("可以吃竹子")
    decorator()
}

fun Panda.carrot(decorator:()->Unit){
    println("可以吃胡萝卜")
    decorator()
}

fun main() {
    Panda().run { 
        bamboo { carrot {  } }
    }
}

四、建造者模式

Java

java 复制代码
public class Pen {
    private Builder builder;

    public Pen(Builder builder) {
        this.builder = builder;
    }

    public void write() {
        System.out.println("color:" + builder.color + "  width:" + builder.width + "  round:" + builder.round);
    }

    public static class Builder {
        private String color = "white";
        private float width = 1.0f;
        private boolean round = false;

        public Builder setColor(String color) {
            this.color = color;
            return this;
        }

        public Builder setWidth(float width) {
            this.width = width;
            return this;
        }

        public Builder setRound(boolean round) {
            this.round = round;
            return this;
        }

        public Pen build() {
            return new Pen(this);
        }
    }
}

public class Client {
    public static void main(String[] args) {
        Pen.Builder builder = new Pen.Builder();
        builder.setColor("").setRound(true).setWidth(1f).build().write();
    }
}

Kotlin

Kotlin 复制代码
class Penk {
    var color = "white"
    var width = 1.0f
    var round = false

    fun write() {
        println("color:${color}   width:${width}   round:${round}")
    }
}

fun main() {
    val pen = Penk()    
    //使用with来实现建造者模式
    with(pen) {
        color = ""
        width = 1f
        round = true
    }
    pen.write()

    //使用apply来实现建造者模式
    pen.apply {
        color = ""
        width = 2f
        round = false
        write()
    }
}

五、适配器模式

把一个类的接口变成客户端所期待的另一个接口,从而使因接口不匹配的两个模块或者部件能在一起工作。

分为类适配器模式

**Android中源码中的使用:**ListView、RecyclerView

优点:

  • 将目标类和适配器类解耦
  • 增加了类的透明性和复用性
  • 灵活性和扩展性好,符合开闭原则

结构:

  • Target:目标角色(所期待得到的接口)
  • Adapter:适配器类
  • Adaptee:适配器类(现在需要适配的接口)
  • Client:客户类

类适配器模式

Kotlin 复制代码
interface Target {
    fun request1()
    fun request2()
}

//适配者类
open class Adaptee {
    fun request1() {
        println("Adaptee:request1")
    }
}

//适配器类
class AdapterClass : Adaptee(), Target {
    override fun request2() {
        println("AdapterClass:request2")
    }
}

class Client {
    fun main() {
        //类适配器
        val adapterClass = AdapterClass()
        adapterClass.apply {
            request1()
            request2()
        }
    }
}

对象适配器模式

使用委派替代继承

Kotlin 复制代码
//适配者类
open class Adaptee {
    fun request1() {
        println("Adaptee:request1")
    }
}

//对象适配器
class AdapterObj(private var adaptee:Adaptee) :Target{
    override fun request1() {
        adaptee.request1()
    }

    override fun request2() {
        println("AdapterObj:request2")
    }
}

class Client {
    fun main() {
        //对象适配器
        val adaptee = Adaptee()
        val adapterObj = AdapterObj(adaptee)
        adapterObj.apply { 
            request1()
            request2()
        }
    }
}

优点:可以适配多个目标

六、架构、框架与设计模式

软件架构:

架构不是软件,它是抽象的,是一种设计方案,是一个蓝图

软件框架:

框架(framework)是整个或部分系统的可重用设计,表现为一组抽象架构及构件实例间交互的方法

框架是一种特殊的软件,它并不能提供完整无缺的解决方案,而是为你构建解决方案提供良好的基础

设计模式:

在软件工程中,设计模式是对软件设计中普遍存在的各种问题,所提出的解决方案。设计模式是解决局部问题的方法

相关推荐
醉颜凉19 分钟前
【NOIP提高组】潜伏者
java·c语言·开发语言·c++·算法
阿维的博客日记24 分钟前
java八股-jvm入门-程序计数器,堆,元空间,虚拟机栈,本地方法栈,类加载器,双亲委派,类加载执行过程
java·jvm
qiyi.sky24 分钟前
JavaWeb——Web入门(8/9)- Tomcat:基本使用(下载与安装、目录结构介绍、启动与关闭、可能出现的问题及解决方案、总结)
java·前端·笔记·学习·tomcat
lapiii35828 分钟前
图论-代码随想录刷题记录[JAVA]
java·数据结构·算法·图论
RainbowSea31 分钟前
4. Spring Cloud Ribbon 实现“负载均衡”的详细配置说明
java·spring·spring cloud
程序员小明z31 分钟前
基于Java的药店管理系统
java·开发语言·spring boot·毕业设计·毕设
爱敲代码的小冰1 小时前
spring boot 请求
java·spring boot·后端
Lyqfor1 小时前
云原生学习
java·分布式·学习·阿里云·云原生
程序猿麦小七1 小时前
今天给在家介绍一篇基于jsp的旅游网站设计与实现
java·源码·旅游·景区·酒店
张某布响丸辣2 小时前
SQL中的时间类型:深入解析与应用
java·数据库·sql·mysql·oracle