zoukankan      html  css  js  c++  java
  • 原型模式

    原型模式概述

    某些特定的时候,我们需要同一个类生成多个相同的对象,或者是基于一个对象生成一个复制对象,并再对复制对象进行修改,这时候就可以使用到原型模式。

    UML

    一个简单的示例:

    package com.prototype;
    
    public class Customer implements Cloneable {
    	private String name;
    	private int createYear;
    	// 由于Address是引用对象, 所以address也需要实现clone方法,防止只实现了浅克隆
    	private Address address;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getCreateYear() {
    		return createYear;
    	}
    
    	public void setCreateYear(int createYear) {
    		this.createYear = createYear;
    	}
    
    	public Address getAddress() {
    		return address;
    	}
    
    	public void setAddress(Address address) {
    		this.address = address;
    	}
    
    	@Override
    	protected Object clone() throws CloneNotSupportedException {
    		Customer customer = new Customer();
    		customer.setCreateYear(this.createYear);
    		customer.setName(this.name);
    		// 不应该使用这行代码,因为是引用对象,
    		// 所以需要深克隆,否则Customerde克隆对象address的修改会影响被克隆对象的address
    		// customer.setAddress(this.address);
    		customer.setAddress((Address) this.address.clone());
    		return customer;
    	}
    
    	@Override
    	public String toString() {
    		return "Customer [name=" + name + ", createYear=" + createYear
    				+ ", address=" + address + "]";
    	}
    
    }
    package com.prototype;
    
    public class Address implements Cloneable {
    	private String city;
    	private String region;
    
    	public Address(String city, String region) {
    		super();
    		this.city = city;
    		this.region = region;
    	}
    
    	@Override
    	protected Object clone() throws CloneNotSupportedException {
    		Address address = new Address(this.city, this.region);
    		return address;
    	}
    
    	public String getCity() {
    		return city;
    	}
    
    	public void setCity(String city) {
    		this.city = city;
    	}
    
    	public String getRegion() {
    		return region;
    	}
    
    	public void setRegion(String region) {
    		this.region = region;
    	}
    
    	@Override
    	public String toString() {
    		return "Address [city=" + city + ", region=" + region + "]";
    	}
    }
    
    package com.prototype;
    
    public class Client {
    	public static void main(String[] args) throws CloneNotSupportedException {
    		Customer customer1 = new Customer();
    		customer1.setName("经销商A");
    		customer1.setCreateYear(3);
    		customer1.setAddress(new Address("Guangzhou", "tianhe"));
    		Customer customer2 = (Customer) customer1.clone();
    		customer2.setName("经销商B");
    		// 大家可以试一下如果Address没有实现Cloneable接口和clone方法的话,会出现什么效果
    		customer2.getAddress().setCity("Shenzhen");
    		System.out.println(customer1);
    		System.out.println(customer2);
    	}
    }

    总结 

    使用原型模式可以在不需要知道对象的创建细节的情况下,生成一个与原有对象相同的对象,不易出错且java给我们提供了Cloneable接口可以标记出该类是否支持克隆,但是这里又涉及了浅复制和深复制两种情况,在java中要实现深复制需要在被引用的类中再单独实现克隆方法,可能在这里就会比较繁琐。

    才疏学浅,如文中有错误,感谢大家指出。

  • 相关阅读:
    nginx-1.8.1的安装
    ElasticSearch 在3节点集群的启动
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    sqoop导入导出对mysql再带数据库test能跑通用户自己建立的数据库则不行
    LeetCode 501. Find Mode in Binary Search Tree (找到二叉搜索树的众数)
    LeetCode 437. Path Sum III (路径之和之三)
    LeetCode 404. Sum of Left Leaves (左子叶之和)
    LeetCode 257. Binary Tree Paths (二叉树路径)
    LeetCode Questions List (LeetCode 问题列表)- Java Solutions
    LeetCode 561. Array Partition I (数组分隔之一)
  • 原文地址:https://www.cnblogs.com/runningRookie/p/11108773.html
Copyright © 2011-2022 走看看