Java常用设计模式

 

目录

一、单例模式

1、枚举实现

2、饿汉式

2.1 代码实现

2.2 JDK源码使用示例

3、懒汉式(双重检查加锁)

4、静态内部类实现懒汉式 

二、策略模式

1、Comparator接口实现示例

三、工厂模式  

1、简单工厂/静态工厂

2、工厂方法

3、抽象工厂

四、动态代理

1、设置vm参数保存jdk生成的代理类

2、示例代码

3、jdk生成的代理类代码


一、单例模式

参考博客:https://www.cnblogs.com/happy4java/p/11206105.html

1、枚举实现

/**
 * 枚举类实现单例模式,保证单一性和线程安全
 * @author DELL
 *
 */
public enum Singleton1 {

	/**
	 * 单例变量
	 */
	INSTANCE;
	
	public void doSomething() {
		System.out.println("do something ...");
	}
	
	/**
	 * 程序入口
	 * @param args
	 */
	public static void main(String[] args) {
		Singleton1.INSTANCE.doSomething();
	}
}

2、饿汉式

2.1 代码实现

/**
 * 饥汉模式
 * @author DELL
 *
 */
public class Singleton2 {

	/**
	 * 初始化直接创建单例
	 */
	private static final Singleton2 instance = new Singleton2();
	
	/**
	 * 构造器私有化
	 */
	private Singleton2() {
	}

	/**
	 * 获取单例接口
	 * @return
	 */
	public static Singleton2 getInstance() {
		return instance;
	}
	
	
	/**
	 * 程序入口
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(Singleton2.getInstance().hashCode());
		
		System.out.println(Singleton2.getInstance().hashCode());
	}

}

2.2 JDK源码使用示例

Runtime类

3、懒汉式(双重检查加锁)

/**
 * 懒汉模式
 * @author DELL
 *
 */
public class Singleton3 {

	/**
	 * 初始化不创建单例
	 */
	private static volatile Singleton3 instance;
	
	/**
	 * 构造器私有化
	 */
	private Singleton3() {
	}

	/**
	 * 获取单例接口,双重检查加锁,保证线程安全
	 * @return
	 */
	public static Singleton3 getInstance() {
		if(null == instance) {
			synchronized (Singleton3.class) {
				if(null == instance) {
					instance = new Singleton3();
				}
			}
		}
		return instance;
	}
	
	
	/**
	 * 程序入口
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(Singleton3.getInstance().hashCode());
		
		System.out.println(Singleton3.getInstance().hashCode());
	}

}

4、静态内部类实现懒汉式 

/**
 * 静态内部类实现单例
 * @author DELL
 *
 */
public class Singleton4 {
	
	/**
	 * 静态内部类只会初始化一次,线程安全懒加载
	 * @author DELL
	 *
	 */
	public static class Inner{
		/**
		 * 单例对象初始化放到静态内部类中
		 */
		private static Singleton4 instance = new Singleton4();
	}
	
	/**
	 * 构造器私有化
	 */
	private Singleton4(){
	}
	
	/**
	 * 获取单例对象
	 * @return
	 */
	public Singleton4 getInstance() {
		return Inner.instance;
	}
	
	/**
	 * 程序入口
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(Inner.instance);
	}

}

二、策略模式

1、Comparator接口实现示例

 按照不同策略给Dog对象排序,sort方法传入不同比较器即可

策略1使用匿名内部类实现Comparator接口创建对象

策略2使用lambda表达式实现Comparator接口创建对象

策略3使用lambda表达式实现Comparator接口创建对象

import java.util.Arrays;
import java.util.Comparator;

public class Strategy {

	public static void main(String[] args) {
		Dog[] ds = {new Dog(1, 5), new Dog(3, 4), new Dog(2, 6)};
		
		/**
		 * 按体重排序,从小到大
		 */
		Arrays.sort(ds, new Comparator<Dog>() {
			@Override
			public int compare(Dog o1, Dog o2) {
				return o1.weight - o2.weight;
			}
		});
		System.out.println("按体重正序排序: "+ Arrays.toString(ds));
		
		/**
		 * 按身高排序,从小到大
		 */
		Arrays.sort(ds, (Dog o1, Dog o2) -> {
			return o1.height - o2.height;
		});
		System.out.println("按身高正序排序: "+ Arrays.toString(ds));
		
		/**
		 * 按体重加身高排序,从小到大
		 */
		Arrays.sort(ds, (Dog o1, Dog o2) -> (o1.weight + o1.height) - (o2.weight + o2.height));
		System.out.println("按体重加身高正序排序: "+ Arrays.toString(ds));
	}

}

class Dog{
	public int weight;
	public int height;
	
	public Dog(int weight, int height) {
		super();
		this.weight = weight;
		this.height = height;
	}

	@Override
	public String toString() {
		return "Dog [weight=" + weight + ", height=" + height + "]";
	}
	
}

三、工厂模式  

参考博客:https://blog.csdn.net/A1342772/article/details/91349142

产品类实现代码 

interface Product {
	void show();
}

class ProductA implements Product {

	@Override
	public void show() {
		System.out.println("产品A");
	}
}

class ProductB implements Product {

	@Override
	public void show() {
		System.out.println("产品B");
	}
}

1、简单工厂/静态工厂

简单工厂代码:

/**
 * Simple Factory
 * @author DELL
 *
 */
public class SimpleFactory {
	
	public Product createProductA() {
		return new ProductA();
	}
	
	public Product createProductB() {
		return new ProductB();
	}

	/**
	 * main方法
	 * @param args
	 */
	public static void main(String[] args) {
		
		Product p1 = new SimpleFactory().createProductA();
		p1.show();
		
		Product p2 = new SimpleFactory().createProductB();
		p2.show();
	}
}

 静态工厂代码:

/**
 * Static Factory
 * @author DELL
 *
 */
public class StaticFactory {

	/**
	 * createProduct
	 * @param productType
	 * @return
	 */
	public static Product createProduct(String productType) {
		Product product = null;
		if("A".equals(productType)) {
			product = new ProductA();
		}else if("B".equals(productType)) {
			product = new ProductB();
		}
		return product;
	}

	/**
	 * main方法
	 * @param args
	 */
	public static void main(String[] args) {
		
		Product p1 = StaticFactory.createProduct("A");
		p1.show();
		
		Product p2 = StaticFactory.createProduct("B");
		p2.show();
	}
}

说明:当工厂类的生产方法被声明为静态方法时,也可称之为静态工厂

简单工厂/静态工厂:将创建产品过程封装到工厂类的创建方法中。

缺点:新增产品后,需要修改工厂类的创建方法

2、工厂方法

工厂方法代码:

/**
 * Factory Method
 * @author DELL
 *
 */
public class FactoryMethod {
	/**
	 * main
	 * @param args
	 */
	public static void main(String[] args) {
		Product p1 = new FactoryA().create();
		p1.show();

		Product p2 = new FactoryB().create();
		p2.show();
	}
}

interface Factory {
	Product create();
}

class FactoryA implements Factory {
	@Override
	public Product create() {
		return new ProductA();
	}
}

class FactoryB implements Factory {
	@Override
	public Product create() {
		return new ProductB();
	}
}

说明:工厂方法将具体产品的创建推迟到子类,由具体工厂实现创建产品过程

优点:新增产品后,只需要新增对应具体工厂即可

缺点:具体产品与具体工厂耦合,创建产品时需要创建具体工厂

3、抽象工厂

 主要针对产品族的扩展,新增产品族时,只需要新增工厂即可

Food接口对象与Cloth接口对象组成一个产品集合,同一系列的产品成为一个产品族

/**
 * Abstract Factory
 * @author DELL
 *
 */
public abstract class AbstractFactory {
	abstract Food CreateFood();
	abstract Cloth CreateCloth();

	public static void main(String[] args) {
		System.out.println("创建A族产品:");
		AbstractFactory fA = new AFactory();
		Food foodA = fA.CreateFood();
		foodA.eat();
		Cloth clothA = fA.CreateCloth();
		clothA.use();
		
		System.out.println("创建B族产品:");
		AbstractFactory fB = new BFactory();
		Food foodB = fB.CreateFood();
		foodB.eat();
		Cloth clothB = fB.CreateCloth();
		clothB.use();
	}

}

/**
 * A工厂,生产A族系列产品
 * @author DELL
 *
 */
class AFactory extends AbstractFactory{
	@Override
	Food CreateFood() {
		return new FoodA();
	}

	@Override
	Cloth CreateCloth() {
		return new ClothA();
	}
}

/**
 * B工厂,生产B族系列产品
 * @author DELL
 *
 */
class BFactory extends AbstractFactory{
	@Override
	Food CreateFood() {
		return new FoodB();
	}

	@Override
	Cloth CreateCloth() {
		return new ClothB();
	}
}
/**
 * Food接口
 * @author DELL
 *
 */
interface Food{
	void eat();
}

/**
 * Cloth接口
 * @author DELL
 *
 */
interface Cloth{
	void use();
}

/**
 * Food A系列
 * @author DELL
 *
 */
class FoodA implements Food{

	@Override
	public void eat() {
		System.out.println("A吃法");
	}
}

/**
 * Cloth A系列
 * @author DELL
 *
 */
class ClothA implements Cloth{

	@Override
	public void use() {
		System.out.println("A用法");
	}
}

/**
 * Food B系列
 * @author DELL
 *
 */
class FoodB implements Food{

	@Override
	public void eat() {
		System.out.println("B吃法");
	}
}

/**
 * Cloth B系列
 * @author DELL
 *
 */
class ClothB implements Cloth{

	@Override
	public void use() {
		System.out.println("B用法");
	}
}

四、动态代理

1、设置vm参数保存jdk生成的代理类

-Dsun.misc.ProxyGenerator.saveGeneratedFiles=true

2、示例代码

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author DELL
 * @date 2020/7/25
 */
public class MyProxy {
    public static void main(String[] args) {

        // 要代理的目标类
        AA aa = new AA();

        // jdk生成的代理类对象
        // 传入目标类的类加载器,传入目标类实现的接口,匿名内部类实现调用控制器
        A a = (A) Proxy.newProxyInstance(AA.class.getClassLoader(), new Class[]{A.class}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("before do something...");

                // 传入目标类对象,调用目标类方法
                Object o = method.invoke(aa, args);

                System.out.println("after do something...");
                return o;
            }
        });

        a.show();
    }
}

interface A {
    void show();
}

class AA implements A {

    @Override
    public void show() {
        System.out.println("running AA.show()");
    }
}

3、jdk生成的代理类代码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.java.demo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

final class $Proxy0 extends Proxy implements A {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void show() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("com.java.demo.A").getMethod("show");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值