欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java 23种设计模式之原型模式

程序员文章站 2022-06-13 07:55:19
...

1. 概念

    用原型实例指定创建对象的种类,并且拷贝这些原型创建新的对象。

2. 创建实体类对象

    1.创建人物对象
    public class Person implements Cloneable{

        private String name;
        private int age;
        private String sex;
        private String workTime;
        private String company;
        private WorkExperience work;

        public Person(String name){
            this.name = name;
            work = new WorkExperience();
        }

        public void setPersonInfo(String sex,int age){
            this.sex = sex;
            this.age = age;
        }

        public void setWorkExperience(String workTime,String company){
            work.setWorkTime(workTime);
            work.setCompany(company);
        }

        @Override
        protected Object clone() throws CloneNotSupportedException {

            Person p = (Person) super.clone();
            return p;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", sex='" + sex + '\'' +
                    ", workTime='" + work.getWorkTime() + '\'' +
                    ", company='" + work.getCompany() + '\'' +
                    '}';
        }
    }

    2. 创建工作经历对象
    public class WorkExperience {

        private String workTime;
        private String company;

        public String getWorkTime() {
            return workTime;
        }

        public void setWorkTime(String workTime) {
            this.workTime = workTime;
        }

        public String getCompany() {
            return company;
        }

        public void setCompany(String company) {
            this.company = company;
        }
    }

3. 浅复制与深复制

    1. 浅复制
     @Override
     protected Object clone() throws CloneNotSupportedException {

            Person p = (Person) super.clone();
            return p;
     }

    2. 深复制
    (1) 工作经历类实现Cloneable
    public class WorkExperience implements Cloneable{

        private String workTime;
        private String company;

        public String getWorkTime() {
            return workTime;
        }

        public void setWorkTime(String workTime) {
            this.workTime = workTime;
        }

        public String getCompany() {
            return company;
        }

        public void setCompany(String company) {
            this.company = company;
        }

        @Override
        protected Object clone() throws CloneNotSupportedException{
            WorkExperience work = (WorkExperience)super.clone();
            return work;
        }
    }

    (2) 修改Person 类
    新增一个私有的构造方法 以方便克隆工作经历的数据
    private Person(WorkExperience work) throws CloneNotSupportedException{
        if(work != null){
            this.work = (WorkExperience) work.clone();
        }
    }

    修改clone方法 让工作经历克隆完成
    @Override
    protected Object clone() throws CloneNotSupportedException {

        Person p = new Person(this.work);
        p.name = this.name;
        p.age = this.age;
        p.sex = this.sex;
        return p;

    }

4. 测试

    1. 浅复制
    @org.junit.Test
    public void test1() throws Exception{
        Person p = new Person("郑乐成");
        p.setPersonInfo("男",25);
        p.setWorkExperience("2015-2017","北京盛世冬康科技发展有限公司");


        Person p1 = (Person) p.clone();
        p1.setWorkExperience("2016-2018","北京盛世东康科技发展有限公司");

        System.out.println(p.toString());
        System.out.println(p1.toString());
    }

    结果展示:因为工作经历是同一个引用 所以两条数据都被修改了
    Person{name='郑乐成', age=25, sex='男', workTime='2016-2018', company='北京盛世东康科技发展有限公司'}
    Person{name='郑乐成', age=25, sex='男', workTime='2016-2018', company='北京盛世东康科技发展有限公司'}

    2. 深复制
    @org.junit.Test
    public void test3() throws Exception{
          Person p = new Person("郑乐成");
          p.setPersonInfo("男",25);
          p.setWorkExperience("2014-2017","北京盛世冬康科技发展有限公司");

          Person p1 = (Person) p.clone();
          p1.setPersonInfo("男",26);
          p1.setWorkExperience("2016-2018","北京盛世东康科技发展有限公司");

        System.out.println(p.toString());
        System.out.println(p1.toString());
    }

    结果展示:
    Person{name='郑乐成', age=25, sex='男', workTime='2014-2017', company='北京盛世冬康科技发展有限公司'}
    Person{name='郑乐成', age=26, sex='男', workTime='2016-2018', company='北京盛世东康科技发展有限公司'}

5.小结

    优:
    简化代码,优化设计。