一、前言

二、单例模式

饿汉模式

java

//单例模式 -- 饿汉式

public class Singleton {

//随着对象的创建就去new

private static Singleton mInstance = new Singleton();

private Singleton() {

}

public static Singleton getInstance(){

return mInstance;

}

}

kotlin

object Singleton {

}

总结:

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

懒汉模式

最初模型

java

//单例模式 -- 懒汉式

public class Singleton {

//只有使用的时候才去new对象,更加高效,

private static Singleton mInstance ;

private Singleton() {

}

public static Singleton getInstance(){

if (mInstance == null){

//会出现多线程并发问题

mInstance = new Singleton();

}

return mInstance;

}

}

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

//单例模式 -- 懒汉式

public class Singleton {

private static Singleton mInstance;

private Singleton() {

}

//解决懒汉式多线程并发问题,但是会出现效率低的问题,每次获取都要经过同步锁的判断

public static synchronized Singleton getInstance(){

if (mInstance == null){

mInstance = new Singleton();

}

return mInstance;

}

}

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

//单例模式 -- 懒汉式

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

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

//静态内部类

public class singleton {

private static class singletonProvider {

private static singleton instance = new singleton();

}

private singleton() {

}

public static singleton getInstance() {

return singletonProvider.instance;

}

}

kotlin

class Singleton {

companion object {

val instance = SingletonProvider.holder

}

private object SingletonProvider {

val holder = singleton()

}

}

总结:

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

三、装饰器模式

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

fun Panda.bamboo(decorator:()->Unit){

eat()

println("可以吃竹子")

decorator()

}

fun Panda.carrot(decorator:()->Unit){

println("可以吃胡萝卜")

decorator()

}

fun main() {

Panda().run {

bamboo { carrot { } }

}

}

四、建造者模式

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

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:客户类

类适配器模式

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()

}

}

}

对象适配器模式

使用委派替代继承

//适配者类

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)是整个或部分系统的可重用设计,表现为一组抽象架构及构件实例间交互的方法

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

设计模式:

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

参考文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: