簡介 原型模式(Prototype Pattern)是一種創建型設計模式,使你能夠複製已有對象,而無需使代碼依賴它們所屬的類,同時又能保證性能。 這種模式是實現了一個原型介面,該介面用於創建當前對象的克隆。當直接創建對象的代價比較大時,則採用這種模式。 如果你需要複製一些對象,同時又希望代碼獨立於這 ...
簡介
原型模式(Prototype Pattern)是一種創建型設計模式,使你能夠複製已有對象,而無需使代碼依賴它們所屬的類,同時又能保證性能。
這種模式是實現了一個原型介面,該介面用於創建當前對象的克隆。當直接創建對象的代價比較大時,則採用這種模式。
如果你需要複製一些對象,同時又希望代碼獨立於這些對象所屬的具體類,可以使用原型模式。
作用
- 利用已有的一個原型對象,快速地生成和原型對象一樣的實例。
- 跳過構造函數的約束,便於提升性能。
實現步驟
- 創建原型介面,並聲明克隆方法。
- 使用new運算符調用原型版本的構造函數。
- 將子類構造函數的直接調用,替換為對原型工廠方法的調用。
UML
Java代碼
基礎原型抽象類
// Shape.java 基礎抽象類
public abstract class Shape implements Cloneable {
private int width;
private int height;
private String color = "";
protected String type;
public Shape() {
}
public String getType() {
return type;
}
// 抽象方法,子類覆蓋
public abstract void draw();
public void setWidth(int width) {
this.width = width;
}
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
public void setHeight(int height) {
this.height = height;
}
public void setColor(String color) {
this.color = color;
}
public String getColor() {
return this.color;
}
// 克隆方法
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
@Override
public String toString() {
return String.format("{width = %s, height = %s, type = %s, color = %s }",
this.width, this.height, this.type, this.color);
}
}
具體原型者
// Circle.java 具體原型類,克隆方法會創建一個新對象並將其傳遞給構造函數。
public class Circle extends Shape {
public Circle() {
super();
type = "Circle";
}
@Override
public void draw() {
System.out.println("Circle::draw() method.");
}
}
// Rectangle.java 具體原型類,克隆方法會創建一個新對象並將其傳遞給構造函數。
public class Rectangle extends Shape {
public Rectangle() {
super();
type = "Rectangle";
}
@Override
public void draw() {
System.out.println("Rectangle::draw() method.");
}
}
// 具體原型類,克隆方法會創建一個新對象並將其傳遞給構造函數。
public class Square extends Shape {
public Square() {
super();
type = "Square";
}
@Override
public void draw() {
System.out.println("Square::draw() method.");
}
}
客戶使用類
// Application.java 客戶調用方
public class Application {
public List<Shape> shapes = new ArrayList<Shape>();
public Application() {
}
public void addToShapes() {
Circle circle = new Circle();
circle.setWidth(10);
circle.setHeight(20);
circle.setColor("red");
shapes.add(circle);
// 添加clone
Circle anotherCircle = (Circle) circle.clone();
anotherCircle.setColor("pink");
shapes.add(anotherCircle);
// 變數 `anotherCircle(另一個圓)`與 `circle(圓)`對象的內容完全一樣。
Rectangle rectangle = new Rectangle();
rectangle.setWidth(99);
rectangle.setHeight(69);
rectangle.setColor("green");
shapes.add(rectangle);
// 添加clone
shapes.add((Shape) rectangle.clone());
}
// 直接取出
public Shape getShape(Integer index) {
return this.shapes.get(index);
}
// 取出時候clone
public Shape getShapeClone(Integer index) {
Shape shape = this.shapes.get(index);
return (Shape) shape.clone();
}
public void printShapes() {
for (int i = 0; i < this.shapes.size(); i++) {
Shape shape = this.shapes.get(i);
System.out.println("shape " + i + " : " + shape.toString());
}
}
}
測試調用
/**
* 原型模式主要就是複製已有的對象,而無需實例化類,從而提升實例化對象時的性能
* 其實就是複製實例的屬性到新對象上,減少了執行構造的步驟
*/
Application application = new Application();
application.addToShapes();
Shape shapeClone = application.getShapeClone(1);
// 更改clone
shapeClone.setColor("gray");
System.out.println("shapeClone : " + shapeClone.toString());
// 直接更改
application.getShape(3).setColor("yellow");
application.printShapes();
// /*********************** 分割線 ******************************************/
application.shapes.add(new Square());
for (Shape shape : application.shapes) {
shape.draw();
System.out.println(shape.toString());
}
C代碼
基礎原型抽象類
// func.h 基礎頭文件
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
typedef struct Shape shape;
typedef struct Circle circle;
typedef struct Rectangle rectangle;
typedef struct Square square;
// 定義了Shape作為基礎介面,以便各形狀有統一類型
typedef struct Shape
{
char name[50];
int width;
int height;
char color[50];
char category[50];
void (*draw)(struct Shape *shape);
struct Shape *(*clone)(struct Shape *shape);
char *(*to_string)(struct Shape *shape);
void (*set_width)(struct Shape *shape, int width);
int (*get_width)(struct Shape *shape);
void (*set_height)(struct Shape *shape, int height);
int (*get_height)(struct Shape *shape);
void (*set_color)(struct Shape *shape, char *color);
char *(*get_color)(struct Shape *shape);
void (*set_category)(struct Shape *shape, char *category);
char *(*get_category)(struct Shape *shape);
} Shape;
Shape *shape_constructor(char *name);
typedef struct Circle
{
char name[50];
int width;
int height;
char color[50];
char category[50];
void (*draw)(struct Circle *shape);
struct Circle *(*clone)(struct Circle *shape);
char *(*to_string)(struct Circle *shape);
void