单例模式
一、饿汉式:
package single;
public class EagerSingleton {
private final static EagerSingleton EAGER_SINGLETON = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return EAGER_SINGLETON;
}
}
二、普通懒汉式:
public class LazySingleton {
private static LazySingleton lazySingleton = null;
private LazySingleton() {}
public static LazySingleton getInstance() {
if(lazySingleton == null) {
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
三、线程安全懒汉式:
public class LazySingletonSafe {
private static LazySingletonSafe lazySingleton = null;
private LazySingletonSafe() {}
public synchronized static LazySingletonSafe getInstance() {
if(lazySingleton == null) {
lazySingleton = new LazySingletonSafe();
}
return lazySingleton;
}
}
四、双重校验懒汉式:
public class LazySingletonDoubleCheck {
private volatile static LazySingletonDoubleCheck lazySingleton = null;
private LazySingletonDoubleCheck() {}
public static LazySingletonDoubleCheck getInstance() {
if(lazySingleton == null) {
synchronized(LazySingletonDoubleCheck.class){
if(lazySingleton == null) {
lazySingleton = new LazySingletonDoubleCheck();
}
}
}
return lazySingleton;
}
}
五、静态内部类式:
public class StaticInnerClassSingleton {
private StaticInnerClassSingleton() {}
private static class StaticInnerClassSingletonLoader{
public static final StaticInnerClassSingleton singleton = new StaticInnerClassSingleton();
}
public static StaticInnerClassSingleton getInstance() {
return StaticInnerClassSingletonLoader.singleton;
}
}
六、防止序列化破坏的单例
增加readResolve方法,这样调用反序列化时,会返回内存存在的单例对象实体
import java.io.Serializable;
public class LazySingleton implements Serializable{
private static final long serialVersionUID = 1L;
private static LazySingleton lazySingleton = null;
private LazySingleton() {}
public static LazySingleton getInstance() {
if(lazySingleton == null) {
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
private Object readResolve() {
return lazySingleton;
}
}
观察者模式
以按下按钮启动机器为例,用观察者模式实现该功能。
设置机器一 、机器二
import java.util.Observable;
import java.util.Observer;
public class Machine1 implements Observer {
Button button ;
public Machine1(Button button) {
this.button = button;
button.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
System.out.println("Machine1接收指令:"+arg);
System.out.println("Machine1已启动");
}
}
import java.util.Observable;
import java.util.Observer;
public class Machine2 implements Observer {
Button button ;
public Machine2(Button button) {
this.button = button;
button.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
System.out.println("Machine2接收指令:"+arg);
System.out.println("Machine2已启动");
}
}
设置一键启动按钮
public class Button extends Observable{
public void notifyMachine(){
setChanged(); //必须调用的方法,底层实现是设置变更标志位为True
notifyObservers("发出启动指令"); //向所有注册的观察者发布最新消息,发布后将变更标志位置位False
}
}
编写主方法,按下启动键
public class Test {
public static void main(String[] args) {
Button b = new Button();
new Machine1(b);
new Machine2(b);
System.out.println("启动所有机器");
b.notifyMachine();
}
}
启动所有机器
Machine2接收指令:发出启动指令
Machine2已启动
Machine1接收指令:发出启动指令
Machine1已启动
工厂模式
一、简单工厂方法:
以视频工厂为例,输入视频类型,自动生产合适的对象
//创建父抽象类Video,定义抽象方法getDetail
public abstract class Video {
public abstract void detail();
}
//创建avi类
public class AVI extends Video{
public void detail() {
System.out.println("这是avi视频");
}
}
//创建MP4类
public class MP4 extends Video{
public void detail() {
System.out.println("这是mp4视频");
}
}
//创建rmvb类
public class RMVB extends Video {
public void detail() {
System.out.println("这是rmvb视频");
}
}
创建工厂
public class VideoFactory {
public static Video getVideo(String type) {
if("mp4".equals(type)) {
return new MP4();
}
else if("rmvb".equals(type)) {
return new RMVB();
}
else if("avi".equals(type)) {
return new AVI();
}else {
return null;
}
}
}
创建测试类
public class Test {
public static void main(String[] args) {
VideoFactory.getVideo("mp4").detail();
Video video = VideoFactory.getVideo("avi");
video.detail();
}
}
结果
这是mp4视频
这是avi视频
二、工厂方法
基于开放关闭原则,对扩展的类创建保持开发,所以将创建类的功能下放到具体视频的工厂方法中。例如:
先创建对应的视频类
public abstract class Video {
public abstract void detail();
}
public class AVI extends Video{
public void detail() {
System.out.println("这是avi视频");
}
}
public class MP4 extends Video{
public void detail() {
System.out.println("这是mp4视频");
}
}
public class RMVB extends Video {
public void detail() {
System.out.println("这是rmvb视频");
}
}
再创建对应的视频类工厂
public interface VideoFactory {
public Video getVideo();
}
public class AVIFactory implements VideoFactory{
@Override
public Video getVideo() {
return new AVI();
}
}
public class MP4Factory implements VideoFactory{
@Override
public Video getVideo() {
return new MP4();
}
}
public class RMVBFactory implements VideoFactory{
@Override
public Video getVideo() {
return new RMVB();
}
}
最终我们的测试方法:
public class Test {
public static void main(String[] args) {
VideoFactory aviFactory = new AVIFactory();
aviFactory.getVideo().detail();
VideoFactory mp4Factory = new MP4Factory();
mp4Factory.getVideo().detail();
VideoFactory rmvbFactory = new RMVBFactory();
rmvbFactory.getVideo().detail();
}
}
这是avi视频
这是mp4视频
这是rmvb视频
三、抽象工厂方法:
所谓抽象工厂,说白了就是当你需要的对象属于不同的类型,但是属于同一家族的时候,我们使用抽象工厂来创建。比如说我们创建一个播放器类,它需要视频文件和字幕文件,那么视频文件和字幕文件又会对应不同的格式,比如mp4啊avi啊之类的。这个时候工厂方式很难满足我们的需求。
所以不妨,我们以播放器为主体,每一个格式类型的播放器对应一套视频+字幕。
//首先编写视频类抽象类和字幕类抽象类
public interface SRT {
public void getDetail();
}
public interface Video {
public void getDetail();
}
//其次编写播放器抽象工厂
public interface PlayerFactory {
//视频
public Video getVideo();
//字幕
public SRT getSRT();
}
接下来针对不同格式的视频和字幕编写实现类
//接下来针对不同格式的视频和字幕编写实现类
public class AVISRT implements SRT{
public void getDetail() {
System.out.println("这是avi字幕");
}
}
public class AVIVideo implements Video{
public void getDetail() {
System.out.println("这是avi视频");
}
}
public class MP4SRT implements SRT{
public void getDetail() {
System.out.println("这是mp4字幕");
}
}
public class MP4Video implements Video{
public void getDetail() {
System.out.println("这是mp4视频");
}
}
最后编写相关类型格式的播放器工厂
//最后编写相关类型格式的播放器工厂
public class MP4PlayerFactory implements PlayerFactory {
@Override
public Video getVideo() {
return new MP4Video();
}
@Override
public SRT getSRT() {
return new MP4SRT();
}
}
public class AVIPlayerFactory implements PlayerFactory {
@Override
public Video getVideo() {
return new AVIVideo();
}
@Override
public SRT getSRT() {
return new AVISRT();
}
}
测试类:
public class Test {
public static void main(String[] args) {
PlayerFactory pf = new AVIPlayerFactory();
Video v = pf.getVideo();
SRT s = pf.getSRT();
v.getDetail();
s.getDetail();
}
}
这是avi视频
这是avi字幕