一.单例模式
饿汉式:不会出现问题的单例,类一加载就会创建创建当前类
懒汉式:可能出现问题的单例:-------->考虑线程安全 延迟加载/懒加载
(当在使用的时候才创建当前类对象)
1.1单例模式之懒汉式
单例模式懒汉式:
前提: 1.当前类是一个具体类
2.当前成员变量位置:仅仅声明一个当前类型变量,没有创建对象(私有修饰) 3.无参构造函数私有化
4.对外界体统静态的公共方法,返回值是当前类本身,用的时候才创建对象 * * 懒汉式的问题:线程安全的问题(延迟加载)---->加锁
需要在静态方法中加入----->同步锁
1.1.1例子
public class TeacherDemo {
private static TeacherDemo t1 =null;//成员变量:私有的静态变量t:类型 Teacher
private TeacherDemo(){} //无参构造私有化:外界不能去new
//对外提供公共静态方法,返回值是当前类本身
public synchronized static TeacherDemo getTeacherDemo(){
if(t1==null){
t1=new TeacherDemo(); //没有对象,这个时候才去new 对象
}
return t1;
}
}
public class TeacherTest {
public static void main(String[] args) {
TeacherDemo teacherDemo=TeacherDemo.getTeacherDemo();
System.out.println(teacherDemo);
}
}
1.2单例模式之饿汉式
饿汉式:eg:runtime *
前提条件:
1.当前类是一个具体的类
2.类的无参构造方法私有化
3.在成员变量位置:提供一个当前类的静态实例变量
4.提供静态功能,当前这个方法返回值是当前类本身
jdk提供的Runtime这个类就是饿汉式:类一加载就创建当前类对象
1.2.1例子
public class Student {//具体类.类一加载就创建当前类的对象
private static Student s=new Student();//创建当前类对象,静态私有化
private Student(){}//无参构造方法私有化
public static Student getStudent(){//提供静态功能,返回值是当前类本身
return s;
}
public class SingleTest {
public static void main(String[] args) {
Student student=Student.getStudent();
System.out.println(student);
Student ss=Student.getStudent();
System.out.println(ss);
System.out.println(ss.equals(student));
}
}
二.代理模式
(一)静态代理
静态代理:
静态代理最大的特点:代理角色和真实角色需要完成实现同一个接口
代理角色;帮助真实完成一件事情
真实角色:专注于自己的主要的事情
public class StaticIntorduce {
public static void main(String[] args) {
//创建婚亲公司===>类似于线程创建方式2 thread:d代理角色
You you=new You();
WeddingCompare weddingCompare=new WeddingCompare(you);
weddingCompare.marry();
}
}
//定义接口
interface Marry{
void marry();
}
//真实角色You
class You implements Marry {
@Override
public void marry() {
System.out.println("结婚很开心");
}
}
//代理角色:婚庆公司:帮助完成婚礼的设计
class WeddingCompare implements Marry {
private Marry marry;//声明接口类型
public WeddingCompare(Marry marry) {
this.marry = marry;
}
@Override
public void marry() {//真实角色
System.out.println("结婚之前要布置线程");
if(marry!=null){
marry.marry();
}
System.out.println("结婚之后,要收尾款");
}
}
(二)动态代理
动态代理 JDK代理--->jdk提供的java.lang.reflect .proxy 前提:必须有接口 cglib:代理---->Spring(导入第三方的cglib.jar包) 基于子类实现的 java.lang.reflect.Proxy---->通过反射 完成接口中的方法调用 静态功能 返回值就是代表创建接口的子实现类对象(代理角色) public static Object newProxyInstance( ClassLoader loader, 当前接口的类加载器 Class<?>[] interfaces, 当前的代理的接口列表数组 InvocationHandler h) 代理的指派的处理程序(就像增删改查方法) throws IllegalArgumentException Proxy提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。 为某个接口创建代理Foo : Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class<?>[] { Foo.class }, handler);
1.创建接口,定义一些方法
public interface UserDao {
void add();
void update();
void delete();
void select();
}
2.创建接口的子实现类,来实现接口的方法
package com.qf.Proxy_DaiLI.proxy_DongTai;
public class UserDaoImpl implements UserDao {
@Override
public void add() {
System.out.println("添加用户");
}
@Override
public void update() {
System.out.println("gengxin");
}
@Override
public void delete() {
System.out.println("删除");
}
@Override
public void select() {
System.out.println("查询所有");
}
}
3.自定义一个类来实现InvocationHandler
/**自定义一个类 来实现InvocationHandler:代理的指派的处理程序(本次就是指的是增删改查)
* 这个类目的:调用接口中的方法 add()/update()/delelte()/findAll()
*
*/
public class MyInvocationHnader implements InvocationHandler {
private Object target;//任意的java类型(对真实角色)
//创建一个有参构造函数
public MyInvocationHnader(Object target) {
this.target = target;
}
/**
* Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
* new Class<?>[] { Foo.class },
* handler);
* @param proxy:代理的实例:eg ud2
* @param method:调用处理接口方法所在类对象Method(add()/update()/delelte()/findAll())
* @param args 实际参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("权限校验"); //系统监控代码
//真实角色调用自己的方法
Object obj = method.invoke(target, args); // 调用这些方法,如果有返回值,返回Object(返回任意类型)
System.out.println("产生日志");//系统监控代码
return obj;
}
}
4.主类
public class JDK_proxy {
public static void main(String[] args) {
//没有使用代理模式之前的的方法
UserDao ud=new UserDaoImpl();
ud.add();
ud.delete();
ud.select();
ud.update();
System.out.println("没有使用代理模式之前的的方法 ");
//加入权限校验,产生日志
UserDao ud2=new UserDaoImpl2();
ud2.update();
ud2.add();
ud2.delete();
ud2.select();
System.out.println("------核心代码和功能没有分离--------");
/**上面这个代码ud2调用所有功能,不太合适,写死了,核心代码:CRUD和权限校验/产生日志写在一起,没有分离
* 借助于jdk提供的Proxy的静态方法,完成代理类的产生---->代理角色 :相当于UserDaoImpl2
* 前提接口:UserDao ---- UserDao ud = new UserDaoIml() ;
* Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
* new Class<?>[] { Foo.class },
* handler);
*
* hander;自定义一个类,实现接口InvocationHandler;代理处理指派程序
* 就是实现增删改查
*/
//创建MyInvocationHandler
MyInvocationHnader handler = new MyInvocationHnader(ud);
UserDao ud3 = (UserDao) Proxy.newProxyInstance(
ud.getClass().getClassLoader(),
//通过字节码文件对象 调用 public Class<?>[] getInterfaces()
ud.getClass().getInterfaces(),
handler
); //代理实例
ud3.add();
System.out.println("==========");
ud3.update();
System.out.println("==========");
ud3.delete();
System.out.println("==========");
ud3.select();
}
}
总结
java的设计模式有很多种,这是其中的两种,如果那里写的不对的话,请大家多多指教.
无须注意别人的言论,做好自己的事情就好.