Java进阶13讲__补充2/2

1.  设计模式

1.1  什么是设计模式

1.2  单例设计模式

package com.itheima.a_单例_饿汉式;

public class T1 {
    public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                Demo demo = Demo.createDemo();
                System.out.println(Thread.currentThread() + "::" + demo);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                Demo demo1 = Demo.createDemo();
                System.out.println(Thread.currentThread() + "::" + demo1);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                Demo demo1 = Demo.createDemo();
                System.out.println(Thread.currentThread() + "::" + demo1);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                Demo demo1 = Demo.createDemo();
                System.out.println(Thread.currentThread() + "::" + demo1);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                Demo demo1 = Demo.createDemo();
                System.out.println(Thread.currentThread() + "::" + demo1);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                Demo demo1 = Demo.createDemo();
                System.out.println(Thread.currentThread() + "::" + demo1);
            }
        }).start();
    }
}

class Demo {
    private static final Demo demo = new Demo();

    public static final Demo createDemo() {
        return demo;
    }

    private Demo() {
    }

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

1.3  懒汉式单例设计模式

package com.itheima.b_单例_懒汉式;

/*
单例设计模式
    作用:确保一个类只有一个对象。
    场景:计算机中的回收站、任务管理器、Java中的Runtime类等

懒汉式(第一次获取时创建对象)
    把类的构造器私有(保证别人不能new)
    在类中定义一个类变量用于存储对象(注意:此时只定义,不创建)
    提供一个类方法,在方法中创建并返回对象(要保证只创建一次)

注意
    获取方法需要使用synchronized修饰,以保证只有一个线程可以成功创建出对象
*/
public class Demo {
    //在类中定义一个类变量用于存储对象(注意:此时只定义,不创建)
    private static volatile Demo demo;

    //提供一个类方法,在方法中创建并返回对象(要保证只创建一次)
    public static Demo createDemo() {
        if (demo == null) {
            synchronized (Demo.class) {
                if (demo == null) {
                    demo = new Demo();
                }
            }
        }
        return demo;
    }

    //把类的构造器私有(保证别人不能new)
    private Demo() {
    }
}
package com.itheima.b_单例_懒汉式;

public class T1 {
    public static void main(String[] args) {
        while (true) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Demo demo = Demo.createDemo();
                    System.out.println(Thread.currentThread() + "::" + demo);
                }
            }).start();
        }


    }
}

1.4  枚举实现单例模式

package com.itheima.c_单例_枚举实现;

import java.sql.SQLOutput;

/*
单例设计模式
    作用:确保一个类只有一个对象。
    场景:计算机中的回收站、任务管理器、Java中的Runtime类等

枚举实现单例
    直接在枚举中提供一个枚举项就可以实现单例

注意
    Google首席Java架构师、(Effective Java》 一书作者Java集合框架的开创者Joshua Bloch在Effective Java一书中提到
        单元素的枚举类型,已经成为实现singleton的最佳方法
        在这种实现方式中,既可以避免多线程同步问题
        还可以防止通过反射和反序列化来重新创建新的对象
        在很多优秀的开源代码中,我们经常可以看到使用枚举方式来实现的单例模式类
*/
public class Demo {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Animal.SunQing.hashCode());
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Animal.SunQing.hashCode());
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Animal.SunQing.hashCode());
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Animal.SunQing.hashCode());
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Animal.SunQing.hashCode());
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Animal.SunQing.hashCode());
            }
        }).start();
    }
}
enum Animal{
    SunQing
}

2.  动态代理

2.1  入门案例 

ProxyUtil.java

package com.itheima.d_动态代理_入门;

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

/**
 * 代理工具类,生成代理对象
 */
public class ProxyUtil {
    /**
     * 创建zxr代理对象
     *
     * @return
     */
    public static Star returnObject(Star item) {
        //获取被代理类对象//参数传入
        //编写代理类业务逻辑
        InvocationHandler handler = new InvocationHandler() {
            /**
             * @param proxy  生成的代理对象
             * @param method 调用代理对象的方法名字
             * @param args   参数
             * @return
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                String methodName = method.getName();
                if (methodName.equals("sing")) {
//                执行method唱歌
                    System.out.println("经纪人准备话筒,收钱");
                    Object obj = method.invoke(item, args);
                    return obj;
                } else {
//                执行method跳舞
                    System.out.println("经纪人准备场地,收钱");
                    Object obj = method.invoke(item, args);
                    return obj;
                }
            }
        };
        //生成代理类对象
        Object obj = Proxy.newProxyInstance(
                item.getClass().getClassLoader(),
                item.getClass().getInterfaces(),
                handler
        );
        //返回代理类对象
        return (Star) obj;
    }
}

Star.interface

package com.itheima.d_动态代理_入门;

//明星接口
public interface Star {
    String sing(String name);

    /**
     * 跳舞
     */
    void dancing();
}

ZXR.java

package com.itheima.d_动态代理_入门;

//Sakream实现类
public class ZXR implements Star {

    @Override
    public String sing(String name) {
        System.out.println("zxr开始唱歌,歌名:" + name);
        return name;
    }

    @Override
    public void dancing() {
        System.out.println("zxr开始跳舞");
    }
}

Test.java

package com.itheima.d_动态代理_入门;

public class Test {
    public static void main(String[] args) {
//        创建被代理对象
        ZXR zxr = new ZXR();
//        创建代理对象
        Star star = ProxyUtil.returnObject(zxr);
//        调用代理对象干活
        star.sing("罗生门");
        star.dancing();
    }
}

2.2  业务案例

UserService.interface

package com.itheima.e_动态代理_案例;

/**
 * 用户业务接口
 */
public interface UserService {
    // 登录功能
    void login(String loginName, String passWord) throws Exception;

    // 删除用户
    void deleteUsers() throws Exception;

    // 查询用户,返回数组的形式。
    String[] selectUsers() throws Exception;
}

UserServiceImpl.java

package com.itheima.e_动态代理_案例;

/**
 * 用户业务实现类
 */
public class UserServiceImpl implements UserService {
    @Override
    public void login(String loginName, String passWord) throws Exception {
        if ("admin".equals(loginName) && "123456".equals(passWord)) {
            System.out.println("您登录成功,欢迎光临本系统~");
        } else {
            System.out.println("您登录失败,用户名或密码错误~");
        }
        Thread.sleep(1000);
    }

    @Override
    public void deleteUsers() throws Exception {
        System.out.println("成功删除了1万个用户~");
        Thread.sleep(1500);
    }

    @Override
    public String[] selectUsers() throws Exception {
        System.out.println("查询出了3个用户");
        String[] names = {"张全蛋", "李二狗", "牛爱花"};
        Thread.sleep(500);
        return names;
    }
}

ProxyUtils.java

package com.itheima.e_动态代理_案例;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Date;

public class ProxyUtils {
    public static UserService createProxy(UserService impl) {
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                调用代理对象的名字
                String methodName = method.getName();
//                计时
                long begin = System.currentTimeMillis();
//                执行方法
                if (methodName.equals("login")) {
//                    记录用户登录日志
                    System.out.println(new Date() + "--" + Arrays.toString(args) + "用户登录了");
                }
                Object obj = method.invoke(impl, args);
//                结束
                long end = System.currentTimeMillis();
                long longTime = end - begin;
                System.out.println(methodName + "方法执行了:[" + longTime + "毫秒]");
                return obj;
            }
        };
        UserService us = (UserService) Proxy.newProxyInstance(
                impl.getClass().getClassLoader(),
                impl.getClass().getInterfaces(),
                invocationHandler
        );
        return us;
    }
}

Test.java

package com.itheima.e_动态代理_案例;

import java.util.Arrays;

/**
 * 目标:使用动态代理解决实际问题,并掌握使用代理的好处。
 */
public class Test {
    public static void main(String[] args) throws Exception {
        // 1、创建用户业务对象
        UserService userService = new UserServiceImpl();
        UserService proxy = ProxyUtils.createProxy(userService);
        proxy.login("admin", "123456");
        proxy.deleteUsers();
        String[] names = proxy.selectUsers();
        System.out.println("查询到的用户是:" + Arrays.toString(names));
        System.out.println("----------------------------------");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值