这里简单描述工厂方法模式和简单工厂模式这两种工厂模式。
工厂方法模式
概述
工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。
优点
客户端不需要在负责对象的创建,直接从具体的实现工厂类中获取对象。
如果有新的对象增加,只需要增加一个具体的类和具体的实现工厂类即可,不影响已有的代码
后期维护容易,增强了系统的扩展性。
缺点
需要额外的编写代码,增加了工作量。
抽象工厂类
//抽象工厂类
public abstract class AnimalFactory {
public abstract Animal createAnimal();
}
具体实现工厂类
//具体实现工厂类
public class DogFactory extends AnimalFactory{
@Override
public Animal createAnimal() {
return new Dog("小狗", "白色");
}
}
工厂方法模式使用
public class 工厂方法模式 {
public static void main(String[] args) {
AnimalFactory dogFactory=new DogFactory();
Animal animal=dogFactory.createAnimal();
System.out.println(animal);
}
}
简单工厂模式
概述
又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例。
优点
客户端不需要在负责对象的创建,直接从具体的实现工厂类中获取对象。
缺点
这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护。
具体实现工厂类
//具体实现工厂类
public class AnimalFactory2 {
public static Animal createDog()
{
return new Dog("小狗", "黄色");
}
}
简单工厂模式使用
public class 简单工厂模式 {
public static void main(String[] args) {
//类名.静态方法生成对象
Animal animal=AnimalFactory2.createDog();
System.out.println(animal);
}
}
概述
模版设计模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现
计时算法骨架
abstract class TimeTemplate{
//获取代码执行时间
public long getScheduleTime(){
//获取当前时间
long start = System.currentTimeMillis();
//测试代码
code();
//获取结束时间
long end = System.currentTimeMillis();
long delta = end - start;//计算时间差 毫秒
return delta;
}
//测试代码交给实现类(子类) 实现
public abstract void code();
}
实现类
class Test1 extends TimeTemplate{
@Override
public void code() {
for(int i=0;i<100000;i++){
System.out.println("测试算法");
}
}
}
模版设计模式使用
public class Demo01 {
public static void main(String[] args) {
//模版(Template)设计模式
System.out.println(new Test1().getScheduleTime());
}
}
概述
代理:本来应该自己做的事情,请了别人来做,被请的人就是代理对象。
举例:春节回家买票让人代买
两种实现方式:
jdk 的动态代理Proxy: Proxy需要接口和实现类
cglib字节码增强 : cglib字节码增强只需要实现类。
jdk 的动态代理Proxy简述
a: 在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口通过使用这个类和接口就可以生成动态代理对象。
b: InvocationHandler API中简介是:
Each proxy instance has an associated invocation handler.When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the {@code invoke} method of its invocation handler.
大概意思是每个动态代理类都要实现InvocationHandler接口,并且关联到一个handler,通过代理对象调用时,这个接口的方法调用就会转接到该handler的invoke方法进行调用。
c: Proxy 通过public static Object newProxyInstance(ClassLoader loader,Class>[] interfaces,InvocationHandler h)创建代理对象
// ClassLoader loader:被代理实现类的加载器
// Class>[] interfaces:被代理实现类的接口
// InvocationHandler h:代理的调用处理者
d: InvocationHandler的public Object invoke(Object proxy, Method method, Object[] args)方法会拦截方法的调用
// Object proxy:被代理的对象
// Method method:要调用的方法
// Object args[]:方法调用时所需要的参数
接口代码:
//接口
interface UserService {
// 注册用户
public void registerUser();
// 删除用户
public void deleteUser();
}
实现类代码:
//实现类
class UserServiceImpl implements UserService {
@Override
public void registerUser() {
System.out.println("注册一个用户");
}
@Override
public void deleteUser() {
System.out.println("删除一个用户");
}
}
测试类代码:
public class Demo01 {
public static void main(String[] args) {
// 1.创建对象
UserServiceImpl usi = new UserServiceImpl();
// 2.创建代理对象
// UserServiceImpl类的加载器:usi.getClass().getClassLoader()
// UserServiceImpl类的接口:usi.getClass().getInterfaces()
// 代理的调用处理者: new InvocationHandler(){}
UserService proxy = (UserService) Proxy.newProxyInstance(usi.getClass().getClassLoader(),
usi.getClass().getInterfaces(), new InvocationHandler() {
// Object proxy:被代理的对象
// Method method:要调用的方法
// Object args[]:方法调用时所需要的参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 显示被拦截方法
System.out.println(method);
// 在方法前添加
System.out.println("权限检验...");
// 拦截了所有方法
Object obj= method.invoke(usi, args);
// 在方法后添加
System.out.println("日志记录");
//这里也可以返回null
return obj;
}
});
//使用代理对象
proxy.deleteUser();
proxy.registerUser();
}
}