做网站公司怎么找,搜索网站内容,网站模板网站,做网站编程时容易遇到的问题1.业务需求
大家好#xff0c;我是菠菜啊#xff0c;前俩天有点忙#xff0c;今天继续更新了。今天给大家介绍克隆对象——原型模式。老规矩#xff0c;在介绍这期之前#xff0c;我们先来看看这样的需求#xff1a;《西游记》中每次孙悟空拔出一撮猴毛吹一下#x…1.业务需求
大家好我是菠菜啊前俩天有点忙今天继续更新了。今天给大家介绍克隆对象——原型模式。老规矩在介绍这期之前我们先来看看这样的需求《西游记》中每次孙悟空拔出一撮猴毛吹一下变出一大批猴子加入战斗他到底是怎么变的如果我们帮他实现这个功能代码怎么设计 2.代码实现
首先先说第一个问题怎么变的我也不知道。 但是第二个问题可以尝试一下。
实现初步思路
我们新建一个猴子类并且实例化多个猴子对象不就行了太简单了。
Monkey类
//猴子
public class Monkey {private String name;private String sex;private int age;private Weapon weapon;public Monkey(String name, String sex, int age, Weapon weapon) {this.name name;this.sex sex;this.age age;this.weapon weapon;}public Weapon getWeapon() {return weapon;}public void setWeapon(Weapon weapon) {this.weapon weapon;}Overridepublic String toString() {return Monkey{ name name \ , sex sex \ , age age , weapon weapon };}
}
Weapon类
//武器
public class Weapon {private String name;private String color;public Weapon(String name, String color) {this.name name;this.color color;}Overridepublic String toString() {return Weapon{ name name \ , color color \ };}
}Client类
public class Client {public static void main(String[] args) {Weapon weaponnew Weapon(金箍棒,金色);Monkey monkeynew Monkey(孙悟空,公,20,weapon);Weapon weapon2new Weapon(monkey.getWeapon().getName(),monkey.getWeapon().getColor());Monkey monkey2new Monkey(猴小弟,monkey.getSex(),monkey.getAge(),weapon2);Weapon weapon3new Weapon(monkey.getWeapon().getName(),monkey.getWeapon().getColor());Monkey monkey3new Monkey(猴小小弟,monkey.getSex(),monkey.getAge(),weapon3);System.out.println(monkey);System.out.println(monkey2);System.out.println(monkey3);}
}思考上述代码比较简单功能是实现了但是在克隆猴哥的时候我们要将新建一个相同类的对象。 然后 我还要必须遍历原始对象的所有成员变量 并将成员变量值复制到新对象中。这也太麻烦了如果属性是上千上万个那么猴哥还没变出猴子师傅就被妖怪给吃了。 而且并非所有对象都能通过这种方式进行复制 因为有些对象可能拥有私有成员变量 它们在对象本身以外是不可见的。而且克隆对象要知道该对象类的所有依赖类才行这样设计也太不符合迪米特法则了详细见***《设计模式——设计原则介绍》***一文。
3.方案改进
Java中提供了一个Cloneable接口其中有一个clone()方法我们只要实现这个方法就行了。
实现代码结构图 Monkey接口
//猴子
public class Monkey implements Cloneable{//......Overrideprotected Monkey clone() throws CloneNotSupportedException {return (Monkey)super.clone();}}Client类
public class Client {public static void main(String[] args) throws CloneNotSupportedException {Weapon weaponnew Weapon(金箍棒,金色);Monkey monkeynew Monkey(孙悟空,公,20,weapon);/* Weapon weapon2new Weapon(monkey.getWeapon().getName(),monkey.getWeapon().getColor());Monkey monkey2new Monkey(猴小弟,monkey.getSex(),monkey.getAge(),weapon2);Weapon weapon3new Weapon(monkey.getWeapon().getName(),monkey.getWeapon().getColor());Monkey monkey3new Monkey(猴小小弟,monkey.getSex(),monkey.getAge(),weapon3);*/Monkey monkey2monkey.clone();monkey2.setName(猴小弟);Monkey monkey3monkey.clone();monkey3.setName(猴小小弟);System.out.println(monkey);System.out.println(monkey2);System.out.println(monkey3);}
} 思考这样我们就可以快速克隆对象并且不需要知道对象创建的细节又大大提高了性能我们把这种设计模式叫做原型模式Prototype 。上述代码还是有问题可以继续往下看。
拓展浅克隆和深克隆
我们把上述代码稍微修改一下看的就明显了。
Client修改后
public class Client {public static void main(String[] args) throws CloneNotSupportedException {Weapon weaponnew Weapon(金箍棒,金色);Monkey monkeynew Monkey(孙悟空,公,20,weapon);Monkey monkey2monkey.clone();monkey2.setName(猴小弟);Monkey monkey3monkey.clone();monkey3.setName(猴小小弟);System.out.println(修改武器前monkey);System.out.println(修改武器前monkey2);System.out.println(修改武器前monkey3);//修改各自的武器装备monkey.getWeapon().setColor(红色);monkey2.getWeapon().setColor(白色);monkey3.getWeapon().setColor(绿色);System.out.println(修改武器);System.out.println(修改武器后monkey);System.out.println(修改武器后monkey2);System.out.println(修改武器后monkey3);}
}**预期结果**猴子们的武器颜色分别是红白绿。
实际结果猴子们的武器都被绿了一不小心开车了。 排查原因发现super.clone(),如果字段是值类型的就复制值如果字段是引用类型的复制引用而不复制引用的对象String是特殊的引用对象因此猴子们引用的武器对象是一个。被复制的对象的所有变量值都含有原来对象相同的值但是其它对象的引用仍然执行原来的对象叫做浅克隆**。反之把引用对象的变量指向复制过的新对象这种叫做深克隆。
我们如果要完成深复制只需做如下修改
Weapon类
//武器
public class Weapon implements Cloneable{//...Overrideprotected Weapon clone() throws CloneNotSupportedException {return (Weapon)super.clone();}}Monkey类
public class Monkey implements Cloneable{//...Overrideprotected Monkey clone() throws CloneNotSupportedException {Monkey clone (Monkey)super.clone();clone.weaponthis.weapon.clone();return clone;}}**思考**如果要深克隆必须重写clone方法如果克隆对象依赖对象的层级嵌套一多代码较复杂。
4.定义和组成结构
原型模式Prototype从一个对象创建一个可定制的对象而不需要知道任何创建细节。
原型模式包含以下主要角色。
抽象原型类Prototype规定了具体原型对象必须实现的接口。具体原型类ConcretePrototype实现抽象原型类的 clone() 方法它是可被复制的对象。访问类Acess使用具体原型类中的 clone() 方法来复制新的对象。 5.优缺点以及应用场景
优点
通过克隆一个已有的对象简化对象的创建过程不用关注对象的内部创建细节符合迪米特法则流的方式比new一个对象克隆对象效率更高
缺点:
克隆对象类必须要重写clone方法如果克隆对象依赖对象的嵌套层级较多并且要达到深克隆代码较复杂clone 方法位于类的内部当对已有类进行改造的时候可能需要修改代码违背了开闭原则
适用场景
保存对象的状态并且对象占用内存较少对象创建成本高,耗用的资源比较多对象初始化复杂
你的收藏和点赞就是我最大的创作动力关注我我会持续输出更新
友情提示请尊重作者劳动成果如需转载本博客文章请注明出处谢谢合作
【作者我爱吃菠菜 】