【设计模式】原型模式(序列化深拷贝)、建造者模式以及代理模式

本专栏将从基础开始,循序渐进,由浅入深讲解常见的设计模式,希望大家都能够从中有所收获,也请大家多多支持。
专栏地址:设计模式实战
所有代码地址:代码地址
如果文章知识点有错误的地方,请指正!大家一起学习,一起进步。

1 原型模式

1.1 使用序列化深拷贝

import lombok.Data;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

//深拷贝对象,super.clone()方法是浅拷贝
@Data
public class ConcretePrototype implements Cloneable, Serializable {
    
    
    private int age;
    private String name;
    private List<String> hobbies;

    //浅拷贝
    @Override
    protected ConcretePrototype clone() throws CloneNotSupportedException {
    
    
        try{
    
    
            return (ConcretePrototype)super.clone();
        }catch (Exception e){
    
    
            e.printStackTrace();
            return null;
        }
    }

    //深拷贝
    public ConcretePrototype deepClone(){
    
    
        try{
    
    
            //字节输出流
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            //对象输出流
            ObjectOutputStream objectOutput = new ObjectOutputStream(byteArrayOutputStream);
            //写入对象
            objectOutput.writeObject(this);

            //字节输入流
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            //对象输入流
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            //读入对象
            return (ConcretePrototype)objectInputStream.readObject();
        }catch (Exception e){
    
    
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public String toString() {
    
    
        return "ConcretePrototype{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", hobbies=" + hobbies +
                '}';
    }


    public static void main(String[] args) {
    
    
        //创建原型对象
        ConcretePrototype concretePrototype = new ConcretePrototype();
        concretePrototype.setAge(18);
        concretePrototype.setName("Tom");
        List<String> hobbies = new ArrayList<String>();
        hobbies.add("书法");
        hobbies.add("美术");
        concretePrototype.setHobbies(hobbies);
        System.out.println(concretePrototype);
        //等号赋值传递的是引用
        hobbies.add("美术");
        System.out.println(concretePrototype);

        try{
    
    
            ConcretePrototype concretePrototype1 = concretePrototype.clone();
            concretePrototype1.getHobbies().add("英语");
            System.out.println(concretePrototype);
            System.out.println(concretePrototype1);

            ConcretePrototype concretePrototype2 = concretePrototype.deepClone();
            concretePrototype2.getHobbies().add("数学");
            System.out.println(concretePrototype);
            System.out.println(concretePrototype2);
        }catch (Exception e){
    
    
            e.printStackTrace();
        }

    }
}

2 建造者模式

2.1 简单建造者

  • Course.java
import lombok.Data;

@Data
public class Course {
    
    
    private String name;
    private String PPT;
    private String video;
    private String note;
    private String homework;
}
  • CourseBuilder.java
public class CourseBuilder {
    
    
    private Course course = new Course();

    public CourseBuilder addName(String name){
    
    
        course.setName(name);
        return this;
    }

    public CourseBuilder addPPT(String PPT){
    
    
        course.setPPT(PPT);
        return this;
    }

    public CourseBuilder addVideo(String video){
    
    
        course.setVideo(video);
        return this;
    }

    public CourseBuilder addNote(String note){
    
    
        course.setNote(note);
        return this;
    }

    public CourseBuilder addHomework(String homework){
    
    
        course.setHomework(homework);
        return this;
    }

    public Course build(){
    
    
        return course;
    }

    public static void main(String[] args) {
    
    
        CourseBuilder builder = new CourseBuilder().addName("设计模式").addPPT("PPT课件").addVideo("回放视频").addNote("课堂笔记").addHomework("课后作业");
        System.out.println(builder.build());
    }
}

2.2 内部类建造者

import lombok.Data;

@Data
public class CourseInnerBuilder {
    
    
    private String name;
    private String PPT;
    private String video;
    private String note;
    private String homework;

    public static class Builder{
    
    
        private CourseInnerBuilder course = new CourseInnerBuilder();

        Builder(){
    
    

        }

        public Builder addName(String name){
    
    
            course.setName(name);
            return this;
        }

        public Builder addPPT(String PPT){
    
    
            course.setPPT(PPT);
            return this;
        }

        public Builder addVideo(String video){
    
    
            course.setVideo(video);
            return this;
        }

        public Builder addNote(String note){
    
    
            course.setNote(note);
            return this;
        }

        public Builder addHomework(String homework){
    
    
            course.setHomework(homework);
            return this;
        }

        public CourseInnerBuilder build(){
    
    
            return course;
        }
    }

    public static void main(String[] args) {
    
    
        CourseInnerBuilder courseInnerBuilder = new CourseInnerBuilder.Builder()
                .addName("设计模式")
                .addPPT("PPT课件")
                .addVideo("回放视频")
                .addNote("课堂笔记")
                .addHomework("课后作业").build();
        System.out.println(courseInnerBuilder);
    }
}

3 代理模式

当无法或不想直接引用某个对象或访问某个对象存在困难时,可以通过代理对象来间接访使用代理模式主要有两个目的:一是保护目标对象,二是增强目标对象。在代码中,一般代理会被理解为代码增强,实际上就是在原代码逻辑前后增加一些代码逻辑,而使调用者无感知。代理模式分为静态代理和动态代理。

3.1 JDK代理(重新实现接口,代理接口中的方法)

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

interface IPerson{
    
    
    void findLove();
}

class ZhangSan implements IPerson{
    
    

    public void findLove() {
    
    
        System.out.println("符合要求");
    }
    
    public void say(){
    
    
        System.out.println("hello");
    }
}

public class JDKMeipo implements InvocationHandler {
    
    
    //被代理的对象
    private IPerson target;

    public IPerson getInstance(IPerson target){
    
    
        this.target = target;
        Class<? extends IPerson> clazz = target.getClass();
        /*第一个参数: 用哪个类加载器去加载代理对象
        第二个参数:动态代理类需要代理的方法
        第三个参数:动态代理方法在执行时,会调用h里面的invoke方法去执行*/
        return (IPerson) Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        before();
        Object result = method.invoke(this.target, args);
        after();
        return result;
    }

    private void before(){
    
    
        System.out.println("开始物色");
    }

    private void after(){
    
    
        System.out.println("开始交往");
    }

    public static void main(String[] args) {
    
    
        JDKMeipo jdkMeipo = new JDKMeipo();

        IPerson zhangsanProxy = jdkMeipo.getInstance(new ZhangSan());
        zhangsanProxy.findLove();
        
        //代理类只能调用接口中的方法
//        zhangsanProxy.say();
    }


}

3.2 CGLib(通过继承,代理所有方法)

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

class Zhangsan{
    
    
    public void findLove(){
    
    
        System.out.println("符合要求");
    }
}

public class CGLibMeipo implements MethodInterceptor {
    
    
    public Object getInstance(Class<?> clazz) throws Exception{
    
    
        //相当于JDK中的Proxy类,完成代理的工具类,通过继承实现
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    
    
        before();
        Object res = methodProxy.invokeSuper(proxy, args);
        after();
        return res;
    }

    private void before(){
    
    
        System.out.println("开始物色");
    }

    private void after(){
    
    
        System.out.println("开始交往");
    }

    public static void main(String[] args) {
    
    
        try{
    
    
            Zhangsan obj = (Zhangsan)new CGLibMeipo().getInstance(Zhangsan.class);
            obj.findLove();
        }catch (Exception e){
    
    
            e.printStackTrace();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/Learning_xzj/article/details/125027547
今日推荐