最近有一个减肥的朋友想要知道自己的BMI是多少,问我能不能给他做一个计算BMI的工具(无中生友)。于是用Java简单写了一个。一起来看看吧。

身体质量指数是BMI指数(身体质量指数,简称体质指数),是目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准。
计算公式为:BMI=体重(千克)除以身高(米)的平方。

为了方便使用我把整个小项目整合成了一个文件,复制到记事本里可以直接运行。

import java.io.*;
/*** 本程序实现简单的BMI计算器。*   |-实现了用户键盘输入数据;*  |-实现了BMI保留一位小数点*    |-实现了Java标准输出到文件*   |-实现了工厂设计模式,减少耦合*    |-添加了对异常的处理* @author chuchu**/
public class Test {public static void main(String[] args) {new Menu();}
}class Menu {private Person per = null;private BMIService bs = null;private double BMI = 0.0;private PrintUtil out = null;public Menu() {this.show();}public void show() {System.out.println("***欢迎使用BMI计算器,请输入相关信息***");String name = InputUtil.getInfo("请输入姓名:");int age = Integer.parseInt(InputUtil.getInfo("请输入年龄:"));double height = Double.parseDouble(InputUtil.getInfo("请输入身高(米):"));double weight = Double.parseDouble(InputUtil.getInfo("请输入体重(kg):"));bs = Factory.getInstance();double b = bs.getBMI(height, weight);BMI = Math.round(b * 100) / 100;String Evl = bs.getEvaluate(BMI);per = new Person(name, age, height, weight, BMI, Evl);System.out.println("***信息创建成功***");System.out.println("您的BMI为:" + BMI);System.out.println("您的身体状况:" + Evl);System.out.println("正在将您的文件输出为文本。。。。");out = Factory.getPrintInstance(per);if (out.print())System.out.println("文件输出成功,地址为" + out.getPATH());else {System.out.println("文件输出失败!");show();}}
}class Factory {private Factory() {}public static BMIService getInstance() {return new BMIServiceImpl();}public static PrintUtil getPrintInstance(Person per) {return new PrintUtil(per);}
}interface BMIService {public double getBMI(double height, double weight);public String getEvaluate(double BMI);
}class BMIServiceImpl implements BMIService {private static final String THIN = "您的体型偏瘦,请增加营养摄入,加强锻炼!";private static final String NORMAL = "您的体型正常,请继续保持!";private static final String FATTY = "您已偏胖,请改变不健康的生活习惯,加强锻炼!";private static final String OBESITY = "您的体型肥胖,相关疾病风险显著增加!";@Overridepublic double getBMI(double height, double weight) {return weight / (height * height);}@Overridepublic String getEvaluate(double BMI) {if (BMI < 18.5)return THIN;else if (BMI < 24)return NORMAL;else if (BMI < 28)return FATTY;else if (28 < BMI)return OBESITY;elsereturn "数据有误,请重新输入相关信息!";}}class InputUtil {private static final BufferedReader BR = new BufferedReader(new InputStreamReader(System.in));private InputUtil() {}public static String getInfo(String promot) {String str = null;boolean flag = true;while (flag) {try {System.out.println(promot);str = BR.readLine();if ("".equals(str) || str == null)System.out.println("输入的信息不能为空,请检查后重新输入!");elseflag = false;} catch (IOException e) {e.printStackTrace();}}return str;}
}class PrintUtil {private Person per;public PrintUtil(Person per) {this.per = per;}public boolean print() {OutputStream os = null;try {os = new FileOutputStream(new File("D:" + File.separator + per.getName() + "的评测报告.txt"));os.write(("姓名:" + per.getName() + "\n").getBytes());os.write(("年龄:" + per.getAge() + "\n").getBytes());os.write(("身高:" + per.getHeight() + "\n").getBytes());os.write(("体重:" + per.getWeight() + "\n").getBytes());os.write(("BMI:" + per.getBMI() + "\n").getBytes());os.write(("健康评测:" + per.getEvl() + "\n").getBytes());return true;} catch (Exception e) {e.printStackTrace();return false;} finally {try {os.close();} catch (IOException e) {e.printStackTrace();}}}public String getPATH() {return "D:" + File.separator + per.getName() + "的评测报告.txt";}
}class Person {private String name;private int age;private double height; // kgprivate double weight; // mprivate double BMI;private String Evl;public Person(String name, int age, double height, double weight, double bMI, String evl) {this.name = name;this.age = age;this.height = height;this.weight = weight;BMI = bMI;Evl = evl;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}public void setBMI(double bMI) {BMI = bMI;}public void setEvl(String evl) {Evl = evl;}public double getBMI() {return BMI;}public String getEvl() {return Evl;}}

主类设计思路

整个程序的设计思路是通过伪菜单界面的方式提醒用户一次输入数据,计算出来结果之后将其返回,并利用Java的输入输出流保存文件到特定的位置。既然是伪菜单界面,那么必不可少的就是写一个Menu类来作为整个程序的入口。

public class Test {public static void main(String[] args) {new Menu();}
}class Menu {private Person per = null;private BMIService bs = null;private double BMI = 0.0;private PrintUtil out = null;public Menu() {this.show();}public void show() {System.out.println("***欢迎使用BMI计算器,请输入相关信息***");String name = InputUtil.getInfo("请输入姓名:");int age = Integer.parseInt(InputUtil.getInfo("请输入年龄:"));double height = Double.parseDouble(InputUtil.getInfo("请输入身高(米):"));double weight = Double.parseDouble(InputUtil.getInfo("请输入体重(kg):"));bs = Factory.getInstance();double b = bs.getBMI(height, weight);BMI = Math.round(b * 100) / 100;String Evl = bs.getEvaluate(BMI);per = new Person(name, age, height, weight, BMI, Evl);System.out.println("***信息创建成功***");System.out.println("您的BMI为:" + BMI);System.out.println("您的身体状况:" + Evl);System.out.println("正在将您的文件输出为文本。。。。");out = Factory.getPrintInstance(per);if (out.print())System.out.println("文件输出成功,地址为" + out.getPATH());else {System.out.println("文件输出失败!");show();}}
}

主方法非常简单,就是一句话,生成一个匿名的Menu类对象,调用Menu无参构造方法。然后依次显示提示语句。

输入流输出流设计

既然要引导依次输入不同的数据,那么就想到我们可以使用System.in实现键盘输入。每次要输入的内容又不同,我们可以将提示信息作为一个字符串传入到输入方法中,并将获取到的数据返回。
而输出流,本来计划要用Hutool的jar包,里面封装了非常好用的输出Map对象的方法。但是考虑到要将整个程序打包成一个文件发给我的朋友,还是决定自己写。于是,我将Person类对象作为一个参数传入到输出工具类之中。这个设计其实不好,因为工具类应该是私有构造的,通过调用不同的静态方法执行相应的功能,Person类对象应该作为参数传入到print()方法中,而不是作为类的私有属性以构造方法参数的形式传入。但是当时写的时候犯困就胡乱写成这个样子。

class InputUtil {private static final BufferedReader BR = new BufferedReader(new InputStreamReader(System.in));private InputUtil() {}public static String getInfo(String promot) {String str = null;boolean flag = true;while (flag) {try {System.out.println(promot);str = BR.readLine();if ("".equals(str) || str == null)System.out.println("输入的信息不能为空,请检查后重新输入!");elseflag = false;} catch (IOException e) {e.printStackTrace();}}return str;}
}class PrintUtil {private Person per;public PrintUtil(Person per) {this.per = per;}public boolean print() {OutputStream os = null;try {os = new FileOutputStream(new File("D:" + File.separator + per.getName() + "的评测报告.txt"));os.write(("姓名:" + per.getName() + "\n").getBytes());os.write(("年龄:" + per.getAge() + "\n").getBytes());os.write(("身高:" + per.getHeight() + "\n").getBytes());os.write(("体重:" + per.getWeight() + "\n").getBytes());os.write(("BMI:" + per.getBMI() + "\n").getBytes());os.write(("健康评测:" + per.getEvl() + "\n").getBytes());return true;} catch (Exception e) {e.printStackTrace();return false;} finally {try {os.close();} catch (IOException e) {e.printStackTrace();}}}public String getPATH() {return "D:" + File.separator + per.getName() + "的评测报告.txt";}
}

接口与服务类设计

其实对于计算一个BMI这种简单到只要一行return语句的业务来说,只需要在Person类之中的getBMI()方法的返回值写就可以解决。但是还是想按照标准的流程来进行开发,于是将其专门写了一个接口和接口实现类。在获取健康评价环节,我将几个要返回的评价设置成了常量,放在程序最上边,方便日后的修改。

class Factory {private Factory() {}public static BMIService getInstance() {return new BMIServiceImpl();}public static PrintUtil getPrintInstance(Person per) {return new PrintUtil(per);}
}interface BMIService {public double getBMI(double height, double weight);public String getEvaluate(double BMI);
}class BMIServiceImpl implements BMIService {private static final String THIN = "您的体型偏瘦,请增加营养摄入,加强锻炼!";private static final String NORMAL = "您的体型正常,请继续保持!";private static final String FATTY = "您已偏胖,请改变不健康的生活习惯,加强锻炼!";private static final String OBESITY = "您的体型肥胖,相关疾病风险显著增加!";@Overridepublic double getBMI(double height, double weight) {return weight / (height * height);}@Overridepublic String getEvaluate(double BMI) {if (BMI < 18.5)return THIN;else if (BMI < 24)return NORMAL;else if (BMI < 28)return FATTY;else if (28 < BMI)return OBESITY;elsereturn "数据有误,请重新输入相关信息!";}}

实体类

这里其实就没什么好说的了,就是最简单的简单Java类,实现构造,getter,setter方法。

class Person {private String name;private int age;private double height; // kgprivate double weight; // mprivate double BMI;private String Evl;public Person(String name, int age, double height, double weight, double bMI, String evl) {this.name = name;this.age = age;this.height = height;this.weight = weight;BMI = bMI;Evl = evl;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}public void setBMI(double bMI) {BMI = bMI;}public void setEvl(String evl) {Evl = evl;}public double getBMI() {return BMI;}public String getEvl() {return Evl;}}

本次的文章就到这里啦,其实不是什么复杂的业务,闲暇时间练手还是不错的。

Java练手小项目——BMI计算器相关推荐

  1. ssm练手小项目_20 个 JavaScript+Html+CSS 练手的小项目

    前言: 最近在 GitHub 上发现了一个 vanillawebprojects[1] 开源仓库,里面收集了 20 个 JavaScript+Html+CSS的练手项目,没有使用任何框架,可以让你从基 ...

  2. 练手小项目(2)-生活小助手--星座运势查询

    上一篇内容 练手小项目(2)-生活小助手 今天星期一.趁着中午的歇息时间把 第二个写出来 星座运势,近期看看极客学院 用聚合数据做了天气预报的视频教程,不好评价他.看他在后面的代码变更那么大,我就知道 ...

  3. 练手小项目(5)安全卫士_程序锁

    最近想做的小新工具箱,一直想做一个程序锁,其实原理,很简单,先注册一个服务,检测手机所有进程,如果发现被加锁的app启动,马上弹出一个输入程序锁界面,但是这样子bug很多.我先做一个基本后面慢慢把bu ...

  4. springboot+vue练手小项目[前台搭建+后台编写](非常详细)

    [ springboot+vue练手小项目 ] 技术栈: springboot+vue3+element-plus +Mybaties-plus+hutool +mysql8 项目介绍 :最近刚学了s ...

  5. 台式小风扇(HTML+CSS+JS练手小项目)

    台式小风扇(HTML+CSS+JS练手小项目) 功能介绍 外观展示 HTML代码 CSS代码 JS代码 总结 功能介绍 前段时间看到这样的风扇特效,感觉还挺好玩,就自己也写一个练练手. 风扇有四个档位 ...

  6. 爬虫练手小项目:豆瓣高分图书TOP100

    爬虫练手小项目:豆瓣高分图书TOP100 import requests import re from requests.exceptions import RequestException impo ...

  7. 数据结构练手小项目(AVL树、哈希表、循环链表、MySQL数据库)

    文章目录 前言 正文(无删减) 我的想法(删减修改版) 数据导入与数据存储 功能实现 数据结构 用户结构 SIM卡结构 AVL树数据结构 哈希表结构 数据表 用户表 SIM卡表 时间安排 前言 本月主 ...

  8. html+css+js之20个练手小项目(一)

    html+css+js之20个练手小项目(一)--Hangman 前言 一.HTML 二.CSS 三.JS 前言 前端新手练习,记录不迷失. 主要练习html和CSS布局以及JS. 来源github, ...

  9. 练手小项目,爬取3DM图片

    博客原文:https://weweweha.com 1. 概述 ​ 爬取3DM指定网页的游戏壁纸,并且通过多线程来加速爬取图片的速度. 2.使用库 ​ request库用来1解析指定网页,re库用来搜 ...

最新文章

  1. poj 3579 Median 中间值(二分搜索)
  2. java web总结:servlet
  3. Nginx反向代理为什么能够提升服务器性能?
  4. 打通两台机器的ssh功能
  5. java注解传递value_spring中@value注解需要注意的问题
  6. [知了堂学习笔记]_网络基础知识_1.OSI参考模型(网络七层协议)
  7. 作者:陶克(1988-),男,博士,北京系统工程研究所助理研究员。
  8. 1NF 2NF 3NF BCNF
  9. InceptionNet V3整理总结
  10. verilog异步复位jk触发器_同步复位和异步复位常见问题总结
  11. 剑指offer之使数组的奇数在偶数前面
  12. Spring(16)——使用注解进行bean定义
  13. 水系图一般在哪里找得到_雨水排水系统施工及设备要点详解!
  14. 最新29刷网课平台系统源码+带教程
  15. 偏最小二乘回归(PLSR)算法原理
  16. php幻灯片图片不显示不出来,织梦dedecms默认模板幻灯片无法显示图片的解决方法...
  17. java http data chunk_HTTP协议之chunk编码(分块传输编码)
  18. 阜和SAP FICO模块课程
  19. linux 运行中磁盘故障,Linux 检查磁盘损坏情况命令 -必会
  20. CodeBlock速配wxWidgets[U版]

热门文章

  1. 怎么控制当前页面不左右滑动,可以上下滑动
  2. [附源码]java毕业设计健身房管理系统
  3. javascript加入收藏夹、设置首页
  4. 中兴新支点操作系统信创全栈国产化解决方案
  5. maya动画镜像_《Maya角色动画规律及设定Alpha MEDIA》随书光盘(MAYA Animation Ring)3[光盘镜像]...
  6. 官方最新版teamview15.5.3.exe
  7. vue大数据表格解决方案的比较
  8. NodeJs 后端开发 04 使用axios调用第三方服务API
  9. 余额宝收益率跌破5% 落后银行类宝宝产品
  10. flowable学习笔记(四):动态多实例