外部状态必须在客户端修改,比如随机画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
非常有启发的一句话:要区分状态,内部状态不可以从客户端设置,而外部状态必须从客户端设置,该模式可以提高内存使用率