一:什么是设计模式
设计模式(Design pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。
二:设计模式的分类
设计模式分为三大类共23种
(1)创建型模式,共五种
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
(2)结构型模式,共七种
适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
(3)行为型模式,共十一种
策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
三:常用的设计模式
(1)单例模式
单例模式:指的是一个类只允许产生一个实例化对象,常见的单例模式懒汉式和饿汉式。
懒汉式:线程不安全,只有需要的时候才去实例化对象。
class SingletonTest {
public static void main(String[] args) {
Singleton sl1 = Singleton.getSingleton();
Singleton sl2 = Singleton.getSingleton();
System.out.println(sl1 == sl2);
}
}
public class Singleton {
// 当需要的才会被实例化
private static Singleton singleton;
private Singleton() {
}
synchronized public static Singleton getSingleton() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
双重检验锁
// 懒汉式 第二种写法 效率高 双重检验锁
static public Singleton getSingleton2() {
if (singleton == null) { // 第一步检验锁
synchronized (Singleton.class) { // 第二步检验锁
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
饿汉式:线程安全,类加载的时候就已经创建了实例化对象。
class SingletonTest1 {
public static void main(String[] args) {
Singleton1 sl1 = Singleton1.getSingleton();
Singleton1 sl2 = Singleton1.getSingleton();
System.out.println((sl1 == sl2)+"-");
}
}
public class Singleton1 {
//当class 文件被加载初始化
private static Singleton1 singleton = new Singleton1();
private Singleton1() {
}
public static Singleton1 getSingleton() {
return singleton;
}
}
(2)工厂模式
工厂模式:实现创建者和调用者分离。
interface Car {
void run();
}
class AoDi implements Car {
@Override
public void run() {
System.out.println("我是奥迪....");
}
}
class BenChi implements Car {
@Override
public void run() {
System.out.println("我是奔驰....");
}
}
class CarFactory {
public static Car createCar(String name) {
Car car = null;
switch (name) {
case "奥迪":
car = new AoDi();
break;
case "奔驰":
car = new BenChi();
break;
default:
break;
}
return car;
}
}
public class Test002 {
public static void main(String[] args) {
Car car = CarFactory.createCar("奔驰");
car.run();
}
}
(3)代理模式
代理模式:指给一个对象提供一个代理对象,并由代理对象控制对原对象的引用。代理可以分为静态代理和动态代理。
静态代理需要自己生成代理类
public class XiaoMing implements Hose {
@Override
public void mai() {
System.out.println("我是小明,我要买房啦!!!!haha ");
}
}
class Proxy implements Hose {
private XiaoMing xiaoMing;
public Proxy(XiaoMing xiaoMing) {
this.xiaoMing = xiaoMing;
}
public void mai() {
System.out.println("我是中介 看你买房开始啦!");
xiaoMing.mai();
System.out.println("我是中介 看你买房结束啦!");
}
public static void main(String[] args) {
Hose proxy = new Proxy(new XiaoMing());
proxy.mai();
}
}
动态代理不需要生成代理类(jdk动态代理和cglib动态代理)
jdk动态代理
public class JDKProxy implements InvocationHandler {
private Object tarjet;
public JDKProxy(Object tarjet) {
this.tarjet = tarjet;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是房产中介.....开始监听你买房啦!");
Object oj = method.invoke(tarjet, args);
System.out.println("我是房产中介.....结束监听你买房啦!");
return oj;
}
}
class Test222 {
public static void main(String[] args) {
XiaoMing xiaoMing = new XiaoMing();
JDKProxy jdkProxy = new JDKProxy(xiaoMing);
Hose hose=(Hose) Proxy.newProxyInstance(xiaoMing.getClass().getClassLoader(), xiaoMing.getClass().getInterfaces(), jdkProxy);
hose.mai();
}
}
cglib动态代理
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class Cglib implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("我是买房中介 , 开始监听你买房了....");
Object invokeSuper = methodProxy.invokeSuper(o, args);
System.out.println("我是买房中介 , 开结束你买房了....");
return invokeSuper;
}
}
class Test22222 {
public static void main(String[] args) {
Cglib cglib = new Cglib();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(XiaoMing.class);
enhancer.setCallback(cglib);
Hose hose = (Hose) enhancer.create();
hose.mai();
}
}