享元模式属于结构型模式
它尝试重用现有的对象,若没有现成的,则创建对象
主要为了减少创建对象的数量,以减少内存占用,
常用在需要缓冲的场景,例如Java的常量池。
包含抽象享元、具体享元类、享元工厂三个角色。
抽象享元
食物
package com.example.duohoob.dp.flyweight;
/**
* 抽象享元、食物
* @Title: Food.java
* @Package com.example.duohoob.dp.flyweight
*
* @author yangwei
* @date 2022年7月12日
*/
public interface Food {
/**
* 味道
* @author yangwei
* @date 2022年7月12日
*
* @param extrinsicState 外部状态、随环境变化,不可共享
*/
void taste(String extrinsicState);
}
具体享元
面条
package com.example.duohoob.dp.flyweight;
/**
* 具体享元、面条
* @Title: Noodle.java
* @Package com.example.duohoob.dp.flyweight
*
* @author yangwei
* @date 2022年7月12日
*/
public class Noodle implements Food {
/**
* 内部状态、存储在对象内部,不会随环境变化
*/
private String intrinsicState = "面条";
@Override
public void taste(String extrinsicState) {
// TODO Auto-generated method stub
System.out.println(extrinsicState + "吃到了" + intrinsicState + "的味道");
}
}
饺子
package com.example.duohoob.dp.flyweight;
/**
* 具体享元、饺子
* @Title: Dumpling.java
* @Package com.example.duohoob.dp.flyweight
*
* @author yangwei
* @date 2022年7月12日
*/
public class Dumpling implements Food {
/**
* 内部状态、存储在对象内部,不会随环境变化
*/
private String intrinsicState = "饺子";
@Override
public void taste(String extrinsicState) {
// TODO Auto-generated method stub
System.out.println(extrinsicState + "吃到了" + intrinsicState + "的味道");
}
}
米饭
package com.example.duohoob.dp.flyweight;
/**
* 具体享元、米饭
* @Title: Rice.java
* @Package com.example.duohoob.dp.flyweight
*
* @author yangwei
* @date 2022年7月12日
*/
public class Rice implements Food {
/**
* 内部状态、存储在对象内部,不会随环境变化
*/
private String intrinsicState = "米饭";
@Override
public void taste(String extrinsicState) {
// TODO Auto-generated method stub
System.out.println(extrinsicState + "吃到了" + intrinsicState + "的味道");
}
}
享元工厂
食堂
package com.example.duohoob.dp.flyweight;
import java.util.HashMap;
import java.util.Map;
/**
* 享元工厂、食堂
* @Title: Canteen.java
* @Package com.example.duohoob.dp.flyweight
*
* @author yangwei
* @date 2022年7月12日
*/
public class Canteen {
/**
* 饭菜
*/
public Map<String, Food> meals = new HashMap<String, Food>();
public Food getFood(String foodName) {
// 如果没有就现做,相反有的话就不用
if (!meals.containsKey(foodName)) {
if ("面条".equals(foodName)) {
meals.put(foodName, new Noodle());
}
if ("饺子".equals(foodName)) {
meals.put(foodName, new Dumpling());
}
if ("米饭".equals(foodName)) {
meals.put(foodName, new Rice());
}
}
return meals.get(foodName);
}
}
测试
package com.example.duohoob.dp.flyweight;
/**
* @Title: FlyweightTest.java
* @Package com.example.duohoob.dp.flyweight
*
* @author yangwei
* @date 2022年7月12日
*/
public class FlyweightTest {
public static void main(String[] args) {
Canteen canteen = new Canteen();
// a要吃面条
Food noodle1 = canteen.getFood("面条");
noodle1.taste("a");
// b要吃面条
Food noodle2 = canteen.getFood("面条");
noodle2.taste("b");
// c要吃饺子
Food dumpling = canteen.getFood("饺子");
dumpling.taste("c");
// d要吃米饭
Food rice = canteen.getFood("米饭");
rice.taste("d");
System.out.println();
System.out.println("abcd共吃了四份饭菜");
System.out.println("但食堂却只需要准备" + canteen.meals.keySet().size() + "种饭菜");
}
}
运行