设计模式-原型模式

版权声明:本文为博主原创文章,转载请注明原文地址。如果觉得对您有帮助的话,请点个赞!如果想踩一脚的话,至少评论下哪里不足或者让您不满意,谢谢! https://blog.csdn.net/qq_34309305/article/details/81901731

原型模式 是用于创建重复的对象,同时又能保证性能。

什么情况下使用原型模式呢?

举个例子:

我想要组织一个军队,要求年龄17,男士。那么报名的人应该是这样的

可以看出,报名的四个人除了名字,其他都一样,我们希望建立一个原型,以原型为基准建立其他的类。

那么我们怎么建立原型模式呢?

下面是一个简单的person类。

public class People {
    private String name;
    private String sex;
    private int age;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

我们希望以Person类为原型,去建立其他的类。所以首先Person类需要实现colneable

public class People implements Cloneable {
    private String name;
    private String sex;
    private int age;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    public People Clone(){
        try {
            return (People) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

我们调用它

public class Test {
    public static void main(String[] args) {
        People person1=new People();
        person1.setAge(17);
        person1.setName("张三");
        person1.setSex("男");

        People person2=person1.Clone();
        person2.setName("李四");

        System.out.println(person1.getName());
        System.out.println(person1.getSex());
        System.out.println(person1.getAge());

        System.out.println(person2.getName());
        System.out.println(person2.getSex());
        System.out.println(person2.getAge());
    }
}

输出结果

可以看出person2不需要设置与person1重复的性别,年龄属性了。

但是,克隆根据对象的不同还分为深度克隆和浅度克隆。

我们假设Person类还有个friends属性,如下。

public class People implements Cloneable {
    private String name;
    private String sex;
    private int age;
    private List<String> friends;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    public List<String> getFriends() {
        return friends;
    }

    public void setFriends(List<String> friends) {
        this.friends = friends;
    }

    public People Clone(){
        try {
            return (People) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

可以看出friends是个List.我们调用他试试。

public class Test {
    public static void main(String[] args) {
        People person1=new People();
        person1.setAge(17);
        person1.setName("张三");
        person1.setSex("男");

        List<String> friends=new ArrayList<>();
        friends.add("傻蛋");
        friends.add("二狗");

        person1.setFriends(friends);

        People person2=person1.Clone();
        person2.setName("李四");

        System.out.println(person1.getName());
        System.out.println(person1.getSex());
        System.out.println(person1.getAge());
        System.out.println(person1.getFriends().toString());

        System.out.println(person2.getName());
        System.out.println(person2.getSex());
        System.out.println(person2.getAge());
        System.out.println(person2.getFriends().toString());
    }
}

输出如下:

这时我们改变下person1的friends。

public class Test {
    public static void main(String[] args) {
        People person1=new People();
        person1.setAge(17);
        person1.setName("张三");
        person1.setSex("男");

        List<String> friends=new ArrayList<>();
        friends.add("傻蛋");
        friends.add("二狗");

        person1.setFriends(friends);

        People person2=person1.Clone();
        person2.setName("李四");
        //增加一个杰克给person1
        person1.getFriends().add("杰克");
        person1.setFriends(person1.getFriends());

        System.out.println(person1.getName());
        System.out.println(person1.getSex());
        System.out.println(person1.getAge());
        System.out.println(person1.getFriends().toString());

        System.out.println(person2.getName());
        System.out.println(person2.getSex());
        System.out.println(person2.getAge());
        System.out.println(person2.getFriends().toString());
    }
}

看看结果。

发现person2的friends也变了。这是因为Person类实现的是浅复制,他复制的只是friends的引用,也就是说,两个person1,person2的friends指向同一个地址。所以person1的friends改变,person2也跟着改变了。

为了解决这个问题。我们要实现深复制。现改变Person类如下:

public class People implements Cloneable {
    private String name;
    private String sex;
    private int age;
    private List<String> friends;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    public List<String> getFriends() {
        return friends;
    }

    public void setFriends(List<String> friends) {
        this.friends = friends;
    }

    public People Clone(){
        try {
            People person=(People)this.clone();
            List <String> newFriends=new ArrayList<>();
            friends.forEach(friend->newFriends.add(friend));
            person.setFriends(newFriends);
            return  person;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

这里在复制的时候,将friends也进行了复制,不只是引用,而是新复制了一个List。所以测试的时候。

public class Test {
    public static void main(String[] args) {
        People person1=new People();
        person1.setAge(17);
        person1.setName("张三");
        person1.setSex("男");

        List<String> friends=new ArrayList<>();
        friends.add("傻蛋");
        friends.add("二狗");

        person1.setFriends(friends);

        People person2=person1.Clone();
        person2.setName("李四");
        //增加一个杰克给person1
        person1.getFriends().add("杰克");
        person1.setFriends(person1.getFriends());

        System.out.println(person1.getName());
        System.out.println(person1.getSex());
        System.out.println(person1.getAge());
        System.out.println(person1.getFriends().toString());

        System.out.println(person2.getName());
        System.out.println(person2.getSex());
        System.out.println(person2.getAge());
        System.out.println(person2.getFriends().toString());
    }
}

输出如下:

可见,这次实现了深复制。

大功告成!觉得有用点个赞吧!

阅读更多

没有更多推荐了,返回首页