单例设计模式:
package com.xiaowei.designpattern;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
public class SingletonTest {
/**
* 定义:
* 保证每一个类只有一个实例,并且提供一个全局访问点
* 场景:
* 重量级的对象,不需要多个实例,如线程池、数据库连接池
* 类图:
* 私有属性、私有构造函数,公有的访问点
* @throws SecurityException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws IOException
* @throws FileNotFoundException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, FileNotFoundException, IOException, ClassNotFoundException {
// new Thread(() -> {
// LazySingleton instance = LazySingleton.getInstance();
// System.out.println(instance);
// }).start();
// new Thread(() -> {
// LazySingleton instance = LazySingleton.getInstance();
// System.out.println(instance);
// }).start();
// 反射进行攻击
// Constructor<InnerClassSingleton> declaredConstructor = InnerClassSingleton.class.getDeclaredConstructor();
// declaredConstructor.setAccessible(true);
// InnerClassSingleton newInstance = declaredConstructor.newInstance();
// InnerClassSingleton instance = InnerClassSingleton.getInstance();
// System.out.println(newInstance == instance);
// EnumSingleTom instance = EnumSingleTom.INSTANCE;
InnerClassSingleton instance = InnerClassSingleton.getInstance();
// 序列化
// ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("test"));
// objectOutputStream.writeObject(instance);
// objectOutputStream.close();
// ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test"));
// InnerClassSingleton innerClassSingleton = (InnerClassSingleton)(ois.readObject());
// ois.close();
// System.out.println(objectOutputStream == ois);
}
}
/**
* 饿汉式单例
*/
class HungrySingleton {
/**
* 类加载的初始化阶段就完成了实例的初始化,本质上还是借助于jvm类加载机制,保证实例的唯一性。
* 类加载过程:
* 1、加载二进制数据到内存中,生成对应的Class数据结构
* 2、连接: a.验证 b.准备(给类的静态成员变量赋默认值) c.解析
* 3、初始化: 给类的静态变量赋初值
* 只有在真正使用对应的类时,才会触发初始化,如(当前类是启动类即main函数所在类,直接进行new操作
* 访问静态属性,静态方法,用发射访问类,初始化一个类的子类等等)
*/
private static HungrySingleton sInstance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return sInstance;
}
}
/**
* 枚举
*/
enum EnumSingleTom {
INSTANCE;
public void print() {}
}
/**
* 静态内部类
* 1、本质上还是利用类的加载机制来保证线程安全
* 2、只有在实际使用的时候才会触发类的初始化,所以也是懒汉式的一种形式
*
*/
class InnerClassSingleton implements Serializable {
// 序列化和反序列化需要版本号
private static final long serialVersionUID = 1L;
private InnerClassSingleton() {
if (InnerClassHolder.sIntance != null) {
throw new RuntimeException(" 单例不允许多个实例 ");
}
}
public static InnerClassSingleton getInstance() {
return InnerClassHolder.sIntance;
}
private static class InnerClassHolder {
private static InnerClassSingleton sIntance = new InnerClassSingleton();
}
// 解决jvm内部没有执行此构造函数的问题
Object readResolve() throws ObjectStreamException{
return InnerClassHolder.sIntance;
}
}
/**
* 懒汉式单例
*/
class LazySingleton {
// volatile:不会发生重排序
private volatile static LazySingleton sInstance;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (sInstance == null) {
// 加锁 T1 T2 多个线程在这里发生并发,也存在性能的损耗
synchronized (LazySingleton.class) {
if (sInstance == null) {
sInstance = new LazySingleton();
// 字节码层面发生什么事情?
// JIT:即时编译, cpu, 有可能对指令进行重排序,导致使用到未初始化的实例
// javap -v -p x.class
//1、分配空间 2、初始化 3、给引用赋值 2和3可置换顺序
}
}
}
return sInstance;
}
}
工厂设计模式:
package com.xiaowei.designpattern;
/**
* 工厂设计模式 对扩展开放,对修改关闭 开闭原则,也符合单一职责原则
*/
public class FactoryModeTest {
public static void main(String[] args) {
IDataBaseUtils iDataBaseUtils = new OracleUtils();
IConnection connection = iDataBaseUtils.getConnection();
connection.connect();
ICommand command = iDataBaseUtils.getCommand();
command.command();
}
}
/**
* 工厂设计模式 定义一个用于创建对象的接口,在子类去决定实例化哪个类。工厂模式使用一个类的实例化延迟到子类。
* 应用场景
* 1、当你不知道该使用对象的确切类型的时候 2、当你希望为库或者框架提供扩展其内部组件的方法时
*
* 主要优点 1、将具体产品和创建者解耦 2、符合单一职责原则 3、符合开闭原则 静态工厂: Calendar.getInstance()
* java.text.NumberFormat.getInstance() java.util.ResourceBundle.getInstance()
* 工厂方法: java.net.URLStreamHandlerFactory
* javax.xml.bind.JAXBContext.createMarshaller
*/
/**
* 抽象工厂模式
* 提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类
* 应用场景:
* 程序需要处理不同系统的相关产品,但是你又不需要它依赖于这些产品的具体类时,可以使用抽象工厂
* 优点:
* 1、可以确信你从工厂得到的产品彼此时兼容的
* 2、可以避免具体产品和客户端代码直接的紧密耦合
* 3、符合单一职责原则
* 4、符合开闭原则
**/
// 未来变化的部分: sql oracle
// 不变的部分:connection,command,sql语句
interface IConnection {
void connect();
}
class MysqlConnection implements IConnection {
@Override
public void connect() {
System.out.println("mysql connection");
}
}
class OracleConnection implements IConnection {
@Override
public void connect() {
System.out.println("oracle connection");
}
}
interface ICommand {
void command();
}
class MysqlCommand implements ICommand {
@Override
public void command() {
System.out.println("mysql command");
}
}
class OracleCommand implements ICommand {
@Override
public void command() {
System.out.println("oracle command");
}
}
interface IDataBaseUtils {
IConnection getConnection();
ICommand getCommand();
}
class MySqlUtils implements IDataBaseUtils {
@Override
public IConnection getConnection() {
return new MysqlConnection();
}
@Override
public ICommand getCommand() {
return new MysqlCommand();
}
}
class OracleUtils implements IDataBaseUtils {
@Override
public IConnection getConnection() {
return new OracleConnection();
}
@Override
public ICommand getCommand() {
return new OracleCommand();
}
}
建造者设计模式:
package com.xiaowei.designpattern;
import com.xiaowei.designpattern.Product.Builder;
public class BuilderModeTest {
public static void main(String[] args) {
ProductBuilder builder = new ConcreateProductBuilder();
Director director = new Director(builder);
// Product product = director.makeProduct("xx","...com", "part1", "part2", "part3", "part4");
// System.out.println(product);
// psvm 快捷键
Product product = new Product.Builder().companyName(".com").productName("xxx").part1("part1").builder();
System.out.println(product);
}
}
interface ProductBuilder {
void builderProductName(String productName);
void builderCompanyName(String conpanyName);
void builderPart1(String part1);
void builderPart2(String part2);
void builderPart3(String part3);
void builderPart4(String part4);
Product builder();
}
class ConcreateProductBuilder implements ProductBuilder {
private String productName;
private String conpanyName;
private String part1;
private String part2;
private String part3;
private String part4;
@Override
public void builderProductName(String productName) {
this.productName = productName;
}
@Override
public void builderCompanyName(String conpanyName) {
this.conpanyName = conpanyName;
}
@Override
public void builderPart1(String part1) {
this.part1 = part1;
}
@Override
public void builderPart2(String part2) {
this.part2 = part2;
}
@Override
public void builderPart3(String part3) {
this.part3 = part3;
}
@Override
public void builderPart4(String part4) {
this.part4 = part4;
}
@Override
public Product builder() {
return new Product(this.productName, this.conpanyName,this.part1,this.part2,this.part3,this.part4);
}
}
class Director {
private ProductBuilder builder;
public Director(ProductBuilder builder) {
this.builder = builder;
}
public Product makeProduct(String productName,String companyName, String part1,String part2,String part3,String part4) {
builder.builderProductName(productName);
builder.builderCompanyName(companyName);
builder.builderPart1(part1);
builder.builderPart2(part2);
builder.builderPart3(part3);
builder.builderPart4(part4);
return builder.builder();
}
}
class Product{
private final String productName;
private final String conpanyName;
private final String part1;
private final String part2;
private final String part3;
private final String part4;
public Product(String productName, String conpanyName, String part1, String part2, String part3, String part4) {
this.productName = productName;
this.conpanyName = conpanyName;
this.part1 = part1;
this.part2 = part2;
this.part3 = part3;
this.part4 = part4;
}
static class Builder {
private String productName;
private String companyName;
private String part1;
private String part2;
private String part3;
private String part4;
public Builder productName(String productName) {
this.productName = productName;
return this;
}
public Builder companyName(String companyName) {
this.companyName = companyName;
return this;
}
public Builder part1(String part1) {
this.part1 = part1;
return this;
}
public Builder part2(String part2) {
this.part2 = part2;
return this;
}
public Builder part3(String part3) {
this.part3 = part3;
return this;
}
public Builder part4(String part4) {
this.part4 = part4;
return this;
}
Product builder() {
return new Product(productName, companyName, part1, part2, part3, part4);
}
}
@Override
public String toString() {
return "Product [productName=" + productName + ", conpanyName=" + conpanyName + ", part1=" + part1 + ", part2="
+ part2 + ", part3=" + part3 + ", part4=" + part4 + "]";
}
}