设计模式 - 原型模式

原型模式概述

原型模式(Prototype Pattern):使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式是一种对象创建型模式。

通过克隆方法所创建的对象是全新的对象,它们在内存中拥有新的地址,通常对克隆所产生的对象进行修改对原型对象不会造成任何影响,每一个克隆对象都是相互独立的。

原型模式的类结构

设计模式 | 原型模式

从类到对象叫“创建”,而由本体对象到副本对象则叫“克隆”。当需要创建多个类似的复杂对象时,我们就可以考虑使用原型模式。

原型模式的核心在于如何实现克隆方法。

原型模式的应用场景

原型模式主要适用于以下应用场景。

(1)创建对象成本较大(例如,初始化时间长,占用CPU太多,或者占用网络资源太多等),需要优化资源。

(2)创建一个对象需要繁琐的数据准备或访问权限等,需要提高性能或者提高安全性。

(3)系统中大量使用该类对象,且各个调用者都需要给它的属性重新赋值。

原型模式的代码实现

效果图预览

设计模式 | 原型模式

图片中的所有圆点和五角星都是通过调用clone()方法创建的。

Shape.java

图形类,对应原型模式中的Prototype。

/**
 * 原型接口
 */
public interface Shape extends Cloneable {

    Shape clone();

    void draw(Graphics g);
}

Circle.java

圆形类,对应原型模式中的ConcretePrototype。

/**
 * 原型实现类:圆形
 */
@Data
@NoArgsConstructor
public class Circle implements Shape {

    /** x轴位置 */
    private int x;

    /** y轴位置 */
    private int y;

    @Override
    public Circle clone() {
        Circle clone = null;
        try {
            clone = (Circle)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }

    @Override
    public void draw(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        Ellipse2D.Double circle = new Ellipse2D.Double(this.getX(), this.getY(), 10, 10);

        g2d.setColor(Color.RED);
        g2d.fill(circle);

    }
}

Star.java

五角星类,对应原型模式中的ConcretePrototype。

/**
 * 原型实现类:五角星
 */
@Data
@NoArgsConstructor
public class Star implements Shape {

    /** x轴位置 */
    private int x;

    /** y轴位置 */
    private int y;

    @Override
    public Star clone() {
        Star clone = null;
        try {
            clone = (Star) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }

    @Override
    public void draw(Graphics g) {
        int xPoints[] = {9, 15, 0, 18, 3};
        int yPoints[] = {0, 18, 6, 6, 18};

        Graphics2D g2d = (Graphics2D) g;
        GeneralPath star = new GeneralPath();

        star.moveTo(xPoints[0] + this.getX(), yPoints[0] + this.getY());
        for (int i = 1; i < xPoints.length; i++) {
            star.lineTo(xPoints[i] + this.getX(), yPoints[i] + this.getY());
        }
        star.closePath();

        g2d.setColor(Color.ORANGE);
        g2d.fill(star);

    }
}

ShapeFactory.java

public class ShapeFactory {
    private static Circle circle = new Circle();
    private static Star star = new Star();
    public static Shape getInstance(String shapeType, int x, int y) {
        if (Objects.equals("circle", shapeType)) {
            Circle cloneCircle = circle.clone();
            cloneCircle.setX(x);
            cloneCircle.setY(y);
            return cloneCircle;
        } else if (Objects.equals("star", shapeType)) {
            Star cloneStar = star.clone();
            cloneStar.setX(x);
            cloneStar.setY(y);
            return cloneStar;
        }
        return null;
    }
}

PrototypePanel.java

面板类,用于绘制图形并展示。

public class PrototypePanel extends JPanel {

    private List shapeList = new ArrayList<>();

    public PrototypePanel() {
        // 设置背景颜色:白色
        setBackground(Color.LIGHT_GRAY);
        // 设置面板大小: 500 * 500
        setPreferredSize(new Dimension(500, 500));

        for(int i = 0; i < 20; i++) {
            Random random = new Random();
            shapeList.add(ShapeFactory.getInstance("circle", random.nextInt(500), random.nextInt(500)));
        }

        for(int i = 0; i < 20; i++) {
            Random random = new Random();
            shapeList.add(ShapeFactory.getInstance("star", random.nextInt(500), random.nextInt(500)));
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Shape shape : shapeList) {
            if (shape instanceof Circle) {
                shape.draw(g);
            } else if (shape instanceof Star) {
                shape.draw(g);
            }
        }
    }

    public static void main(String[] args) {
        JFrame jFrame = new JFrame();
        jFrame.add(new PrototypePanel());
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.pack();
        jFrame.setLocationRelativeTo(null);

        jFrame.setVisible(true);
    }
}

深拷贝和浅拷贝

Java中的变量分为原始类型和引用类型。

浅拷贝是指只复制原始类型的值。引用类型同样会被拷贝,但是只是拷贝了地址引用。



展开阅读全文

页面更新:2024-05-10

标签:原型   模式   圆形   客户端   实例   接口   对象   位置   类型   方法

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top