前言
构造器的问题应该还是比较重要的,因为我们要设置合理的构造函数暴露出来生成对象。
在我看来,构造器的设置还是需要慎重考虑的,所以以我愚见,结合自己写过的一些代码,对这个问题进行一下分析。
设计模式之——单例模式
(下面的代码为懒汉式、线程非安全)
public class MedicineInfoMapper implements IFileSerialization<AllMedicinesMap> {
private MedicineInfoMapper() {}
private static MedicineInfoMapper mapper;
/**
* 获取单例
* @return 单例
*/
public static MedicineInfoMapper getInstance() {
if (mapper == null) {
mapper = new MedicineInfoMapper();
}
return mapper;
}
/**
* 反序列化从文件中读取PatientList的序列化对象
*/
@Override
public AllMedicinesMap readObject() {
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(ALL_MEDICINES_FILENAME))) {
AllMedicinesMap medicinesMap = (AllMedicinesMap)ois.readObject();
return medicinesMap;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
/**
* 序列化对象
*/
@Override
public void writeObject(AllMedicinesMap object) {
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(ALL_MEDICINES_FILENAME))) {
oos.writeObject(object);
} catch (IOException e) {
e.printStackTrace();
}
}
}
不应暴露构造器
这种情况一般适用于工具类/常量类这样的类,不适合(也没必要)生成实例。
下面是常量类,我们暴露出静态常量交给整个工程调用:
public class Constant {
/**
* 不允许被实例化
*/
private Constant() {}
//...
public static final ...;
}
下面是纯粹的工具类,不应该被实例化,暴露出必要的public static的方法就OK:
public class TimeCalculator {
//工具类,不允许被实例化
private TimeCalculator() {}
/**
* 根据两个时间计算岁数
* @param nowTime
* @param oldTime
* @return
*/
public static int calculateAge(Calendar nowTime, Calendar oldTime) {
int age = nowTime.get(Calendar.YEAR) - oldTime.get(Calendar.YEAR);
if (nowTime.get(Calendar.MONTH) < oldTime.get(Calendar.MONTH)) {
age--;
} else if (nowTime.get(Calendar.MONTH) == oldTime.get(Calendar.MONTH) &&
nowTime.get(Calendar.DATE) < oldTime.get(Calendar.DATE)) {
age--;
}
return age;
}
//...
}
设计模式之——工厂模式
public class ResultGenerator {
private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";
private ResultGenerator() {}
public static Result genSuccessResult() {
return new Result()
.setCode(ResultCode.SUCCESS)
.setMessage(DEFAULT_SUCCESS_MESSAGE);
}
public static Result genSuccessResult(Object data) {
return new Result()
.setCode(ResultCode.SUCCESS)
.setMessage(DEFAULT_SUCCESS_MESSAGE)
.setData(data);
}
public static Result genFailResult(String message) {
return new Result()
.setCode(ResultCode.FAIL)
.setMessage(message);
}
}
懒得写,完全用默认的构造器
这个比较常见(特别是初学者),编写的类不设计构造器,直接new就完事,就不贴代码了……
emmm还是示意一下吧:
public class DefaultConstructorTest {
public static void main(String[] args) {
DefaultConstructorTest obj = new DefaultConstructorTest();
}
}
直接梭哈,把全部的可用属性全加上
这种也行,干脆全加上,爱咋咋地
import java.io.Serializable;
/**
* 医生类
*/
public class Doctor implements Serializable {
/**
* 默认序列化UID
*/
private static final long serialVersionUID = 1L;
/**
* 医生ID
*/
private Integer doctorId;
/**
* 医生登录名
*/
private String userName;
/**
* 医生账户密码
*/
private String password;
/**
* 医生真实姓名
*/
private String name;
/**
* 医生所在科室
*/
private String department;
/**
* 医生职称信息(主任医师、副主任医师、主治医师、住院医师)
*/
private String title;
/**
* 是否参与排班
*/
private Boolean isOnline;
public Doctor(Integer doctorId, String userName, String password, String name, String department, String title,
Boolean isOnline) {
super();
this.doctorId = doctorId;
this.userName = userName;
this.password = password;
this.name = name;
this.department = department;
this.title = title;
this.isOnline = isOnline;
}
public Integer getDoctorId() {
return doctorId;
}
public void setDoctorId(Integer doctorId) {
this.doctorId = doctorId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Boolean getIsOnline() {
return isOnline;
}
public void setIsOnLine(Boolean isOnline) {
this.isOnline = isOnline;
}
}
在构造器里进行一些处理再得到结果
比如下面的代码,有这样一句: this.patientAge = TimeCalculator.calculateAge(patientBirthday); ,就是调用了外部方法,利用已有参数进行处理得到值再赋给属性:
public class Patient implements IList<RegisterInfo>, Serializable {
/**
* 序列化
*/
private static final long serialVersionUID = 1L;
/**
* 患者ID
*/
private Integer patientId;
/**
* 患者姓名
* (这是必填项)
*/
private String patientName;
/**
* 患者性别
* (这是必填项)
*/
private String patientSex;
/**
* 患者出生日期
* (应该是年龄和出生日期填一个,另一个自动计算)
* 但是为了便于处理,我们只让用户输入出生日期
*/
private Long patientBirthday;
/**
* 患者年龄
* (由计算得到,不需要填)
*/
private Integer patientAge;
/**
* 患者身份证号(末尾有x的情况也需要考虑)
* 这个很重要,是区分不同患者身份的依据
* 一定是18位的
* 正则表达式是这样的
* "^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$"
*/
private String patientIDNumber;
/**
* 患者的家庭住址
*/
private String patientAddress;
/**
* 患者的挂号历史
* 用List储存
*/
private List<RegisterInfo> registerInfoList;
/**
* 患者收费记录
*/
private AllChargeItemsList chargeInfo;
/**
* 患者被开药记录
*/
private AllPrescriptionsMap prescriptionMap;
public Patient(Integer patientId, String patientName, String patientSex,
Long patientBirthday, String patientIDNumber,
String patientAddress, List<RegisterInfo> registerInfoList,
AllChargeItemsList chargeInfo, AllPrescriptionsMap prescriptionMap) {
super();
this.patientId = patientId;
this.patientName = patientName;
this.patientSex = patientSex;
this.patientBirthday = patientBirthday;
this.patientAge = TimeCalculator.calculateAge(patientBirthday);
this.patientIDNumber = patientIDNumber;
this.patientAddress = patientAddress;
this.registerInfoList = registerInfoList;
this.chargeInfo = chargeInfo;
this.prescriptionMap = prescriptionMap;
}
@Override
public Boolean add(RegisterInfo item) {
// TODO Auto-generated method stub
if (item == null) {
return false;
} else if (getElement(item.getRegisterId()) != null) {
return false;
}
registerInfoList.add(item);
return true;
}
@Override
public Boolean remove(RegisterInfo item) {
if (item == null) {
return false;
}
RegisterInfo searchItem = getElement(item.getRegisterId());
if (searchItem == null) {
return false;
}
registerInfoList.remove(searchItem);
return true;
}
@Override
public RegisterInfo getElement(Integer index) {
RegisterInfo registerInfo = null;
for (RegisterInfo item : registerInfoList) {
if (item.getRegisterId() != null && index.equals(item.getRegisterId())) {
registerInfo = item;
break;
}
}
return registerInfo;
}
@Override
public List<RegisterInfo> getList() {
return registerInfoList;
}
@Override
public Integer getSize() {
if (registerInfoList != null) {
return registerInfoList.size();
}
return -1;
}
public Integer getPatientId() {
return patientId;
}
public void setPatientId(Integer patientId) {
this.patientId = patientId;
}
public String getPatientName() {
return patientName;
}
public void setPatientName(String patientName) {
this.patientName = patientName;
}
public String getPatientSex() {
return patientSex;
}
public void setPatientSex(String patientSex) {
this.patientSex = patientSex;
}
public Long getPatientBirthday() {
return patientBirthday;
}
public void setPatientBirthday(Long patientBirthday) {
this.patientBirthday = patientBirthday;
}
public Integer getPatientAge() {
return patientAge;
}
public String getPatientIDNumber() {
return patientIDNumber;
}
public void setPatientIDNumber(String patientIDNumber) {
this.patientIDNumber = patientIDNumber;
}
public String getPatientAddress() {
return patientAddress;
}
public void setPatientAddress(String patientAddress) {
this.patientAddress = patientAddress;
}
public List<RegisterInfo> getRegisterInfoList() {
return registerInfoList;
}
public void setRegisterInfoList(List<RegisterInfo> registerInfoList) {
this.registerInfoList = registerInfoList;
}
/**
* 调用util包里的方法
* @param patientBirthday
* @return
*/
public Integer getAge(Long patientBirthday) {
return TimeCalculator.calculateAge(patientBirthday);
}
public AllChargeItemsList getChargeInfo() {
return chargeInfo;
}
public void setChargeInfo(AllChargeItemsList chargeInfo) {
this.chargeInfo = chargeInfo;
}
public AllPrescriptionsMap getPrescriptionMap() {
return prescriptionMap;
}
public void setPrescriptionMap(AllPrescriptionsMap prescriptionMap) {
this.prescriptionMap = prescriptionMap;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((patientIDNumber == null) ? 0 : patientIDNumber.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Patient other = (Patient) obj;
if (patientIDNumber == null) {
if (other.patientIDNumber != null)
return false;
} else if (!patientIDNumber.equals(other.patientIDNumber))
return false;
return true;
}
}
重载构造器,比较复杂
这种确实麻烦点,可能有多种情况,为了外部构造的方便,会考虑一些默认情况。
但是我不希望出现null,所以比如集合,会new一下。
这种写法另起炉灶(其实可以考虑用this(),调用已有构造器)
import java.io.Serializable;
import java.util.*;
/**
* 疾病类型类
* 这是疾病树的结点
*/
public class DiseaseType implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 疾病ID
*/
private Integer diseaseId;
/**
* 疾病名称
*/
private String diseaseName;
/**
* 疾病上一级分类
*/
private DiseaseType parentDiseaseName;
/**
* 疾病下属子分类集合
*/
private Map<String, DiseaseType> subIllnessesMap;
/**
* 下属病人的集合
*/
private List<PatientInfo> patientSet;
public DiseaseType(Integer diseaseId, String diseaseName) {
this.diseaseId = diseaseId;
this.diseaseName = diseaseName;
this.parentDiseaseName = null;
this.subIllnessesMap = new HashMap<>();
this.patientSet = new ArrayList<>();
}
public DiseaseType(Integer diseaseId, String diseaseName, DiseaseType parentDiseaseName,
Map<String, DiseaseType> subIllnessesMap) {
this.diseaseId = diseaseId;
this.diseaseName = diseaseName;
this.parentDiseaseName = parentDiseaseName;
this.subIllnessesMap = subIllnessesMap;
this.patientSet = new ArrayList<>();
}
public DiseaseType(Integer diseaseId, String diseaseName, DiseaseType parentDiseaseName,
Map<String, DiseaseType> subIllnessesMap, List<PatientInfo> patientSet) {
this.diseaseId = diseaseId;
this.diseaseName = diseaseName;
this.parentDiseaseName = parentDiseaseName;
this.subIllnessesMap = subIllnessesMap;
this.patientSet = patientSet;
}
public String getDiseaseName() {
return diseaseName;
}
public void setDiseaseName(String diseaseName) {
this.diseaseName = diseaseName;
}
public Integer getDiseaseId() {
return diseaseId;
}
public void setDiseaseId(Integer diseaseId) {
this.diseaseId = diseaseId;
}
public DiseaseType getParentDiseaseName() {
return parentDiseaseName;
}
public void setParentDiseaseName(DiseaseType parentDiseaseName) {
this.parentDiseaseName = parentDiseaseName;
}
public Map<String, DiseaseType> getSubIllnessesMap() {
return subIllnessesMap;
}
public void setSubIllnessesMap(Map<String, DiseaseType> subIllnessesMap) {
this.subIllnessesMap = subIllnessesMap;
}
public List<PatientInfo> getPatientSet() {
return patientSet;
}
public void setPatientSet(List<PatientInfo> patientSet) {
this.patientSet = patientSet;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DiseaseType that = (DiseaseType) o;
return diseaseName.equals(that.diseaseName);
}
@Override
public int hashCode() {
return Objects.hash(diseaseName);
}
@Override
public String toString() {
return diseaseName;
}
}
感想
有时间的话,这个构造器诶,还是要好好设计啊……
来源:CSDN
作者:进阶的JFarmer
链接:https://blog.csdn.net/weixin_43896318/article/details/103485341