3.3 建造者模式
将复杂的对象细化拆分成零件,再组装,不同的组装可以得到不同的结果
例子:一个汉堡店的基础套餐: 汉堡 + 饮料。汉堡可选蔬菜汉堡和鸡肉汉堡,饮料可选雪碧和可乐。食物包装分为纸(汉堡)和杯子(饮料)。要求输出不同选择下的订单信息(名称,包装,单价,总价)
例子参考菜鸟教程 https://www.runoob.com/design-pattern/builder-pattern.html
/**
* 套餐
* @Author gpy
* @CreateTime 2022-08-09 16:56
* @Version 1.0
*/
public class Meal {
private List<Item> items = new ArrayList<>();
/**
* 添加食物
* @param item
*/
public void addItem(Item item) {
items.add(item);
}
/**
* 计算价格
* @return
*/
public float getCost() {
AtomicReference<Float> cost = new AtomicReference<>((float) 0);
items.forEach(item -> {
cost.updateAndGet(v -> new Float((float) (v + item.price())));
});
return cost.get();
}
/**
* 订单展示
*/
void showItems() {
items.forEach(item -> {
System.out.println("name:" + item.name() + ",packing:" + item.packing().packing()+ ",price:" + item.price());
});
System.out.println("cost:" + getCost());
}
}
/**
* @Author gpy
* @CreateTime 2022-08-09 17:06
* @Version 1.0
*/
public class MealBuilder {
public Meal prepareVegMeal() {
Meal meal = new Meal();
meal.addItem(new VegBurgerItem());
meal.addItem(new CokeItem());
return meal;
}
public Meal prepareNonVegMeal() {
Meal meal = new Meal();
meal.addItem(new ChickenBurgerItem());
meal.addItem(new PepsiItem());
return meal;
}
}
3.4 原型模式
原型模式是拷贝一个原有的对象,生成一个新的对象,浅拷贝是实现Cloneable,深拷贝是通过实现Serializable 读取二进制流。
4 结构型模式
4.1 适配器模式
通过继承或依赖,作为两个原本不兼容的接口之间的桥梁。比如音频播放器设备只能播放 mp3 文件,通过使用一个更高级的音频播放器来播放 vlc 和 mp4 文件。
// 某音频播放设备
public interface MediaPlayer {
// 播放接口
void player(String type, String filename);
}
// 另一个更高级的音频播放设备
public interface AdapterMediaPalyer {
void vlcPlayer(String filename);
void mp4Player(String filename);
}
// 高级设备的mp4播放
public class Mp4Player implements AdapterMediaPalyer {
@Override
public void vlcPlayer(String filename) {
// 无处理
}
@Override
public void mp4Player(String filename) {
System.out.println("mp4文件" + filename + " 播放拉~~~");
}
}
// 高级设备的vlc播放
public class VlcPlayer implements AdapterMediaPalyer {
@Override
public void vlcPlayer(String filename) {
System.out.println("vlc文件" + filename + " 播放拉~~~");
}
@Override
public void mp4Player(String filename) {
// 无处理
}
}
// 适配代码,实现原音频设备,实际是通过高级设备播放
public class MediaAdapter implements MediaPlayer {
private AdapterMediaPalyer adapterMediaPalyer;
public MediaAdapter(String type) {
if("vlc".equalsIgnoreCase(type)) {
adapterMediaPalyer = new VlcPlayer();
} else if("mp4".equalsIgnoreCase(type)) {
adapterMediaPalyer = new Mp4Player();
}
}
@Override
public void player(String type, String filename) {
if("vlc".equalsIgnoreCase(type)) {
adapterMediaPalyer.vlcPlayer(filename);
} else if("mp4".equalsIgnoreCase(type)) {
adapterMediaPalyer.mp4Player(filename);
}
}
}
// 原设备播放接口实现,通过适配器播放其他音频
public class AdapterPlayer implements MediaPlayer {
@Override
public void player(String type, String filename) {
if("mp3".equalsIgnoreCase(type)) {
System.out.println("mp3文件" + filename + "播放拉~~~");
} else if("vlc".equalsIgnoreCase(type) || "mp4".equalsIgnoreCase(type)) {
MediaAdapter mediaAdapter = new MediaAdapter(type);
mediaAdapter.player(type, filename);
} else {
System.out.println("不支持" + type + "格式的文件播放");
}
}
}
// 测试播放功能
public class TestAdapter {
public static void main(String[] args) {
AdapterPlayer adapterPlayer = new AdapterPlayer();
adapterPlayer.player("mp3", "大嘻哈");
adapterPlayer.player("vlc", "将军令");
adapterPlayer.player("mp4", "洗刷刷");
adapterPlayer.player("mp5", "哈哈哈");
}
}