Java设计模式

  1. 单例模式
    **单例模式最核心的地方就是实例对象有且只有一个,所以构造方法私有化是必须的,对外界只留一个getInstance方法去获取唯一的实例对象,这样就防止该实例在类外部产生。
    **饿汉式:无论调用与否,都会产生实例对象
package Singleton;
//饿汉式
public class Singleton1 {
    private Singleton1(){
    }

    private static Singleton1 singleton1=new Singleton1();

    public static Singleton1 getInstance(){
        return singleton1;
    }
}

**懒汉式:只有调用后才会产生实例对象

package Singleton;

public class Singleton2 {
    private Singleton2(){
    }

    private static volatile Singleton2 singleton2=null;//预防指令重排序,解决内存可见性

    public static Singleton2 getInstance(){
        if(singleton2==null){
            synchronized (Singleton2.class){
                if(singleton2==null){
                    singleton2=new Singleton2();
                }
            }
        }
        return singleton2;
    }
}

多线程中懒汉式并不安全,需要加锁,但又需要锁的粒度尽量小,所以在判断为null后进行加锁,但是如果当前线程没有完成初始化并写入内存,另一个线程已经读取到值为null那么此时当另一个线程再获取到锁就会产生一个实例,当前线程获取到锁继续执行锁中的实例化代码就会又产生一个实例对象,所以在锁里面还需要判断是否为null,即便如此,还需要在定义对象的时候加上一个volatile修饰,这部分不是线程安全问题导致,而是JMM内存模型所做出的优化而导致的指令重排序问题。如果进入到加锁中判断引用对象为空,由于内存模型允许所谓的无序写入,就有可能导致singleton2=new Singleton2()没有运行完但singleton2值已经不为null,那么另一个线程判断第一个if语句时就直接返回的是一个没有初始化成功的singleton2。

  1. 观察者模式:也叫做发布-订阅模型
    **当一个对象改变,依赖它地订阅者都会收到通知执行更新操作,而未订阅者不会收到消息。
    **需要四个角色:
    –(1)抽象被观察者:保存所有观察者对象,提供增加,删除观察者以及通知观察者的接口
    –(2)抽象观察者:当发生更新操作的时候,通过这个接口通知自己发生了什么更新操作
    –(3)被观察者:实现抽象被观察者接口,当想要发布消息的时候,为列表中的订阅者分发消息
    –(4)观察者:实现抽象观察者接口,当有更新操作发生,那么观察者就会通过这个接口获取到更新操作
package Observer;
//抽象被观察者,进行观察者的增删和消息分发
public interface Oberserverable {
    void register(Oberserver o);//添加观察者
    void remove(Oberserver o);//删除观察者
    void pushMessage();//为所有观察者推送消息
}

package Observer;
//抽象观察者,为观察者提供消息更新的接口
public interface Oberserver {//实现该接口的类都可以作为观察者进行订阅
    void update(String message);//当发生消息更新的时候为所有观察者推送更新的消息
}

package Observer;
//举例:以微信公众号作为被观察者进行观察者的增删和消息推送,即发布者
import java.util.ArrayList;
import java.util.List;

public class WeChatServer implements Oberserverable{
    private List<Oberserver> list;
    private String message;
    public WeChatServer() {
        list=new ArrayList<>();
    }

    @Override
    public void register(Oberserver o) {
        list.add(o);//当有人关注公众号,就会将该用户当做订阅者加入列表
    }

    @Override
    public void remove(Oberserver o) {
        if(list.contains(o)){
            list.remove(o);//当有人取关,就要将该用户从列表删除,后续的更新消息也不再推送
        }
    }

    @Override
    public void pushMessage() {
        for(Oberserver o:list){
            o.update(message);//给每位订阅者推送消息
        }
    }

    public void setInfomation(String message){
        this.message=message;
        System.out.println("微信服务更新的消息是:"+message);

        pushMessage();//通知所有观察者更新消息
    }
}

package Observer;
//观察者,即微信公众号的订阅者
public class User implements Oberserver {
    private String name;
    private String message;
    public User(String name){
        this.name=name;
    }

    @Override
    public void update(String message) {//实现抽象观察者接口中的方法,当发布者有更新操作,就会从该接口获取到消息
        this.message=message;
        System.out.println(name+" :"+message+"是世界上最好的语言");
    }
}
  1. 适配器模式:将一个类的接口转换为另一个接口,适配器使得原本不能在一起工作的两个类可以兼容。
    **举例:假如要将手机视屏投影到大屏幕,可是type-c和vga两个接口不兼容。实现一个type-c转vga适配器
    **当希望将一个类转化为另一个满足新接口的类,就可以使用类适配器,即创建新类继承原有的类实现接口。
    **当希望将一个对象转化为满足另一个新接口的对象时,可直接创建Type2vga2 类持有原类的实例,在Type2vga2 中调实例方法。
    **当不希望实现接口中所有方法时,就用一个抽象类AdapterClass 实现接口中所有方法,写其他类只需要继承抽象类AdapterClass
    **(1)类的适配器模式:通过继承特性实现适配器功能
package Adapter;
//手机输出type-c数据
public class Phone {
    public void typecPhone(){
        System.out.println("信息从Typec口输出");
    }
}
package Adapter;
//定义一个vga接口
public interface VGA {
    public abstract void vgaInterface();
}
package Adapter;

public class Typec2vga extends Phone implements VGA{
    @Override
    public void vgaInterface() {
        typecPhone();
        System.out.println("正在进行typec数据转换vga数据......");
        System.out.println("转换成功,可以进行vga对接...");
    }
}

**(2)对象的适配器模式

package Adapter;
//通过组合的方式实现适配器功能
public class Type2vga2 implements VGA{
    private Phone phone;

    public Type2vga2(Phone phone){
        this.phone=phone;
    }

    @Override
    public void vgaInterface() {
        if(phone!=null){
            phone.typecPhone();
            System.out.println("正在进行typec数据转换vga数据......");
            System.out.println("转换成功,可以进行vga对接...");
        }
    }
}

**(3)接口的适配器模式

package Adapter;
//定义三个接口
public interface Adapter {
    void typec();
    void vga();
    void hdmi();
}
package Adapter;
//定义抽象类
public abstract class AdapterClass implements Adapter{
    public AdapterClass() {
    }

    @Override
    public void typec() {

    }

    @Override
    public void vga() {

    }
}
public class vgaAdapter extends AdapterClass{
    @Override
    public void typec() {
        Phone phone=new Phone();
        phone.typecPhone();
    }

    @Override
    public void vga() {//实现了VGA适配器
        System.out.println("正在进行typec数据转换vga数据......");
        System.out.println("转换成功,可以进行vga对接...");
    }

    @Override//同理,还可实现HDMI的适配器
    public void hdmi() {

    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值