1.原型模式
定义:通过复制现有的对象实例来创建新的对象实例。
实现:
1.实现Cloneable接口
Cloneable接口的作用是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法。在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedException异常。2.重写Object类中的clone方法
Java中,所有类的父类都是Object类,Object类中有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此,原型类需要将clone方法的作用域修改为public类型。
代码:Mail.java
/** * 对于拿邮件发邀请函来说,邮件的大部分内容都是一样的 * 变的只是接收者的名称和邮件地址 */ public class Mail implements Cloneable { private String receiver; // 接收者地址 private String subject; //邮件主题(不变) private String content; //邮件内容 private String tail; //邮件结尾(不变) public Mail(EventTemplate et){ this.tail = et.getEventContent(); this.subject = et.getEventSubject(); } @Override public Mail clone(){ Mail mail = null; try { mail = (Mail) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return mail; } public String getReceiver() { return receiver; } public void setReceiver(String receiver) { this.receiver = receiver; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getTail() { return tail; } public void setTail(String tail) { this.tail = tail; } }
EventTemplate.java
public class EventTemplate { private String eventContent; private String eventSubject; public EventTemplate(String eventSubject, String eventContent) { this.eventContent = eventContent; this.eventSubject = eventSubject; } public String getEventContent() { return eventContent; } public void setEventContent(String eventContent) { this.eventContent = eventContent; } public String getEventSubject() { return eventSubject; } public void setEventSubject(String eventSubject) { this.eventSubject = eventSubject; } }
测试方法:
public class cloneTest { public static void main(String[] args) { //数据库获取被邀请人的信息 Map<String, String> map = new HashMap<String, String>(); map.put("张三先生", "[email protected]"); map.put("小红女士", "[email protected]"); map.put("李四先生", "[email protected]"); EventTemplate et = new EventTemplate("邀请函", "欢迎来参加我的结婚典礼。。。。"); Mail mail = new Mail(et); Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); Mail cloneMail = mail.clone(); cloneMail.setContent(entry.getKey()+mail.getTail()); cloneMail.setReceiver(entry.getValue()); //发送邮件 sendMail(cloneMail); } } }
原型模式无法和单例模式一起使用(原型模式复制对象不会调用类的构造方法),一般和工厂模式一起出现。
浅拷贝是基础类型的拷贝,深拷贝是在对象中又定义了对象时,内部的对象也要实现cloneable接口,重写clone方法。
2.建造者模式
定义:使用多个简单的对象,一步步构建成一个复杂的对象。例如java中的StringBuilder。
使用场景:基础对象相对稳定,但组合多变的情况下。
代码:
public interface Item { public String name(); public float price(); public Packing packing(); } public interface Packing { public String packing(); } public class Bottle implements Packing { public String packing() { return "瓶装"; } } public class Box implements Packing { public String packing() { return "盒装"; } } public abstract class Burger implements Item{ @Override public Packing packing(){ return new Box(); } } public abstract class ChickenWing implements Item{ @Override public Packing packing(){ return new Box(); } } public abstract class Drink implements Item{ @Override public Packing packing(){ return new Bottle(); } }
public class ChickenBurger extends Burger { @Override public String name() { return "鸡肉汉堡"; } @Override public float price() { return 18.5f; } } public class VegBurger extends Burger { @Override public String name() { return "蔬菜汉堡"; } @Override public float price() { return 12.5f; } } public class RoastChickWing extends ChickenWing { @Override public String name() { return "奥尔良烤鸡翅"; } @Override public float price() { return 10; } } public class Coke extends Drink { @Override public String name() { return "可乐"; } @Override public float price() { return 10; } } public class Milk extends Drink { @Override public String name() { return "牛奶"; } @Override public float price() { return 12.5f; } }
public class Meal { private List<Item> items = new ArrayList<Item>(); public void addItem(Item item){ items.add(item); } public float getCost(){ float cost = 0.0f; for (Item item : items) { cost += item.price(); } return cost; } public void showItems(){ for (Item item : items) { System.out.print("Item : "+item.name()); System.out.print(", Packing : "+item.packing().packing()); System.out.println(", Price : "+item.price()); } } } public class MealBuilder { public Meal meal1() { Meal meal = new Meal(); meal.addItem(new ChickenBurger()); meal.addItem(new RoastChickWing()); meal.addItem(new Coke()); return meal; } public Meal meal2() { Meal meal = new Meal(); meal.addItem(new VegBurger()); meal.addItem(new Milk()); return meal; } }
测试:
public class BuilderTest { public static void main(String[] args){ MealBuilder mealBuilder = new MealBuilder(); Meal meal1 = mealBuilder.meal1(); System.out.println("套餐一"); meal1.showItems(); System.out.println("Total Cost: " +meal1.getCost()); Meal meal2 = mealBuilder.meal2(); System.out.println("套餐二"); meal2.showItems(); System.out.println("Total Cost: " +meal2.getCost()); } }
结果: