设计模式的七大原则
- 开闭原则:对扩展开放、对修改关闭。
- 单一指责原则:一个类只做一件事。
- 依赖倒转原则:类似于ioc,采用接口编程。
- 迪米特原则:高内聚,低耦合。
- 接口隔离原则:应该使用多个接口,而不是用单一的总接口。
- 合成复用原则:尽量使用对象组合,而不是继承来达到复用目的。
- 里氏替换原则:子类可以扩展父类的功能,但不能改变原有的功能。
一、创建型模式(5种)
1.单例模式(Singleton)
保证一个类只有一个实例,并提供一个全局访问点。
/**
* 饿汉式 单利模式 静态变量
*/
class Person{
//饿汉式 单利模式 类加载时初始创建 一个对象
private final static Person person= new Person();
//构造器私有化
private Person() {
}
//提供返回类的静态方法
public static Person getInstance(){
return person;
}
}
/**
* 饿汉式 单利模式 静态代码块
*/
class Student{
//饿汉式 单利模式 类加载时初始创建 一个对象
private static Student student;
// 在静态代码块中,创建单例对象
static {
student=new Student();
}
//构造器私有化
private Student() {
}
//提供返回类的静态方法
public static Student getInstance(){
return student;
}
}
/**
* 懒汉式 单利模式 线程不安全
*/
class Student1{
private static Student1 student;
//构造器私有化
private Student1() {
}
//提供返回类的静态方法
public static Student1 getInstance(){
if (null==student){
student = new Student1();
}
return student;
}
}
/**
* 懒汉式 单利模式 线程安全 同步方法
*/
class Student2{
private static Student2 student;
//构造器私有化
private Student2() {
}
//提供返回类的静态方法
public static synchronized Student2 getInstance(){
if (null==student){
student = new Student2();
}
return student;
}
}
/**
* 懒汉式 单利模式
*
* 同步代码块 高并发也是 线程不安全
*/
class Student3{
private static Student3 student;
//构造器私有化
private Student3() {
}
//提供返回类的静态方法
public static Student3 getInstance(){
if (null==student){
synchronized (Student.class){
student = new Student3();
}
}
return student;
}
}
/**
* 双重判定锁 单利模式
*
*/
class Student4{
private static Student4 student;
//构造器私有化
private Student4() {
}
//提供返回类的静态方法
public static Student4 getInstance(){
if (null==student){
synchronized (Student.class){
if (null==student){
student = new Student4();
}
}
}
return student;
}
}
/**
* 静态内部类 单利模式
*
*/
class Student7{
//构造器私有化
private Student7() {
}
/**
* 静态内部类 类加载的时候 不初始化,调用的时候 初始化加载一次
*/
public static class SingletonStudent{
private static final Student7 student= new Student7();
}
//提供返回类的静态方法
public static Student7 getInstance(){
return SingletonStudent.student;
}
}
/**
* 枚举
*
*/
enum Student8{
INSTANCE;
private AtomicLong id = new AtomicLong(0);
//提供返回类的静态方法
public static Student8 getInstance(){
return INSTANCE;
}
}
2、工厂模式(Factory)
/**
* 简单工厂 类
*/
public class SimplePizzaFactory {
public Pizza CreatePizza(String orderType){
Pizza pizza=null;
if (orderType.equals("cheese")){
pizza=new CheesePizza();
}else if (orderType.equals("greek")){
pizza=new GreekPizza();
} else if (orderType.equals("pepper")){
pizza=new PepperPizza();
}
return pizza;
}
}
工厂方法
public interface Product {
void show();
}
public class ProductA implements Product {
@Override
public void show() {
System.out.println("具体产品A");
}
}
public class ProductB implements Product{
@Override
public void show() {
System.out.println("具体产品B");
}
}
public interface ProductFactory {
Product manufacture();
}
public class FactoryA implements ProductFactory{
@Override
public Product manufacture() {
System.out.println("具体工厂A");
return new ProductA();
}
}
public class FactoryB implements ProductFactory{
@Override
public Product manufacture() {
System.out.println("具体工厂B");
return new ProductB();
}
}
/**
* 新增一个产品 就得对应得 又一个工厂类 随着产品的增加,类会变得越来越复杂
*
* 模式优点:
* 1,符合开闭原则:增加新产品时,只需要增加相应的具体工厂类和具体产品类;
* 2,符合单一职责原则:一个工厂只负责一个产品的创建
*
* 模式缺点:
* 1,一个具体工厂只生产一个具体产品,当工厂和产品增多,类也增多,系统复杂度上升;
* 2,如果需要更换具体工厂里面生产的具体产品还是要更改原有代码,这就违反了开闭原则;
* @param args
*/
public static void main(String[] args) {
FactoryA factoryA = new FactoryA();
Product productA = factoryA.manufacture();
productA.show();
FactoryB factoryB = new FactoryB();
Product productB = factoryB.manufacture();
productB.show();
}
3.抽象工厂
public interface IPhoneProduct {
//开机
void start();
//关机
void shutdown();
//打电话
void callup();
//发邮件
void sendSMS();
}
public interface IRouterProduct {
//开机
void start();
//关机
void shutdown();
//打开wifi
void openwifi();
//设置
void setting();
}
public class HuaweiPhone implements IPhoneProduct{
@Override
public void start() {
System.out.println("开启华为手机");
}
@Override
public void shutdown() {
System.out.println("关闭华为手机");
}
@Override
public void callup() {
System.out.println("华为手机打电话");
}
@Override
public void sendSMS() {
System.out.println("华为手机发邮件");
}
}
public class HuaweiRouter implements IRouterProduct{
@Override
public void start() {
System.out.println("开启华为路由器");
}
@Override
public void shutdown() {
System.out.println("关闭华为路由器");
}
@Override
public void openwifi() {
System.out.println("打开华为wifi");
}
@Override
public void setting() {
System.out.println("设置华为路由器");
}
}
public class XiaomiPhone implements IPhoneProduct{
@Override
public void start() {
System.out.println("开启小米手机");
}
@Override
public void shutdown() {
System.out.println("关闭小米手机");
}
@Override
public void callup() {
System.out.println("小米手机打电话");
}
@Override
public void sendSMS() {
System.out.println("小米手机发邮件");
}
}
public class XiaomiRouter implements IRouterProduct{
@Override
public void start() {
System.out.println("开启小米路由器");
}
@Override
public void shutdown() {
System.out.println("关闭小米路由器");
}
@Override
public void openwifi() {
System.out.println("打开小米wifi");
}
@Override
public void setting() {
System.out.println("设置小米路由器");
}
}
public interface IProductFactory {
//生产手机
IPhoneProduct phoneProduct();
//生成路由器
IRouterProduct routerProduct();
}
public class HuaweiFactory implements IProductFactory{
@Override
public IPhoneProduct phoneProduct() {
return new HuaweiPhone();
}
@Override
public IRouterProduct routerProduct() {
return new HuaweiRouter();
}
}
public class XiaomiFactory implements IProductFactory{
@Override
public IPhoneProduct phoneProduct() {
return new XiaomiPhone();
}
@Override
public IRouterProduct routerProduct() {
return new XiaomiRouter();
}
}
/**
* 抽象工厂 感觉 是一个行为的 抽象,
* 然后分为不同的接口,工厂定义不同行为的返回实现类
* @param args
*/
public static void main(String[] args) {
System.out.println("============小米产品============");
//创建小米工厂
IProductFactory xiaomiFactory = new XiaomiFactory();
//生产小米手机
IPhoneProduct xiaomiPhone = xiaomiFactory.phoneProduct();
xiaomiPhone.start();
xiaomiPhone.sendSMS();
//生产小米路由器
IRouterProduct xiaomiRouter = xiaomiFactory.routerProduct();
xiaomiRouter.openwifi();
xiaomiRouter.setting();
System.out.println("============华为产品============");
//创建华为工厂
IProductFactory huaweiFactory = new HuaweiFactory();
//生产华为手机
IPhoneProduct huaweiPhone = huaweiFactory.phoneProduct();
huaweiPhone.start();
huaweiPhone.sendSMS();
//生产华为路由器
IRouterProduct huaweiRouter = huaweiFactory.routerProduct();
huaweiRouter.openwifi();
huaweiRouter.setting();
}
4.原型模式
public class Product implements Cloneable{
private String name;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
/**
* 原型模式 只是浅拷贝 ,
* 要实现深拷贝,引用数据 也要重写clone ,除string之外
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
Product product = new Product();
product.setName("嗷嗷");
Product clone1 = (Product)product.clone();
System.out.println(product==clone1);
System.out.println(clone1.getName()==product.getName());
System.out.println(clone1.getName());
System.out.println(product.getName());
}
5。建造者模式
/**
* 产品
*/
@Data
public class Car {
/**
* 车的名字
*/
private String name;
/**
* 发动机
*/
private String engine;
/**
* 底盘
*/
private String chassis;
/**
* 车身
*/
private String body;
/**
* 电气设备
*/
private String electricalEquipment;
}
/**
* 抽象建造者
*/
public abstract class Builder {
protected Car car=new Car();
/**
* 建造发动机
*/
public abstract void buildEngine();
/**
* 制造底盘
*/
public abstract void buildChassis();
/**
* 制造车身
*/
public abstract void buildBody();
/**
* 制造电气设备
*/
public abstract void buildElectricalEquipment();
/**
* 返回制造的车辆
*/
public Car buildCar() {
return car;
}
}
/**
* 具体建造者
*/
public class BMWBuilder extends Builder{
{
car.setName("宝马");
}
@Override
public void buildEngine() {
car.setEngine("宝马发动机");
System.out.println("制造宝马发动机");
}
@Override
public void buildChassis() {
car.setChassis("宝马底盘");
System.out.println("制造宝马底盘");
}
@Override
public void buildBody() {
car.setBody("宝马车身");
System.out.println("制造宝马车身");
}
@Override
public void buildElectricalEquipment() {
car.setElectricalEquipment("宝马电气设备");
System.out.println("制造宝马电气设备");
}
}
/**
* 指挥者
*/
public class CarDirector {
private Builder carBuilder;
public CarDirector(Builder carBuilder) {
this.carBuilder = carBuilder;
}
public Car constructCar() {
carBuilder.buildEngine();
carBuilder.buildChassis();
carBuilder.buildBody();
carBuilder.buildElectricalEquipment();
return carBuilder.buildCar();
}
public static void main(String[] args) {
// 造宝马
BMWBuilder bmwBuilder = new BMWBuilder();
// 创建指挥者
CarDirector diretor = new CarDirector(bmwBuilder);
Car car = diretor.constructCar();
System.out.println(car);
}
}
6.适配器模式
- 类适配器
public class AC220 {
public int OutputAC220V(){
int output=220;
System.out.println("输出电压"+output);
return output;
}
}
public interface DC5 {
int outputAC5V();
}
public class PowerAdapter extends AC220 implements DC5{
@Override
public int outputAC5V() {
int ac220V = super.OutputAC220V();
int adapter= ac220V / 44;
return adapter;
}
public static void main(String[] args) {
PowerAdapter powerAdapter = new PowerAdapter();
int i = powerAdapter.outputAC5V();
System.out.println("===="+i);
}
}
- 对象适配器
public class AC220 {
public int OutputAC220V(){
int output=220;
System.out.println("输出电压"+output);
return output;
}
}
public interface DC5 {
int outputAC5V();
}
public class PowerAdapter implements DC5 {
private AC220 ac220;
public PowerAdapter(AC220 ac220) {
this.ac220 = ac220;
}
public int outputAC5V() {
int adapterInput = ac220.OutputAC220V();
int adapterOutput = adapterInput / 44;
System.out.println("使用Adapter输入AC" + adapterInput + "V,输出DC" + adapterOutput + "V");
return adapterOutput;
}
public static void main(String[] args) {
AC220 ac220 = new AC220();
PowerAdapter adapter = new PowerAdapter(ac220);
int i = adapter.outputAC5V();
System.out.println("===="+i);
}
}
- 接口适配器
接口适配器的关注点与类适配器和对象适配器的关注点不太一样,类适配器和对象适配器着重将系统存在的一个角色(Adaptee)转化成目标接口(Target)所需内容,而接口适配器的使用场景是解决接口方法过多,如果直接实现接口,那么类会多处许多空实现的方法。类显得臃肿。此时,使用接口适配器就能让我们只实现我们需要的接口方法,目标更清晰。
接口适配器的主要原理就是利用抽象类实现接口,并且空实现接口众多方法
public class AC220 {
public int OutputAC220V(){
int output=220;
System.out.println("输出电压"+output);
return output;
}
}
public interface DC {
int output5V();
int output12V();
int output24V();
int output36V();
}
public class PowerAdapter implements DC{
private AC220 ac220;
public PowerAdapter(AC220 ac220) {
this.ac220 = ac220;
}
public int output5V() {
int adapterInput = ac220.OutputAC220V();
int adapterOutput = adapterInput / 44;
System.out.println("使用Adapter输入AC" + adapterInput + "V,输出DC" + adapterOutput + "V");
return adapterOutput;
}
public int output12V() {
return 0;
}
public int output24V() {
return 0;
}
public int output36V() {
return 0;
}
public static void main(String[] args) {
AC220 ac220 = new AC220();
PowerAdapter adapter = new PowerAdapter(ac220);
adapter.output5V()
System.out.println("===="+i);
}
}
7.代理模式
- 静态代理
public interface IRentHouse {
void rentHouse();
}
public class RentHouse implements IRentHouse{
@Override
public void rentHouse() {
System.out.println("实现租房");
}
}
public class IntermediaryProxy implements IRentHouse{
private IRentHouse iRent;
public IntermediaryProxy(IRentHouse iRentHouse) {
iRent=iRentHouse;
}
@Override
public void rentHouse() {
System.out.println("交中介费");
iRent.rentHouse();
System.out.println("中介负责维修管理");
}
public static void main(String[] args) {
//定义租房
IRentHouse iRentHouse = new RentHouse();
//定义中介
IRentHouse intermediaryProxy = new IntermediaryProxy(iRentHouse);
//中介租房
intermediaryProxy.rentHouse();
}
}
- jdk 动态代理
public interface IRentHouse {
void rentHouse();
}
public class RentHouse implements IRentHouse {
@Override
public void rentHouse() {
System.out.println("实现租房");
}
}
public class JdkProxyFactory {
private IRentHouse rentHouse;
public IRentHouse getProxyIRentHouse(){
IRentHouse instance = (IRentHouse) Proxy.newProxyInstance(rentHouse.getClass().getClassLoader(),//类加载器
rentHouse.getClass().getInterfaces(),//代理类实现的接口 字节码对象
new InvocationHandler() {
//代理对象 的调用程序
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("jdk动态代理收取一定的费用");
Object o = method.invoke(rentHouse, args);
return o;
}
});
return instance;
}
public JdkProxyFactory(IRentHouse rentHouse) {
this.rentHouse = rentHouse;
}
}
public class Client {
public static void main(String[] args) {
JdkProxyFactory proxyFactory = new JdkProxyFactory(new RentHouse());
IRentHouse rentHouse = proxyFactory.getProxyIRentHouse();
rentHouse.rentHouse();
}
}
- cglib 动态代理
public class RentHouse {
public void rentHouse() {
System.out.println("实现租房");
}
}
public class CglbProxyFactory implements MethodInterceptor {
public static RentHouse creatCglibProxyObj(Class<?> clazz) {
Enhancer enhancer = new Enhancer();
// 为加强器指定要代理的业务类(即为下面生成的代理类指定父类)
enhancer.setSuperclass(clazz);
// 设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法
enhancer.setCallback(new CglbProxyFactory());
return (RentHouse) enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("【cglib增强方法】代理对象正在执行的方法:" + method.getName());
Object result = methodProxy.invokeSuper(o,objects);
return result;
}
}
public class Client {
public static void main(String[] args) {
RentHouse rentHouse = CglbProxyFactory.creatCglibProxyObj(RentHouse.class);
rentHouse.rentHouse();
}
}
8.装饰者模式
/**
* 快餐类
*
* 抽象构件角色
*/
@Data
public abstract class FastFood {
/**
* 价格
*/
private float price;
/**
* 描述
*/
private String desc;
public abstract float cost();
public FastFood(float price, String desc) {
this.price = price;
this.desc = desc;
}
}
/**
* 炒饭 具体构件角色
*/
public class FriedNoodles extends FastFood{
@Override
public float cost() {
return getPrice();
}
public FriedNoodles(float price, String desc) {
super(12, "炒面");
}
}
/**
* 炒饭 具体构件角色
*/
public class FriedRice extends FastFood{
@Override
public float cost() {
return getPrice();
}
public FriedRice() {
super(10,"炒饭");
}
}
/**
* 装饰者类 抽象装饰者角色
*/
@Data
public abstract class Garnish extends FastFood{
/**
* 声明快餐类的变量
*/
private FastFood fastFood;
public Garnish(float price, String desc,FastFood fastFood) {
super(price, desc);
this.fastFood=fastFood;
}
}
/**
* 培根类 具体装饰者角色
*/
@Data
public class Bacon extends Garnish{
public Bacon(FastFood fastFood) {
super(2, "培根", fastFood);
}
@Override
public float cost() {
return getPrice()+getFastFood().cost();
}
@Override
public String getDesc() {
return super.getDesc()+getFastFood().getDesc();
}
}
/**
* 鸡蛋类 具体装饰者角色
*/
@Data
public class Egg extends Garnish{
public Egg( FastFood fastFood) {
super(1, "鸡蛋", fastFood);
}
@Override
public float cost() {
return getPrice()+getFastFood().cost();
}
@Override
public String getDesc() {
return super.getDesc()+getFastFood().getDesc();
}
}
public class Client {
public static void main(String[] args) {
//点一份炒饭
FastFood food = new FriedRice();
System.out.println(food.getDesc()+"=="+food.cost());
//在上面的炒饭中加一个鸡蛋
food = new Egg(food);
System.out.println(food.getDesc()+"=="+food.cost());
// 再加一个鸡蛋
food = new Egg(food);
System.out.println(food.getDesc()+"=="+food.cost());
// 再加一个培根
food = new Bacon(food);
System.out.println(food.getDesc()+"=="+food.cost());
}
}
9.桥接模式
/**
* 抽象的操作系统类 抽象化角色
*/
@Data
public abstract class OpratingSystem {
//声明videoFile 变量
protected VideoFile videoFile;
public abstract void play(String fileName);
public OpratingSystem(VideoFile videoFile) {
this.videoFile = videoFile;
}
}
/**
* 视频文件 实现化角色
*/
public interface VideoFile {
/**
* 解码功能
* @param fileName
*/
void decode(String fileName);
}
/**
* 扩展抽象化角色 windows 操作系统
*/
public class Windows extends OpratingSystem{
@Override
public void play(String fileName) {
this.videoFile.decode(fileName);
}
public Windows(VideoFile videoFile){
super(videoFile);
}
}
/**
* 扩展抽象化角色 MAC 操作系统
*/
public class MAC extends OpratingSystem{
@Override
public void play(String fileName) {
this.videoFile.decode(fileName);
}
public MAC(VideoFile videoFile){
super(videoFile);
}
}
/**
* AV 视频文件 具体的实现化角色
*/
public class AvFIle implements VideoFile{
@Override
public void decode(String fileName) {
System.out.println("av视频文件"+fileName);
}
}
/**
* RMV 视频文件 具体的实现化角色
*/
public class RmvFile implements VideoFile{
@Override
public void decode(String fileName) {
System.out.println("RMV视频文件"+fileName);
}
}
public class Client {
public static void main(String[] args) {
OpratingSystem mac = new MAC(new AvFIle());
//使用操作系统播放视频文件
mac.play("战狼");
}
}
10.外观模式
/**
* 空调类型
*/
public class AirCondition {
//开灯
public void on(){
System.out.println("打开空调");
}
//开灯
public void off(){
System.out.println("关闭空调");
}
}
/**
* 电灯类型
*/
public class Light {
//开灯
public void on(){
System.out.println("打开电灯");
}
//开灯
public void off(){
System.out.println("关闭电灯");
}
}
/**
* 电视机类型
*/
public class TV {
//开灯
public void on(){
System.out.println("打开电视机");
}
//开灯
public void off(){
System.out.println("关闭电视机");
}
}
/**
* 外观 类 用户主要和该类对象 进行交互
*/
public class SmartAppFacade {
/**
* 聚合 电灯 电视机 空调对象
*/
private Light light;
private TV tv;
private AirCondition airCondition;
public SmartAppFacade() {
this.light = new Light();
this.tv = new TV();
this.airCondition = new AirCondition();
}
public void say(String message){
if (message.contains("打开")){
light.on();
tv.on();
airCondition.on();
}else if (message.contains("关闭")){
light.off();
tv.off();
airCondition.off();
}else
System.out.println("我还听不懂你说什么。。。");
}
}
public class Client {
public static void main(String[] args) {
SmartAppFacade appFacade = new SmartAppFacade();
//控制家电
appFacade.say("打开");
appFacade.say("关闭 ");
}
}
11.组合模式
/**
* 菜单组件 抽象根节点
*/
public abstract class MenuComponent {
/**
* 菜单组件的名称
*/
protected String name;
/**
* 菜单组件的层级
*/
protected int level;
//添加子菜单
public void add(MenuComponent menuComponent){
throw new UnsupportedOperationException();
}
//移除子菜单
public void remove(MenuComponent menuComponent){
throw new UnsupportedOperationException();
}
//获取指定的子菜单
public MenuComponent getChild(int index){
throw new UnsupportedOperationException();
}
//获取菜单或者菜单项的名称
public String getName(){
return name;
}
//打印菜单名称的方法(包括子菜单和子菜单项)
public abstract void print();
}
/**
* 菜单类 属于树枝节点
*/
public class Menu extends MenuComponent{
//菜单可以有多个子菜单 或者子菜单项
private List<MenuComponent> menuComponentList=new ArrayList<MenuComponent>();
//构造方法
public Menu(String name,int level) {
this.level=level;
this.name =name;
}
@Override
public void add(MenuComponent menuComponent) {
menuComponentList.add(menuComponent);
}
@Override
public void remove(MenuComponent menuComponent) {
menuComponentList.remove(menuComponent);
}
@Override
public MenuComponent getChild(int index) {
return menuComponentList.get(index);
}
@Override
public void print() {
//打印菜单名称
System.out.println(name);
//打印子菜单名称 或者子菜单项名称
for (MenuComponent menuComponent : menuComponentList) {
menuComponent.print();
}
}
}
/**
* 菜单项类 属于叶子节点
*/
public class MenuItem extends MenuComponent{
public MenuItem(String name,int level){
this.level=level;
this.name =name;
}
@Override
public void print() {
//打印菜单项的名称
System.out.println(name);
}
}
public class Cilent {
/**
* 组合模式
* @param args
*/
public static void main(String[] args) {
//创建菜单书
MenuComponent menu1 = new Menu("菜单管理", 2);
menu1.add(new MenuItem("页面访问",3));
menu1.add(new MenuItem("展开菜单",3));
menu1.add(new MenuItem("编辑菜单",3));
menu1.add(new MenuItem("删除菜单",3));
menu1.add(new MenuItem("新增菜单",3));
MenuComponent menu2 = new Menu("权限配置", 2);
menu2.add(new MenuItem("页面访问",3));
menu2.add(new MenuItem("提交保存",3));
MenuComponent menu3 = new Menu("角色管理", 2);
menu3.add(new MenuItem("页面访问",3));
menu3.add(new MenuItem("新增角色",3));
menu3.add(new MenuItem("修改角色",3));
//创建一级菜单
MenuComponent menu = new Menu("系统管理", 1);
//将二级菜单添加到一级菜单中
menu.add(menu1);
menu.add(menu2);
menu.add(menu3);
menu.print();
}
}
12.享元模式
/**
* 抽象享元类:定义充电宝 </p>
*/
public abstract class BasePowerBankFlyWeight {
/**
* 维持一个是否在使用中的状态 true:正在使用 false:未使用
*/
boolean inUse = false;
/**
* 使用充电宝
*/
abstract void use();
/**
* 结束使用
*/
abstract void endUse();
}
/**
* @author ZhongJing </p>
* @Description 具体享元类 </p>
*/
@Data
public class PowerBank extends BasePowerBankFlyWeight {
/**
* 编号
*/
private Integer id;
/**
* 品牌
*/
private String brand;
@Override
void use() {
System.out.println("编号:" + id + " 品牌:" + brand + " 的充电宝正在使用中……");
this.inUse = true;
}
@Override
void endUse() {
System.out.println("编号:" + id + " 品牌:" + brand + " 的充电宝使用结束,已放回……");
this.inUse = false;
}
public PowerBank(Integer id, String brand) {
this.id = id;
this.brand = brand;
}
}
/**
* @author ZhongJing </p>
* @Description 充电宝箱子:享元工厂 </p>
*/
public class PowerBankBox {
private static Map<Integer, BasePowerBankFlyWeight> powerBankPool = new HashMap<>();
private static Integer powerBankNum = 1;
static {
// 初始化时创建两个充电宝放到充电箱中
PowerBank powerBank = new PowerBank(powerBankNum++, "罗马仕");
PowerBank powerBank2 = new PowerBank(powerBankNum++, "小米");
powerBankPool.put(powerBank.getId(), powerBank);
powerBankPool.put(powerBank2.getId(), powerBank2);
}
/**
* 添加一个充电宝到充电宝箱中
*/
public void addPowerBank(BasePowerBankFlyWeight powerBank) {
powerBankPool.put(powerBankNum++, powerBank);
}
/**
* 取出充电宝
*/
public static BasePowerBankFlyWeight usePowerBank(Integer num) {
// 首先查找指定的充电宝
BasePowerBankFlyWeight powerBank = powerBankPool.get(num);
// 如果找不到指定编号的充电宝或者指定编号充电宝正在使用中,则随机返回一个充电宝
if (Objects.isNull(powerBank) || powerBank.inUse) {
// 遍历连接迟中所有充电宝
for (BasePowerBankFlyWeight p : powerBankPool.values()) {
// 如果某个充电宝未在使用,则返回这个充电宝
if (!p.inUse) {
return p;
}
}
// 循环到最后都没有空闲的充电宝,则返回null
return null;
}
// 如果找到了指定编号的充电宝且没有在使用,直接返回指定充电宝
return powerBank;
}
public static void main(String[] args) {
BasePowerBankFlyWeight powerBank1 = PowerBankBox.usePowerBank(2);
powerBank1.use();
BasePowerBankFlyWeight powerBank2 = PowerBankBox.usePowerBank(null);
powerBank2.use();
powerBank2.endUse();
BasePowerBankFlyWeight powerBank3 = PowerBankBox.usePowerBank(null);
powerBank3.use();
}
}