zoukankan      html  css  js  c++  java
  • 设计模式01 创建型模式

    参考

    1. 设计模式:原型模式 | 博客园

    2. Java clone深拷贝、浅拷贝 | CSDN

    3. Cloneable接口和Object的clone()方法 | 博客园

    原型模式(Prototype Pattern)

     指定创建对象的种类,并且通过拷贝创建新的对象。

    原型模式复制的克隆对象≠原对象,内存地址段不同,但是属性状态相同。

    角色

    角色名称 中文名称 作用描述
    Client 客户类 让一个原型克隆自身从而获得新的对象
    Prototype 原型接口 声明克隆的接口
    ConcretePrototype 具体原型类 实现声明的克隆接口

    特点

    1. 当要克隆的对象比较复杂时,原型模式的克隆方法能简化对象创建过程,提高创建对象效率;

    2. 克隆对象保持了原对象的所有属性状态;

    3. 原型提供了简化的创建结构;

    缺点

    1. 深克隆时,要为每一个原型的属性对象都创建克隆方法,可能需要修改原有类实现,不符合对扩展开放、对修改关闭的“开闭”原则;

    适用场景

    1. 创建对象的过程比较复杂,可以利用已有对象进行复制,如需要深克隆;

    2. 需要保持对象状态,或者状态变化较少,可以利用原型克隆对象。

    深克隆&浅克隆

    克隆:复制一个原有对象,产生一个新对象。[浅克隆,深克隆统称]

    浅克隆:会复制所有属性值,如果属性是对象地址/引用,不会复制对象本身,而仅仅是复制对象地址/引用;[仅复制一次对象]

    深克隆:不仅会复制所以属性值,而且会复制属性所代表对象本身,如果还包含子对象,也会进行迭代复制;[迭代复制对象]

    UML类图

     

    demo

    现以一个舰船的小游戏为例。

    一般来说,敌舰EnemyShip包含name, damage, size, position 4个共有属性。

    代码

     1. 创建要克隆的原型EnemyShip接口/抽象类, 以及属性对象Position, Size对应类

    EnemyShip抽象类,在clone方法复制position和size对象属性目的是为了进行深克隆。如若是浅克隆可以不用创建新属性对象。

    // EnemyShip.java
    public abstract class EnemyShip {
    	protected String name;
    	protected float damage;
    	protected Size size;
    	protected Position position;
    	
    	public abstract EnemyShip clone();
    	
    	/**
    	 * 打印各属性信息
    	 * 如果具体实现类有新添的属性, 需要重写该方法
    	 */
    	public void display() {
    		System.out.println(this.getClass().toString() + ": [" );
    		System.out.println("Name: " + getName());
    		System.out.println("Damage: " + getDamage());
    		System.out.println("Size: (" + getSize().getWidth() + " , " + getSize().getHeight() + ")");
    		System.out.println("Position: " + getPosition().getX() + " , " + getPosition().getY() + ")");
    		System.out.println("]");
    	}
    	
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public float getDamage() {
    		return damage;
    	}
    
    	public void setDamage(float damage) {
    		this.damage = damage;
    	}
    
    	public Size getSize() {
    		return size;
    	}
    
    	public void setSize(Size size) {
    		this.size = size;
    	}
    
    	public Position getPosition() {
    		return position;
    	}
    
    	public void setPosition(Position position) {
    		this.position = position;
    	}
    	
    }
    

     Position

    // Position.java
    public class Position {
    	private int x;
    	private int y;
    	
    	public Position(int x, int y) {
    		this.x = x;
    		this.y = y;
    	}
    	
    	public Position(Position p) {
    		this.x = p.x;
    		this.y = p.y;
    	}
    
    	public int getX() {
    		return x;
    	}
    
    	public void setX(int x) {
    		this.x = x;
    	}
    
    	public int getY() {
    		return y;
    	}
    
    	public void setY(int y) {
    		this.y = y;
    	}
    }
    

     Size

    // Size.java
    public class Size {
    	private int width;
    	private int height;
    	
    	public Size(int width, int height) {
    		this.width = width;
    		this.height = height;
    	}
    	
    	public Size(Size s) { 
    		this.width = s.width;
    		this.height = s.height;
    	}
    	
    	public int getWidth() {
    		return width;
    	}
    	public void setWidth(int width) {
    		this.width = width;
    	}
    	public int getHeight() {
    		return height;
    	}
    	public void setHeight(int height) {
    		this.height = height;
    	}
    }
    

    2. 创建具体要实现克隆的原型类UFO, Rocket, Ultimate EnemyShip

    原型实现类UFOEnemyShip

    // UFOEnemyShip
    public class UFOEnemyShip  extends EnemyShip{
    
    	@Override
    	public EnemyShip clone() {
    		EnemyShip clone = new UFOEnemyShip();
    		
    		if(clone != null){
    
    			Position p = new Position(this.getPosition());
    			clone.setPosition(p);
    
    			Size s = new Size(this.getSize());
    			clone.setSize(s);
    		}
    		
    		return clone;
    	}
    /*	
    	public void display() {
    		System.out.println(this.getClass().toString() + ": [" );
    		System.out.println("Name: " + getName());
    		System.out.println("Damage: " + getDamage());
    		System.out.println("Size: (" + getSize().getWidth() + " , " + getSize().getHeight() + ")");
    		System.out.println("Position: " + getPosition().getX() + " , " + getPosition().getY() + ")");
    	}*/
    }
    

     原型实现类RocketEnemyShip

    // RocketEnemyShip.java
    public class RocketEnemyShip extends EnemyShip {
    	
    	@Override
    	public EnemyShip clone() {
    		EnemyShip clone = new RocketEnemyShip();
    		
    		if(clone != null){
    
    			Position p = new Position(this.getPosition());
    			clone.setPosition(p);
    
    			Size s = new Size(this.getSize());
    			clone.setSize(s);
    		}
    		
    		return clone;
    	}
    
    }
    

     原型实现类UltimateEnemyShip

    // UltimateEnemyShip.java
    public class UltimateEnemyShip extends EnemyShip {
    
    	@Override
    	public EnemyShip clone() {
    		EnemyShip clone = new UltimateEnemyShip();
    		
    		if(clone != null){
    
    			Position p = new Position(this.getPosition());
    			clone.setPosition(p);
    
    			Size s = new Size(this.getSize());
    			clone.setSize(s);
    		}
    		
    		return clone;
    	}
    }
    

    3. 创建客户类,使用EnemyShip UFO类对象进行克隆Rocket, Ultimiate

    客户端类Client

    // Client.java
    public class Client {
    
    	public static void main(String[] args) {
    		// 新建ufo
    		EnemyShip ufo = new UFOEnemyShip();
    		ufo.setName("UFO");
    		ufo.setDamage(15);
    		ufo.setPosition(new Position(0, 0));
    		ufo.setSize(new Size(5,5));
    		
    		// 利用ufo克隆rocket
    		EnemyShip rocket = ufo.clone();
    		rocket.setName("Rocket");
    		rocket.setDamage(20);
    		rocket.setPosition(new Position(10, 12));
    		rocket.setSize(new Size(15, 15));
    		
    		// 利用ufo克隆ultimate
    		EnemyShip ultimate = ufo.clone();
    		ultimate.setName("Ultimate");
    		ultimate.setDamage(100);
    		ultimate.setPosition(new Position(20, 16));
    		ultimate.setSize(new Size(30, 30));
    		
    		// 显示创建对象信息
    		ufo.display();
    		rocket.display();
    		ultimate.display();
    	}
    }
    

    运行结果

    Console输出结果

    class DesignPattern.UFOEnemyShip: [
    Name: UFO
    Damage: 15.0
    Size: (5 , 5)
    Position: 0 , 0)
    ]
    class DesignPattern.UFOEnemyShip: [
    Name: Rocket
    Damage: 20.0
    Size: (15 , 15)
    Position: 10 , 12)
    ]
    class DesignPattern.UFOEnemyShip: [
    Name: Ultimate
    Damage: 100.0
    Size: (30 , 30)
    Position: 20 , 16)
    ]
    

      

  • 相关阅读:
    robotium(及百度cafe)运行testcase之后程序挂起没有响应的原因调查及解决
    python——请求服务器(http请求和https请求)
    Django项目:CRM(客户关系管理系统)--65--55PerfectCRM实现CRM客户报名状态颜色变化
    Django项目:CRM(客户关系管理系统)--64--54PerfectCRM实现CRM客户报名链接
    Django项目:CRM(客户关系管理系统)--63--53PerfectCRM实现CRM客户报名流程缴费
    Django项目:CRM(客户关系管理系统)--62--52PerfectCRM实现CRM客户报名流程学生合同审核
    Django项目:CRM(客户关系管理系统)--60--50PerfectCRM实现CRM客户报名流程学生合同URL随机码
    Django项目:CRM(客户关系管理系统)--59--49PerfectCRM实现CRM客户报名流程学生合同表单验证
    Django项目:CRM(客户关系管理系统)--58--48PerfectCRM实现CRM客户报名流程学生合同
    Django项目:CRM(客户关系管理系统)--56--47PerfectCRM实现CRM客户报名流程01
  • 原文地址:https://www.cnblogs.com/fortunely/p/9800807.html
Copyright © 2011-2022 走看看