大话设计模式-享元模式

外部状态必须在客户端修改,比如随机画10000个小人,小人颜色有三种:红色、绿色、蓝色,实现结果如下

场景代码实现

1. 小人抽象类

package com.hj.designPattern.flyweight;

import com.hj.designPattern.flyweight.enums.Color;
import lombok.Data;

@Data
public abstract class Person {
    public Color color;

    public void drawPosition(Position position) {
        System.out.println(color.name() + "小人出现位置在" + position.getX()+","+position.getY());
    }
}

2. 外部状态Positon类

package com.hj.designPattern.flyweight;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Position {
    private int x;
    private int y;
}

3. 红、绿、蓝小人类

// 红色小人
package com.hj.designPattern.flyweight;

import com.hj.designPattern.flyweight.enums.Color;

public class RedPerson extends Person {
    RedPerson() {
        this.color = Color.RED;
    }
}

// 绿色小人
package com.hj.designPattern.flyweight;

import com.hj.designPattern.flyweight.enums.Color;

public class GreenPerson extends Person{
    GreenPerson(){
        this.color = Color.GREEN;
    }
}


// 蓝色小人
package com.hj.designPattern.flyweight;

import com.hj.designPattern.flyweight.enums.Color;

public class BluePerson extends Person{
    BluePerson(){
        this.color = Color.BLUE;
    }
}


// 颜色枚举类
package com.hj.designPattern.flyweight.enums;

public enum Color {
    RED,
    BLUE,
    GREEN;
}

4. 小人工厂

package com.hj.designPattern.flyweight;

import com.hj.designPattern.flyweight.enums.Color;

import java.util.HashMap;

public class PersonFactory {
    HashMap<String,Person> map = new HashMap<>();
    PersonFactory(){
        map.put(Color.RED.name(), new RedPerson());
        map.put(Color.GREEN.name(), new GreenPerson());
        map.put(Color.BLUE.name(), new BluePerson());
    }
    public Person getPerson(Color type){
        return map.get(type.name());
    }
}

 5. 画小人测试类

package com.hj.designPattern.flyweight;

import javax.swing.*;
import java.awt.*;
import java.util.Random;

public class FlyweightTest {
    public static void main(String[] args) {
        JFrame jFrame = new JFrame();
        jFrame.setTitle("游戏 10000个 红绿蓝小人");

        JPanel jPanel = new JPanel() {
            @Override
            public void paint(Graphics graphics) {
                // 必须先调用父类的paint方法
                super.paint(graphics);
                for (int i = 0; i < 10000; i++) {
                    Random random = new Random();
                    int randomInt = random.nextInt(3);
                    PersonFactory factory = new PersonFactory();
                    Person person = factory.getPerson(com.hj.designPattern.flyweight.enums.Color.values()[randomInt]);
                    System.out.println(person.color.name());
//                    person.drawPosition(new Position(random.nextInt(600),random.nextInt(800)));
                    if (person.color == com.hj.designPattern.flyweight.enums.Color.RED) {
                        graphics.setColor(java.awt.Color.RED);
                    } else if (person.color == com.hj.designPattern.flyweight.enums.Color.GREEN) {
                        graphics.setColor(Color.GREEN);
                    } else if (person.color == com.hj.designPattern.flyweight.enums.Color.BLUE) {
                        graphics.setColor(Color.BLUE);
                    }
                    // 用画笔Graphics,在画板JPanel上画一个小人
                    int randomX = random.nextInt(600);
                    int randomY = random.nextInt(800);
                    graphics.drawOval(100 + randomX, 70 + randomY, 30, 30);// 头部(画圆形)
                    graphics.drawRect(105 + randomX, 100 + randomY, 20, 30);// 身体(画矩形)
                    graphics.drawLine(105 + randomX, 100 + randomY, 75 + randomX, 120 + randomY);// 左臂(画直线)
                    graphics.drawLine(125 + randomX, 100 + randomY, 150 + randomX, 120 + randomY);// 右臂(画直线)
                    graphics.drawLine(105 + randomX, 130 + randomY, 75 + randomX, 150 + randomY);// 左腿(画直线)
                    graphics.drawLine(125 + randomX, 130 + randomY, 150 + randomX, 150 + randomY);// 右腿(画直线)

                    graphics.drawOval(15 + randomX, 15 + randomY, 30, 30);// 头部(画圆形)
                    graphics.drawRect(20 + randomX, 45 + randomY, 20, 30);// 身体(画矩形)
                    graphics.drawLine(20 + randomX, 45 + randomY, 0 + randomX, 60 + randomY);// 左臂(画直线)
                    graphics.drawLine(40 + randomX, 45 + randomY, 60 + randomX, 65 + randomY);// 右臂(画直线)
                    graphics.drawLine(20 + randomX, 75 + randomY, 0 + randomX, 95 + randomY);// 左腿(画直线)
                    graphics.drawLine(40 + randomX, 75 + randomY, 60 + randomX, 95 + randomY);// 右腿(画直线)
                }
            }
        };
        jFrame.add(jPanel);

        jFrame.setSize(600, 800);
        jFrame.setVisible(true);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

参考:看完就明白的享元模式 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/392581561

非常有启发的一句话:要区分状态,内部状态不可以从客户端设置,而外部状态必须从客户端设置,该模式可以提高内存使用率

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值