patternjavaMinor
System to process data from a specific client
Viewed 0 times
processsystemclientspecificfromdata
Problem
I'm working on an important project. We're an IT services provider and we have a project where we have to build a new system to process data from a specific client.
The problem is that usually we process their data, but they send us a pre-processed data that's easy to parse, but this time around, they're trying with a new format, which is extremely weird.
Anyways, there were two senior programmers that didn't want to mess with the project, and it's been on hold for one whole year. I'm a junior programmer and I managed to build a system that kind of works as intended but I want to improve on it. I don't like the way it ended up, even if it works.
The thing is, this format is for generating account statements for a local bank, and they're sending in RAW data. I managed to read and parse the data by using a configuration file that's able to read the data from it's position on the file, which can have up to 500 MB of text data. I built a
The data comes grouped in
I only use one
I feel that my approach is kind of stupid, even if it works, and I'd like to improve it and make it more clean. Right now the whole system has like 25 different classes and I feel that my solution is too disorganized. Any advice on how to improve on my design?
I'm going to just include the code for the
The problem is that usually we process their data, but they send us a pre-processed data that's easy to parse, but this time around, they're trying with a new format, which is extremely weird.
Anyways, there were two senior programmers that didn't want to mess with the project, and it's been on hold for one whole year. I'm a junior programmer and I managed to build a system that kind of works as intended but I want to improve on it. I don't like the way it ended up, even if it works.
The thing is, this format is for generating account statements for a local bank, and they're sending in RAW data. I managed to read and parse the data by using a configuration file that's able to read the data from it's position on the file, which can have up to 500 MB of text data. I built a
loadInfo() method that uses reflection to fill in the data in the different classes.The data comes grouped in
Registers, which have many fields. Each Register holds specific information, like transactions, client info, balances and stuff. I created a superclass called Register, and then made the other corresponding types of register extend from this superclass. The thing is that there are 17 different kinds of registers, and a Register can have from 1 to more than 30 members.I only use one
loadInfo() from the Register superclass, and using reflection I can set the member variables for all the other registers.I feel that my approach is kind of stupid, even if it works, and I'd like to improve it and make it more clean. Right now the whole system has like 25 different classes and I feel that my solution is too disorganized. Any advice on how to improve on my design?
I'm going to just include the code for the
Registry that contains the information for the client. We are talking about bank data here, and this code Solution
It's been a while since I asked this question and I'm still working on this project, so far, these are the refactorings that I've been able to make so far.
First, I changed the way all Registers are created, and then modified the parent Registry class like this:
In my first implementation, I couldn't control very well the way that the Registry's childs were created since I used reflection to access all private members of each Registry sub-class and created them by using Campo's constructors, which didn't give me much control on their creation.
Here's the modified RegistroCL that holds the client's information:
Here's the new ClientInfo class:
```
import java.util.List;
public class ClientInfo {
private List _dataSource;
private String _name;
private String _firstLastName;
private String _secondLastName;
private PhysicalAddress _physicalAddress;
private String _email;
public ClientInfo(List dataSource) {
_dataSource = dataSource;
create();
}
public void create() {
_name = _dataSource.get(0).getFieldValue();
_firstLastName = _dataSource.get(1).getFieldValue();
_secondLastName = _dataSource.get(2).getFieldValue();
_email = _dataSource.get(4).getFieldValue().trim().toUpperCase();
_physicalAddress = new PhysicalAddress(_dataSource);
}
public String getFullName() {
return getName() + getFirstLastName() + getSecondLastName();
}
First, I changed the way all Registers are created, and then modified the parent Registry class like this:
import java.util.ArrayList;
import java.util.List;
public abstract class Registro {
// dataReg holds information about the starting position, length and decimal places
// for all the fields that make up the Registry
private String dataReg;
private String idReg; // registry ID
private String[] fields;
protected List fieldValues;
public Registro(){
}
public Registro(String dataReg){
this();
this.setDataRegistro(dataReg);
}
public void setDataRegistro(String dataReg){
this.fields= dataReg.split("\\|");
}
public void loadInfo(String rawData) {
this.setListaValores(rawData);
callSetters();
}
public void setListaValores(String rawData) {
this.fieldValues= new ArrayList();
for(String valor : getCampos()) {
this.fieldValues.add(new Campo(Campo.getField(valor, rawData, "_")));
}
}
public String[] getCampos() {
return this.fields;
}
public abstract void callSetters();
public void setIdRegistro(String idReg){
this.idReg = idReg;
}
public List getListaValores() {
return this.fieldValues;
}
public String getDataRegistro(){
return this.dataReg;
}
public String getIdRegistro(){
return this.idReg;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return this.buildString();
}
protected abstract String buildString();
}In my first implementation, I couldn't control very well the way that the Registry's childs were created since I used reflection to access all private members of each Registry sub-class and created them by using Campo's constructors, which didn't give me much control on their creation.
Here's the modified RegistroCL that holds the client's information:
public class RegistroCL extends Registro{
private ClientInfo _person;
public RegistroCL(String dataReg){
super(dataReg);
setIdRegistro("CL");
}
public String getFullName() {
return _person.getFullName();
}
public String getName() {
return _person.getName();
}
public String getFirstLastName() {
return _person.getFirstLastName();
}
public String getSecondLastName() {
return _person.getSecondLastName();
}
public String getPhysicalAddress(){
return _person.getPhysicalAddress();
}
public String getEmail() {
return _person.getEmail();
}
public String getDesProv() {
return _person.getProvincia();
}
public String getMunicipio() {
return _person.getMunicipio();
}
public String getSector() {
return _person.getSector();
}
public String getStreet() {
return _person.getStreet();
}
public String getBuildingNumber() {
return _person.getBuildingNumber();
}
public String getFloorNumber() {
return _person.getFloorNumber();
}
public String getApartmentNumber() {
return _person.getApartmentNumber();
}
public String getBlock() {
return _person.getBlock();
}
public String getBuildingName() {
return _person.getBuildingName();
}
public String getDesEntreCalles1() {
return _person.getDesEntreCalles1();
}
public String getDesEntreCalles2() {
return _person.getDesEntreCalles2();
}
@Override
public void callSetters() {
_person = new ClientInfo(this.getListaValores());
}
@Override
protected String buildString() {
String output = this.getName();
output = output.concat(" " + this.getFirstLastName());
output = output.concat(" " + this.getSecondLastName() + "\n");
return output;
}
}Here's the new ClientInfo class:
```
import java.util.List;
public class ClientInfo {
private List _dataSource;
private String _name;
private String _firstLastName;
private String _secondLastName;
private PhysicalAddress _physicalAddress;
private String _email;
public ClientInfo(List dataSource) {
_dataSource = dataSource;
create();
}
public void create() {
_name = _dataSource.get(0).getFieldValue();
_firstLastName = _dataSource.get(1).getFieldValue();
_secondLastName = _dataSource.get(2).getFieldValue();
_email = _dataSource.get(4).getFieldValue().trim().toUpperCase();
_physicalAddress = new PhysicalAddress(_dataSource);
}
public String getFullName() {
return getName() + getFirstLastName() + getSecondLastName();
}
Code Snippets
import java.util.ArrayList;
import java.util.List;
public abstract class Registro {
// dataReg holds information about the starting position, length and decimal places
// for all the fields that make up the Registry
private String dataReg;
private String idReg; // registry ID
private String[] fields;
protected List<Campo> fieldValues;
public Registro(){
}
public Registro(String dataReg){
this();
this.setDataRegistro(dataReg);
}
public void setDataRegistro(String dataReg){
this.fields= dataReg.split("\\|");
}
public void loadInfo(String rawData) {
this.setListaValores(rawData);
callSetters();
}
public void setListaValores(String rawData) {
this.fieldValues= new ArrayList<Campo>();
for(String valor : getCampos()) {
this.fieldValues.add(new Campo(Campo.getField(valor, rawData, "_")));
}
}
public String[] getCampos() {
return this.fields;
}
public abstract void callSetters();
public void setIdRegistro(String idReg){
this.idReg = idReg;
}
public List<Campo> getListaValores() {
return this.fieldValues;
}
public String getDataRegistro(){
return this.dataReg;
}
public String getIdRegistro(){
return this.idReg;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return this.buildString();
}
protected abstract String buildString();
}public class RegistroCL extends Registro{
private ClientInfo _person;
public RegistroCL(String dataReg){
super(dataReg);
setIdRegistro("CL");
}
public String getFullName() {
return _person.getFullName();
}
public String getName() {
return _person.getName();
}
public String getFirstLastName() {
return _person.getFirstLastName();
}
public String getSecondLastName() {
return _person.getSecondLastName();
}
public String getPhysicalAddress(){
return _person.getPhysicalAddress();
}
public String getEmail() {
return _person.getEmail();
}
public String getDesProv() {
return _person.getProvincia();
}
public String getMunicipio() {
return _person.getMunicipio();
}
public String getSector() {
return _person.getSector();
}
public String getStreet() {
return _person.getStreet();
}
public String getBuildingNumber() {
return _person.getBuildingNumber();
}
public String getFloorNumber() {
return _person.getFloorNumber();
}
public String getApartmentNumber() {
return _person.getApartmentNumber();
}
public String getBlock() {
return _person.getBlock();
}
public String getBuildingName() {
return _person.getBuildingName();
}
public String getDesEntreCalles1() {
return _person.getDesEntreCalles1();
}
public String getDesEntreCalles2() {
return _person.getDesEntreCalles2();
}
@Override
public void callSetters() {
_person = new ClientInfo(this.getListaValores());
}
@Override
protected String buildString() {
String output = this.getName();
output = output.concat(" " + this.getFirstLastName());
output = output.concat(" " + this.getSecondLastName() + "\n");
return output;
}
}import java.util.List;
public class ClientInfo {
private List<Campo> _dataSource;
private String _name;
private String _firstLastName;
private String _secondLastName;
private PhysicalAddress _physicalAddress;
private String _email;
public ClientInfo(List<Campo> dataSource) {
_dataSource = dataSource;
create();
}
public void create() {
_name = _dataSource.get(0).getFieldValue();
_firstLastName = _dataSource.get(1).getFieldValue();
_secondLastName = _dataSource.get(2).getFieldValue();
_email = _dataSource.get(4).getFieldValue().trim().toUpperCase();
_physicalAddress = new PhysicalAddress(_dataSource);
}
public String getFullName() {
return getName() + getFirstLastName() + getSecondLastName();
}
public String getName() {
return String.format("%1$-40s", _name);
}
public String getFirstLastName() {
return String.format("%1$-36s",
appendCharacterToOriginalStringIfNotEmpty(_firstLastName, ' '));
}
private String appendCharacterToOriginalStringIfNotEmpty(String str, char appendWhat) {
return !str.isEmpty() ? appendWhat + str : "";
}
public String getSecondLastName() {
return String.format("%1$-36s",
appendCharacterToOriginalStringIfNotEmpty(_secondLastName, ' '));
}
public String getEmail() {
return (_email.isEmpty() ? "--" : "EMAIL: " + _email);
}
public String getPhysicalAddress() {
return _physicalAddress.getDireccion();
}
public String getProvincia() {
return _physicalAddress.getProvincia();
}
public String getMunicipio() {
return _physicalAddress.getMunicipio();
}
public String getSector() {
return _physicalAddress.getSector();
}
public String getStreet() {
return _physicalAddress.getStreet();
}
public String getBuildingNumber() {
return _physicalAddress.getBuildingNumber();
}
public String getFloorNumber() {
return _physicalAddress.getFloorNumber();
}
public String getApartmentNumber() {
return _physicalAddress.getApartmentNumber();
}
public String getBlock() {
return _physicalAddress.getBlock();
}
public String getBuildingName() {
return _physicalAddress.getBuildingName();
}
public String getDesEntreCalles1() {
return _physicalAddress.getDesEntreCalles1();
}
public String getDesEntreCalles2() {
return _physicalAddress.getDesEntreCalles2();
}
}import java.util.List;
public class PhysicalAddress {
private List<Campo> _clientData;
private String _street;
private String _buildingNumber;
private String _block;
private String _buildingName;
private String _floorNumber;
private String _apartmentNumber;
private String _entreCalle1;
private String _entreCalle2;
private String _municipio;
private String _sector;
private String _provincia;
public PhysicalAddress(List<Campo> clientData){
_clientData = clientData;
create();
}
public void create() {
_provincia = _clientData.get(10).getFieldValue();
_sector = _clientData.get(16).getFieldValue();
_street = _clientData.get(21).getFieldValue();
_buildingNumber = _clientData.get(22).getFieldValue();
_floorNumber = _clientData.get(24).getFieldValue();
_apartmentNumber = _clientData.get(25).getFieldValue();
_block = _clientData.get(26).getFieldValue();
_buildingName = _clientData.get(27).getFieldValue();
_entreCalle1 = _clientData.get(32).getFieldValue();
_entreCalle2 = _clientData.get(34).getFieldValue();
setMunicipio();
}
public void setMunicipio() {
_municipio = String.format("\n %s, %s", getSector(), getProvincia());
}
public String getSector() {
return _sector;
}
public String getProvincia() {
return _provincia;
}
public String getDireccion(){
return getStreet() + getBuildingNumber() + getBlock() + getBuildingName() +
getFloorNumber() + getApartmentNumber() + getDesEntreCalles1() +
getDesEntreCalles2() + getMunicipio();
}
public String getStreet() {
return (_street.isEmpty() ? "" : "C/ " + _street + " ");
}
public String getBuildingNumber() {
return (_buildingNumber.isEmpty() ? "" : "#" + _buildingNumber + " ");
}
public String getBlock() {
return (_block.isEmpty() ? "" : "MANZ. " + _block + " ");
}
public String getBuildingName() {
return (_buildingName.isEmpty() ? "" : "EDIF. " + _buildingName + " ");
}
public String getFloorNumber() {
return (_floorNumber.isEmpty() ? "" : "PISO: " + _floorNumber + " ");
}
public String getApartmentNumber() {
return (_apartmentNumber.isEmpty() ? "" : "APTO. " + _apartmentNumber + " " );
}
public String getDesEntreCalles1() {
return (_entreCalle1.isEmpty() ? "\n --" : "\n ENTRE ") + _entreCalle1;
}
public String getDesEntreCalles2() {
return (_entreCalle2.isEmpty() ? "\n --" : "\n Y ") + _entreCalle2;
}
public String getMunicipio() {
return _municipio;
}
public PhysicalAddress getPhysicalAddress(){
return this;
}
}CL999999999999AAAAA AAAAAAAA AAAAAAAA AAAA AAAAAAAAAAA@BBBBB.CCC.DD 999AAA. AAAAAAAAAA 9 AAAAAA AAA AAAA 99AAAA AAA 99 AAAAAAAA AAAAAAAA 999 AAAA AAA 9999 AA AAAAAAAAA 99999AA AAAAAA AA9999999 AA AAAAAAA 999 9999999 AAAAAAA / AAAAAAA AAAAA AAAAAAA AAAAAAAAContext
StackExchange Code Review Q#142514, answer score: 2
Revisions (0)
No revisions yet.