优快云博客地址 https://blog.youkuaiyun.com/weixin_47053123
Github项目下载地址https://github.com/MaBo2420935619
单例模式
饿汉模式
- 像一个饿汉一样,不管需不需要用到实例都要去创建实例,即在类产生的时候就创建好实例,这是一种空间换时间的做法。作为一个饿汉而言,体现了它的本质——“我全都要”。
- 对于饿汉模式而言,是线程安全的,因为在线程创建之前实例已经被创建好了。
代码演示
/**
* @Author mabo
* @Description 单例模式:饿汉式
* @Description 在类初始化的时候,完成对属性的初始化
* @Description 获取的对象是线程安全的
*/
class SingletonHungry {
//构造方法私有化,防止new对象
private SingletonHungry(){};
private final static SingletonHungry singletonHungry=new SingletonHungry();
public SingletonHungry getInstance(){
return singletonHungry;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
SingletonHungry singletonHungry = new SingletonHungry();
SingletonHungry instance = singletonHungry.getInstance();
System.out.println(instance.hashCode());
}
}
}
JDK Runtime实现源码
public class Runtime {
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
}
懒汉模式
懒汉模式就是需要用到创建实例了程序再去创建实例,而不是JVM加载类的时候就创建好实例。
这里采用双重检验来提高代码执行效率,同时保证线程安全
public static SingletonLazy getInstance(){
if (singletonLazy==null){
synchronized (SingletonLazy.class){
singletonLazy=new SingletonLazy();
}
}
return singletonLazy;
}
代码演示
/**
* @Author mabo
* @Description 单例模式:懒汉式,线程安全,双重检验初始化
* @Description
*/
class SingletonLazy {
//私有化构造器
private SingletonLazy() {
}
private volatile static SingletonLazy singletonLazy;
/**
* @Author mabo
* @Description 锁住方法体
*/
// public static synchronized SingletonLazy getInstance(){
// if (singletonLazy==null){
// singletonLazy=new SingletonLazy();
// }
// return singletonLazy;
// }
/**
* @Author mabo
* @Description 锁住代码块,双重检查
* @Description 此方法执行效率更高
*/
public static SingletonLazy getInstance() {
if (singletonLazy == null) {
synchronized (SingletonLazy.class) {
singletonLazy = new SingletonLazy();
}
}
return singletonLazy;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
SingletonLazy instance = SingletonLazy.getInstance();
System.out.println(instance.hashCode());
}
}
}
枚举实现单例模式
/**
* @Author mabo
* @Description 枚举实现单例模式
*/
public class SingletonEnum {
enum Test {
testEnum;
public void sayTest() {
System.out.println("我是枚举的方法");
}
public Test getTestEnum() {
return testEnum;
}
}
public static void main(String[] args) {
Test test = Test.testEnum;
Test test2 = Test.testEnum;
test.sayTest();
System.out.println(test.hashCode());
System.out.println(test2.hashCode());
}
}
工厂模式
为了下面的举例
创建两种食物:汉堡和鸡肉,都实现了Food接口
public interface Food {
public void get();
}
public class Chicken implements Food{
@Override
public void get() {
System.out.println("我要一份鸡肉");
}
}
public class Hamburger implements Food {
@Override
public void get() {
System.out.println("我要一份汉堡");
}
}
简单工厂模式
简单工厂模式又称为静态工厂模式,实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
食物工厂,根据传入的参数,来决定返回什么类型的实例
public class FoodFactory {
public static Food getFood(String type) throws InstantiationException, IllegalAccessException{
if (type.equalsIgnoreCase("Chicken")) {
return Chicken.class.newInstance();
} else if (type.equalsIgnoreCase("Hamburger")) {
return Hamburger.class.newInstance();
} else {
System.out.println("找不到相应的实例化类啦!"+type);
return null;
}
}
}
方法工厂模式
- 工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。
- 将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。
//创建食物工厂
public interface FoodFactory {
public Food getFood() throws InstantiationException, IllegalAccessException;
}
//创建鸡肉工厂
public class ChickenFactory implements FoodFactory{
public Food getFood() throws InstantiationException, IllegalAccessException {
return Chicken.class.newInstance();
}
}
//创建汉堡工厂
public class HamburgerFactory implements FoodFactory {
public Food getFood() throws InstantiationException, IllegalAccessException {
return Hamburger.class.newInstance();
}
}
//测试
public class MethodFactoryTest {
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
FoodFactory factory=new ChickenFactory();
Food food = factory.getFood();
food.get();
FoodFactory factory1=new HamburgerFactory();
Food food1 = factory1.getFood();
food1.get();
}
}
原型模式
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
克隆
public class Student implements Cloneable {
private String name;
private int age;
private Prototype prototype;
public Student(String name, int age, Prototype prototype) {
this.name = name;
this.age = age;
this.prototype = prototype;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", prototype=" + prototype +
'}';
}
@Override
public Object clone() throws CloneNotSupportedException {
Student clone = (Student)super.clone();
return clone;
}
}
测试
public class ShallowTest {
public static void main(String[] args) throws CloneNotSupportedException {
Prototype prototype =new Prototype();
Student student=new Student("mabo",20, prototype);
Student student1 =(Student) student.clone();
System.out.println(student);
System.out.println(student.hashCode());
System.out.println(student1);
System.out.println(student1.hashCode());
System.out.println(student==student1);
}
}
序列化反序列化
public class Student implements Serializable{
private String name;
private int age;
private Prototype prototype;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student(String name, int age, Prototype prototype) {
this.name = name;
this.age = age;
this.prototype = prototype;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", prototype=" + prototype +
'}';
}
public Object deep(){
//序列化反序列化进行深度拷贝
ByteArrayOutputStream byteOut=null;
ObjectOutputStream objOut=null;
ByteArrayInputStream byteIn=null;
ObjectInputStream objIn=null;
try {
//序列化
byteOut=new ByteArrayOutputStream();
objOut=new ObjectOutputStream(byteOut);
objOut.writeObject(this);
//反序列化
byte[] bytes = byteOut.toByteArray();
byteIn=new ByteArrayInputStream(bytes);
objIn=new ObjectInputStream(byteIn);
Student o =(Student) objIn.readObject();
return o;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
finally {
try {
objIn.close();
byteIn.close();
objOut.close();
byteOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
测试
public class ShallowTest {
public static void main(String[] args) throws CloneNotSupportedException {
Prototype prototype =new Prototype();
Student student=new Student("mabo",20, prototype);
Student student1 =(Student) student.deep();
System.out.println(student);
System.out.println(student.hashCode());
System.out.println(student1);
System.out.println(student1.hashCode());
}
}
建造者模式
建造者(Builder)模式由产品、抽象建造者、具体建造者、指挥者等 4 个要素构成
下面以造车为例子,展示建造者模式
创建车的抽象类
public abstract class Car {
public String color;
public String size;
public abstract void setColor();
public abstract void setSize();
@Override
public String toString() {
return "{" +
"\"color\":\""+color+"\"," +
"\"size\":\""+size+"\"" +
"}";
}
}
创建黑车
public class BlackCar extends Car{
@Override
public void setColor() {
color="黑色";
}
@Override
public void setSize() {
size="四人座";
}
}
创建红车
public class RedCar extends Car{
@Override
public void setColor() {
color="红色";
}
@Override
public void setSize() {
size="双人坐";
}
}
创建导购
public class Director {
public Car getCar(Car car){
car.setColor();
car.setSize();
return car;
}
}
创建客人买车
public class Client {
public static void main(String[] args) {
Director director=new Director();
Car car = director.getCar(new BlackCar());
System.out.println("我买的车是"+car);
car = director.getCar(new BlueCar());
System.out.println("我买的车是"+car);
car = director.getCar(new RedCar());
System.out.println("我买的车是"+car);
}
}
当客人需要一个蓝车,我们无需改动其他代码,只需要创建蓝车
public class BlueCar extends Car{
@Override
public void setColor() {
color="蓝色";
}
@Override
public void setSize() {
size="单人";
}
}
适配器模式
适配器模式可以分为类适配器,对象适配器,接口适配器。
以下只展示接口适配器模式
音乐播放器接口
public interface MusicPlayer {
public void playMp3(String fileName);
public void playM4(String fileName);
public void playMav(String fileName);
}
MP3 格式适配器
public class Mp3Player implements MusicPlayer{
@Override
public void playMp3(String fileName) {
System.out.println("播放mp3文件"+fileName);
}
@Override
public void playM4(String fileName) {
}
@Override
public void playMav(String fileName) {
}
}
MP4格式适配器
public class Mp4Player implements MusicPlayer{
@Override
public void playMp3(String fileName) {
}
@Override
public void playM4(String fileName) {
System.out.println("播放mp4文件"+fileName);
}
@Override
public void playMav(String fileName) {
}
}
mav格式适配器
public class MavPlayer implements MusicPlayer {
@Override
public void playMp3(String fileName) {
}
@Override
public void playM4(String fileName) {
}
@Override
public void playMav(String fileName) {
System.out.println("播放mav文件" + fileName);
}
}
播放接口
public interface PlayMusic {
void playMusic(String fileName);
}
音乐适配器
public class MusicAdapter implements PlayMusic {
private MusicPlayer musicplayer;
private void getPlayer(String fileName) {
if (fileName.equals("mp3")) {
musicplayer = new Mp3Player();
} else if (fileName.equals("mp4")) {
musicplayer = new Mp4Player();
} else if (fileName.equals("mav")) {
musicplayer = new MavPlayer();
} else {
System.out.println("找不到适配器");
}
}
@Override
public void playMusic(String fileName) {
getPlayer(fileName);
if (musicplayer != null) {
musicplayer.playMp3(fileName);
musicplayer.playM4(fileName);
musicplayer.playMav(fileName);
}
musicplayer = null;
}
}
客户使用
public class Client {
public static void main(String[] args) {
MusicAdapter musicAdapter = new MusicAdapter();
musicAdapter.playMusic("mp3");
musicAdapter.playMusic("mp4");
musicAdapter.playMusic("mav");
musicAdapter.playMusic("23");
}
}
测试结果