The First 100 Hours: Commonality and Variability AnalysisJason Cheong-Kee-You  @jpcky www.mightyjupiter.com   Alistair McK...
Commonality andVariability Analysis
Commonality and   Variability AnalysisAvoiding Duplicate Code
Exercise
Exercise1. Did you write any code last year?   If so, how many lines of code?2. How many lines of code in your   code base...
Code Visibility
Code Visibility
Code Visibility
Avoiding Duplicate Code
Avoiding Duplicate Code
Avoiding Duplicate Code     DRY: Don’t Repeat Yourself
Avoiding Duplicate Code     DRY: Don’t Repeat Yourself     Every piece of knowledge must have     a single, unambiguous, a...
Avoiding Duplicate Code
Avoiding Duplicate Code     Once and Only Once
Avoiding Duplicate Code     Once and Only Once     Data, structure, or logic should exist     in only one place in the sys...
Avoiding Duplicate Code
Avoiding Duplicate Code     Test-Driven Development
Avoiding Duplicate Code     Test-Driven Development     1. Write new code only if an        automated test has failed.
Avoiding Duplicate Code     Test-Driven Development     1. Write new code only if an        automated test has failed.    ...
Avoiding Duplicate Code
Avoiding Duplicate Code     Single Choice Principle
Avoiding Duplicate Code     Single Choice Principle     Whenever a software system must     support a set of alternatives,...
Avoiding Duplicate Code
Avoiding Duplicate Code     Duplication may be the     root of all evil in software.
Exercise
Exercise
ExerciseWhat are the consequences ofduplicate code?
ExerciseWhat are the consequences ofduplicate code?Consider both good and evil.
Exercise
Exercise
ExerciseHow does duplicate codecome about?
ExerciseHow does duplicate codecome about?Make a Top 3 list.
Alistair’s Contention
Alistair’s ContentionCopy and Paste leads to thecreation of duplicate code.
Alistair’s ContentionCopy and Paste leads to thecreation of duplicate code.Developers lack the thinking toolsand the devel...
Duplicate Code:Select Options
Select Optionspublic static List<SelectOption> createEndMonthList(Date expiryDate) {    List<SelectOption> monthList = new...
Select Optionspublic static List<SelectOption> createEndMonthList(Date expiryDate) {    List<SelectOption> monthList = new...
Select Optionspublic static List<SelectOption> createEndMonthList(Date expiryDate) {    List<SelectOption> monthList = new...
Select Optionspublic static List<SelectOption> createEndMonthList(Date expiryDate) {    List<SelectOption> monthList = new...
Select Optionspublic static List<SelectOption> createEndMonthList(Date expiryDate) {    List<SelectOption> monthList = new...
Select Optionspublic static List<SelectOption> createEndMonthList(Date expiryDate) {    List<SelectOption> monthList = new...
Select Options           SelectOptions                       SelectOptionsSourcecreate()                                  ...
Select Options           SelectOptions               SelectOptionsSourcecreate()                          getFirst()      ...
Select Options           SelectOptions                      SelectOptionsSourcecreate()                                  g...
Select Options           SelectOptions               SelectOptionsSourcecreate()                           getFirst()     ...
Duplicate Code:Select Options Extra
Select Options Extrapublic static List<SelectOption> createProvinceList(String selectedProvince){    List<SelectOption> pr...
Select Options Extrapublic static List<SelectOption> createProvinceList(String selectedProvince){    List<SelectOption> pr...
Select Options ExtraList<String> provinces = asList("AB", "BC", "MB", "NB", "NL",            "NT", "NS", "NU", "ON", "PE",...
Select Options ExtraList<String> provinces = asList("AB", "BC", "MB", "NB", "NL",            "NT", "NS", "NU", "ON", "PE",...
Select Options Extrapublic enum Province {    AB, BC, MB, NB, NL, NT, NS, NU, ON, PE, QC, SK, YT;}                    Sing...
Select Options Extrapublic static List<SelectOption> createEndMonthList(Date expiryDate) {    for (int intLooper = 1; intL...
Select Options Extrapublic static List<SelectOption> createEndMonthList(Date expiryDate) {    for (int intLooper = 1; intL...
Select Options Extrapublic static List<SelectOption> createEndMonthList(Date expiryDate) {    for (int intLooper = 1; intL...
Select Options Extrapublic static List<SelectOption> createEndMonthList(Date expiryDate) {    for (int intLooper = 1; intL...
Select Options Extra                                                                      String                          ...
Select Options Extra                                                                      String                          ...
Select Options Extra                                                                           String                     ...
Select Options Extra                                                                           String                     ...
Select Options Extra                                                                          String                      ...
Duplicate Code:Compound Result Handler
Compound Result Handlerpublic Collection<IRegCommand> processCompondResults(Patient sourcePatient, Collection<Result> resu...
Compound Result Handlerpublic Collection<IRegCommand> processCompondResults(Patient sourcePatient, Collection<Result> resu...
Compound Result Handlerpublic Collection<IRegCommand> processCompondResults(Patient sourcePatient, Collection<Result> resu...
Compound Result Handler    CompoundResultHandler                CompoundResultClassifier                                   ...
Compound Result Handler      CompoundResultHandler                CompoundResultClassifier                                 ...
Compound Result Handler       CompoundResultHandler                CompoundResultClassifier                                ...
Code Visibility
Reading
Reading
ReadingThe Pragmatic Programmer: From Journeyman to MasterAndrew Hunt and Dave ThomasExtreme Programming Explained: Embrac...
ReadingClean Code: A Handbook of Agile SoftwareCraftsmanship Robert C. MartinDesign Patterns: Elements of Reusable Object-...
Photo Creditshttp://www.flickr.com/photos/27558040@N00/4151899795/http://www.flickr.com/photos/popilop/331357312/http://www....
Commonality and Variability Analysis: Avoiding Duplicate Code
Commonality and Variability Analysis: Avoiding Duplicate Code
Commonality and Variability Analysis: Avoiding Duplicate Code
Upcoming SlideShare
Loading in...5
×

Commonality and Variability Analysis: Avoiding Duplicate Code

2,541

Published on

Duplicate code is something to be avoided. And yet, everyday developers make copies of working code, make edits to the copy, and create duplicate code.

Some developers have the discipline and the skill to refactor to eliminate this duplicate code. Many do not.

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,541
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
22
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Commonality and Variability Analysis: Avoiding Duplicate Code

    1. 1. The First 100 Hours: Commonality and Variability AnalysisJason Cheong-Kee-You @jpcky www.mightyjupiter.com Alistair McKinnell@amckinnell www.valuablecode.com
    2. 2. Commonality andVariability Analysis
    3. 3. Commonality and Variability AnalysisAvoiding Duplicate Code
    4. 4. Exercise
    5. 5. Exercise1. Did you write any code last year? If so, how many lines of code?2. How many lines of code in your code base?3. Percentage of duplicate code?
    6. 6. Code Visibility
    7. 7. Code Visibility
    8. 8. Code Visibility
    9. 9. Avoiding Duplicate Code
    10. 10. Avoiding Duplicate Code
    11. 11. Avoiding Duplicate Code DRY: Don’t Repeat Yourself
    12. 12. Avoiding Duplicate Code DRY: Don’t Repeat Yourself Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
    13. 13. Avoiding Duplicate Code
    14. 14. Avoiding Duplicate Code Once and Only Once
    15. 15. Avoiding Duplicate Code Once and Only Once Data, structure, or logic should exist in only one place in the system.
    16. 16. Avoiding Duplicate Code
    17. 17. Avoiding Duplicate Code Test-Driven Development
    18. 18. Avoiding Duplicate Code Test-Driven Development 1. Write new code only if an automated test has failed.
    19. 19. Avoiding Duplicate Code Test-Driven Development 1. Write new code only if an automated test has failed. 2. Eliminate duplication.
    20. 20. Avoiding Duplicate Code
    21. 21. Avoiding Duplicate Code Single Choice Principle
    22. 22. Avoiding Duplicate Code Single Choice Principle Whenever a software system must support a set of alternatives, one and only one module in the system should know their exhaustive list.
    23. 23. Avoiding Duplicate Code
    24. 24. Avoiding Duplicate Code Duplication may be the root of all evil in software.
    25. 25. Exercise
    26. 26. Exercise
    27. 27. ExerciseWhat are the consequences ofduplicate code?
    28. 28. ExerciseWhat are the consequences ofduplicate code?Consider both good and evil.
    29. 29. Exercise
    30. 30. Exercise
    31. 31. ExerciseHow does duplicate codecome about?
    32. 32. ExerciseHow does duplicate codecome about?Make a Top 3 list.
    33. 33. Alistair’s Contention
    34. 34. Alistair’s ContentionCopy and Paste leads to thecreation of duplicate code.
    35. 35. Alistair’s ContentionCopy and Paste leads to thecreation of duplicate code.Developers lack the thinking toolsand the development skills to avoidthe duplication.
    36. 36. Duplicate Code:Select Options
    37. 37. Select Optionspublic static List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption> monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate); for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } monthList.add(option); } return monthList;}
    38. 38. Select Optionspublic static List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption> monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate); for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } monthList.add(option); } return monthList;}
    39. 39. Select Optionspublic static List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption> monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate); for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } monthList.add(option); } return monthList;}
    40. 40. Select Optionspublic static List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption> monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate); for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } monthList.add(option); } return monthList;}
    41. 41. Select Optionspublic static List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption> monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate); for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } monthList.add(option); } return monthList;}
    42. 42. Select Optionspublic static List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption> monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate); for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } monthList.add(option); } return monthList;}
    43. 43. Select Options SelectOptions SelectOptionsSourcecreate() getFirst() getLast() isSelected() Commonality Variability Resolution Data Structure Value of State Simple Java Type
    44. 44. Select Options SelectOptions SelectOptionsSourcecreate() getFirst() getLast() isSelected() Parameter Object
    45. 45. Select Options SelectOptions SelectOptionsSourcecreate() getFirst() getLast() isSelected() Commonality Variability Resolution Encapsulate Behaviour Collaborator Collection
    46. 46. Select Options SelectOptions SelectOptionsSourcecreate() getFirst() getLast() isSelected() Encapsulate Collection
    47. 47. Duplicate Code:Select Options Extra
    48. 48. Select Options Extrapublic static List<SelectOption> createProvinceList(String selectedProvince){ List<SelectOption> provinceList = new ArrayList<SelectOption>(); List<String> provinces = asList("AB", "BC", "MB", "NB", "NL", "NT", "NS", "NU", "ON", "PE", "QC", "SK", "YT"); for (int intLooper = 0; intLooper < provinces.size(); intLooper++) { SelectOption option = new SelectOption(); if (selectedProvince.equals(provinces.get(intLooper))) { option.setLabel(provinces.get(intLooper)); option.setValue(provinces.get(intLooper)); option.setSelected(true); } else { option.setLabel(provinces.get(intLooper)); option.setValue(provinces.get(intLooper)); option.setSelected(false); } provinceList.add(option); } return provinceList;}
    49. 49. Select Options Extrapublic static List<SelectOption> createProvinceList(String selectedProvince){ List<SelectOption> provinceList = new ArrayList<SelectOption>(); List<String> provinces = asList("AB", "BC", "MB", "NB", "NL", "NT", "NS", "NU", "ON", "PE", "QC", "SK", "YT"); for (int intLooper = 0; intLooper < provinces.size(); intLooper++) { SelectOption option = new SelectOption(); if (selectedProvince.equals(provinces.get(intLooper))) { option.setLabel(provinces.get(intLooper)); option.setValue(provinces.get(intLooper)); option.setSelected(true); } else { option.setLabel(provinces.get(intLooper)); option.setValue(provinces.get(intLooper)); option.setSelected(false); } provinceList.add(option); } return provinceList;}
    50. 50. Select Options ExtraList<String> provinces = asList("AB", "BC", "MB", "NB", "NL", "NT", "NS", "NU", "ON", "PE", "QC", "SK", "YT");
    51. 51. Select Options ExtraList<String> provinces = asList("AB", "BC", "MB", "NB", "NL", "NT", "NS", "NU", "ON", "PE", "QC", "SK", "YT");public enum Province { AB, BC, MB, NB, NL, NT, NS, NU, ON, PE, QC, SK, YT;} Commonality Variability Resolution A small set of Data Structure enum values
    52. 52. Select Options Extrapublic enum Province { AB, BC, MB, NB, NL, NT, NS, NU, ON, PE, QC, SK, YT;} Single Choice Principle Whenever a software system must support a set of alternatives, one and only one module in the system should know their exhaustive list.
    53. 53. Select Options Extrapublic static List<SelectOption> createEndMonthList(Date expiryDate) { for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper));}public static List<SelectOption> createProvinceList(String selectedProvince){ for (int intLooper = 0; intLooper < provinces.size(); intLooper++) { SelectOption option = new SelectOption(); if (selectedProvince.equals(provinces.get(intLooper))) { option.setLabel(provinces.get(intLooper));}
    54. 54. Select Options Extrapublic static List<SelectOption> createEndMonthList(Date expiryDate) { for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper));}public static List<SelectOption> createProvinceList(String selectedProvince){ for (int intLooper = 0; intLooper < provinces.size(); intLooper++) { SelectOption option = new SelectOption(); if (selectedProvince.equals(provinces.get(intLooper))) { option.setLabel(provinces.get(intLooper));}
    55. 55. Select Options Extrapublic static List<SelectOption> createEndMonthList(Date expiryDate) { for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper));}public static List<SelectOption> createProvinceList(String selectedProvince){ for (int intLooper = 0; intLooper < provinces.size(); intLooper++) { SelectOption option = new SelectOption(); if (selectedProvince.equals(provinces.get(intLooper))) { option.setLabel(provinces.get(intLooper));}
    56. 56. Select Options Extrapublic static List<SelectOption> createEndMonthList(Date expiryDate) { for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper));}public static List<SelectOption> createProvinceList(String selectedProvince){ for (int intLooper = 0; intLooper < provinces.size(); intLooper++) { SelectOption option = new SelectOption(); if (selectedProvince.equals(provinces.get(intLooper))) { option.setLabel(provinces.get(intLooper));}
    57. 57. Select Options Extra String Iterable iterator() SelectOptions SelectOptionsSource create() isSelected() IntegerRangeSource ProvinceSource iterator() iterator() isSelected() isSelected()
    58. 58. Select Options Extra String Iterable iterator() SelectOptions SelectOptionsSource create() isSelected() IntegerRangeSource ProvinceSource iterator() iterator() isSelected() isSelected()
    59. 59. Select Options Extra String Iterable iterator() SelectOptions SelectOptionsSource create() isSelected() IntegerRangeSource ProvinceSource iterator() iterator() isSelected() isSelected()Commonality Variability Resolution Collection Values Iterator
    60. 60. Select Options Extra String Iterable iterator() SelectOptions SelectOptionsSource create() isSelected() IntegerRangeSource ProvinceSource iterator() iterator() isSelected() isSelected()Commonality Variability Resolution Collection Type Generics
    61. 61. Select Options Extra String Iterable iterator() SelectOptions SelectOptionsSource create() isSelected() IntegerRangeSource ProvinceSource iterator() iterator() isSelected() isSelected()Commonality Variability Resolution Inheritance Behaviour Implementation (Object-Oriented)
    62. 62. Duplicate Code:Compound Result Handler
    63. 63. Compound Result Handlerpublic Collection<IRegCommand> processCompondResults(Patient sourcePatient, Collection<Result> results) { Collection<IRegCommand> retVal = new ArrayList<IRegCommand>(); Set<Result> resultsMarkedForRemoval = new HashSet<Result>(); Set<Result> resultsProcessed = new HashSet<Result>(); for (Result primaryResult : results) { if (isResultProcessed(resultsProcessed, primaryResult)) { continue; } resultsProcessed.add(primaryResult); Result correspondingResult = getCorrespondingResult(primaryResult, results); if (correspondingResult != null) { resultsProcessed.add(correspondingResult); resultsMarkedForRemoval.add(correspondingResult); } if (!sourcePatient.getDataWarehouse().equals(DataWarehouseTag.QHN)) { // If the response to either question is yes then display positive as the measure value. if (primaryResult.getDwValue().equalsIgnoreCase("1")) { primaryResult.setDwValue("POSITIVE"); } else { // If the response to both questions is no then display negative as the measure value. if (correspondingResult != null) { if (correspondingResult.getDwValue().equalsIgnoreCase("2")) { primaryResult.setDwValue("NEGATIVE"); } else if (correspondingResult.getDwValue().equalsIgnoreCase("1")) { // It must be yes - thus value is POSITIVE primaryResult.setDwValue("POSITIVE"); } else { badDataLogger.logBadData(sourcePatient.getExternalId(), Measure.NAME_2ITEMSCREENER, primaryResult.getDwValue() + " (" + primaryResult.getEventDateTime() + ") ", "Issue with multiple PHQ results"); continue; } } else { // No corresponding result - where is the 2nd result? - badDataLogger.logBadData(sourcePatient.getExternalId(), Measure.NAME_2ITEMSCREENER, primaryResult.getDwValue() + " (" + primaryResult.getEventDateTime() + ") ", "No corresponding value found for a 2 item screener with value of no"); continue; } } } else { // If the response to either question is yes then display positive as the measure value. if (primaryResult.getDwValue().equalsIgnoreCase("3") || primaryResult.getDwValue().equalsIgnoreCase("4")) { primaryResult.setDwValue("POSITIVE"); } else { // If the response to both questions is no then display negative as the measure value. if (correspondingResult != null) { if (primaryResult.getDwValue().equalsIgnoreCase("0") || primaryResult.getDwValue().equalsIgnoreCase("1") || primaryResult.getDwValue().equalsIgnoreCase("2")) { primaryResult.setDwValue("NEGATIVE"); } else if (primaryResult.getDwValue().equalsIgnoreCase("3") || primaryResult.getDwValue().equalsIgnoreCase("4")) { // It must be yes - thus value is POSITIVE primaryResult.setDwValue("POSITIVE"); } else { badDataLogger.logBadData(sourcePatient.getExternalId(), Measure.NAME_2ITEMSCREENER, primaryResult.getDwValue() + " (" + primaryResult.getEventDateTime() + ") ", "Issue with multiple PHQ results"); continue; } } else { // No corresponding result - where is the 2nd result? - badDataLogger.logBadData(sourcePatient.getExternalId(), Measure.NAME_2ITEMSCREENER, primaryResult.getDwValue() + " (" + primaryResult.getEventDateTime() + ") ", "No corresponding value found for a 2 item screener with value of no"); continue; } } } Map<String, Object> transformedResult = resultTransformer.transformResult(sourcePatient, primaryResult); if (null != transformedResult) { retVal.add(new PatientDataUpdateCommand(CommandType.RESULT, sourcePatient, transformedResult)); } } return retVal;}
    64. 64. Compound Result Handlerpublic Collection<IRegCommand> processCompondResults(Patient sourcePatient, Collection<Result> results) { Collection<IRegCommand> retVal = new ArrayList<IRegCommand>(); Set<Result> resultsMarkedForRemoval = new HashSet<Result>(); Set<Result> resultsProcessed = new HashSet<Result>(); for (Result primaryResult : results) { if (isResultProcessed(resultsProcessed, primaryResult)) { continue; } resultsProcessed.add(primaryResult); Result correspondingResult = getCorrespondingResult(primaryResult, results); if (correspondingResult != null) { resultsProcessed.add(correspondingResult); } resultsMarkedForRemoval.add(correspondingResult); if (!sourcePatient.getDataWarehouse() if (!sourcePatient.getDataWarehouse().equals(DataWarehouseTag.QHN)) { // If the response to either question is yes then display positive as the measure value. if (primaryResult.getDwValue().equalsIgnoreCase("1")) { primaryResult.setDwValue("POSITIVE"); .equals(DataWarehouseTag.QHN)) { } else { // If the response to both questions is no then display negative as the measure value. if (correspondingResult != null) { if (correspondingResult.getDwValue().equalsIgnoreCase("2")) { primaryResult.setDwValue("NEGATIVE"); } else if (correspondingResult.getDwValue().equalsIgnoreCase("1")) { // It must be yes - thus value is POSITIVE primaryResult.setDwValue("POSITIVE"); } else { badDataLogger.logBadData(sourcePatient.getExternalId(), Measure.NAME_2ITEMSCREENER, primaryResult.getDwValue() + " (" + primaryResult.getEventDateTime() + ") ", "Issue with multiple PHQ results"); continue; } } else { // No corresponding result - where is the 2nd result? - badDataLogger.logBadData(sourcePatient.getExternalId(), Measure.NAME_2ITEMSCREENER, primaryResult.getDwValue() + " (" + primaryResult.getEventDateTime() + ") ", "No corresponding value found for a 2 item screener with value of no"); continue; } } } else { // If the response to either question is yes then display positive as the measure value. if (primaryResult.getDwValue().equalsIgnoreCase("3") || primaryResult.getDwValue().equalsIgnoreCase("4")) { primaryResult.setDwValue("POSITIVE"); } else { // If the response to both questions is no then display negative as the measure value. if (correspondingResult != null) { if (primaryResult.getDwValue().equalsIgnoreCase("0") || primaryResult.getDwValue().equalsIgnoreCase("1") || primaryResult.getDwValue().equalsIgnoreCase("2")) { primaryResult.setDwValue("NEGATIVE"); } else if (primaryResult.getDwValue().equalsIgnoreCase("3") || primaryResult.getDwValue().equalsIgnoreCase("4")) { // It must be yes - thus value is POSITIVE primaryResult.setDwValue("POSITIVE"); } else { badDataLogger.logBadData(sourcePatient.getExternalId(), Measure.NAME_2ITEMSCREENER, primaryResult.getDwValue() + " (" + primaryResult.getEventDateTime() + ") ", "Issue with multiple PHQ results"); continue; } } else { // No corresponding result - where is the 2nd result? - badDataLogger.logBadData(sourcePatient.getExternalId(), Measure.NAME_2ITEMSCREENER, primaryResult.getDwValue() + " (" + primaryResult.getEventDateTime() + ") ", "No corresponding value found for a 2 item screener with value of no"); continue; } } } Map<String, Object> transformedResult = resultTransformer.transformResult(sourcePatient, primaryResult); if (null != transformedResult) { retVal.add(new PatientDataUpdateCommand(CommandType.RESULT, sourcePatient, transformedResult)); } } return retVal;}
    65. 65. Compound Result Handlerpublic Collection<IRegCommand> processCompondResults(Patient sourcePatient, Collection<Result> results) { Collection<IRegCommand> retVal = new ArrayList<IRegCommand>(); Set<Result> resultsMarkedForRemoval = new HashSet<Result>(); Set<Result> resultsProcessed = new HashSet<Result>(); for (Result primaryResult : results) { if (isResultProcessed(resultsProcessed, primaryResult)) { continue; } resultsProcessed.add(primaryResult); Result correspondingResult = getCorrespondingResult(primaryResult, results); if (correspondingResult != null) { resultsProcessed.add(correspondingResult); } resultsMarkedForRemoval.add(correspondingResult); if (!sourcePatient.getDataWarehouse().equals(DataWarehouseTag.QHN)) { if (primaryResult.getDwValue().equalsIgnoreCase("1")) // If the response to either question is yes then display positive as the measure value. if (primaryResult.getDwValue().equalsIgnoreCase("1")) { primaryResult.setDwValue("POSITIVE"); } else { // If the response to both questions is no then display negative as the measure value. if (correspondingResult != null) { if (correspondingResult.getDwValue().equalsIgnoreCase("2")) { primaryResult.setDwValue("NEGATIVE"); } else if (correspondingResult.getDwValue().equalsIgnoreCase("1")) { // It must be yes - thus value is POSITIVE primaryResult.setDwValue("POSITIVE"); } else { badDataLogger.logBadData(sourcePatient.getExternalId(), Measure.NAME_2ITEMSCREENER, primaryResult.getDwValue() + " (" + primaryResult.getEventDateTime() + ") ", "Issue with multiple PHQ results"); continue; } } else { // No corresponding result - where is the 2nd result? - badDataLogger.logBadData(sourcePatient.getExternalId(), Measure.NAME_2ITEMSCREENER, primaryResult.getDwValue() + " (" + primaryResult.getEventDateTime() + ") ", "No corresponding value found for a 2 item screener with value of no"); continue; } } else { } if (primaryResult.getDwValue().equalsIgnoreCase("3") || // If the response to either question is yes then display positive as the measure value. if (primaryResult.getDwValue().equalsIgnoreCase("3") || primaryResult.getDwValue().equalsIgnoreCase("4")) { primaryResult.setDwValue("POSITIVE"); primaryResult.getDwValue().equalsIgnoreCase("4")) } else { // If the response to both questions is no then display negative as the measure value. if (correspondingResult != null) { if (primaryResult.getDwValue().equalsIgnoreCase("0") || primaryResult.getDwValue().equalsIgnoreCase("1") || primaryResult.getDwValue().equalsIgnoreCase("2")) { primaryResult.setDwValue("NEGATIVE"); } else if (primaryResult.getDwValue().equalsIgnoreCase("3") || primaryResult.getDwValue().equalsIgnoreCase("4")) { // It must be yes - thus value is POSITIVE primaryResult.setDwValue("POSITIVE"); } else { badDataLogger.logBadData(sourcePatient.getExternalId(), Measure.NAME_2ITEMSCREENER, primaryResult.getDwValue() + " (" + primaryResult.getEventDateTime() + ") ", "Issue with multiple PHQ results"); continue; } } else { // No corresponding result - where is the 2nd result? - badDataLogger.logBadData(sourcePatient.getExternalId(), Measure.NAME_2ITEMSCREENER, primaryResult.getDwValue() + " (" + primaryResult.getEventDateTime() + ") ", "No corresponding value found for a 2 item screener with value of no"); continue; } } } Map<String, Object> transformedResult = resultTransformer.transformResult(sourcePatient, primaryResult); if (null != transformedResult) { retVal.add(new PatientDataUpdateCommand(CommandType.RESULT, sourcePatient, transformedResult)); } } return retVal;}
    66. 66. Compound Result Handler CompoundResultHandler CompoundResultClassifier isNegative() isPositive() AbstractCompoundResultClassifier toNumber() QueensCompoundResultClassifier StandardCompoundResultClassifier isNegative() isNegative() isPositive() isPositive()
    67. 67. Compound Result Handler CompoundResultHandler CompoundResultClassifier isNegative() isPositive() AbstractCompoundResultClassifier toNumber() QueensCompoundResultClassifier StandardCompoundResultClassifier isNegative() isNegative() isPositive() isPositive() Commonality Variability Resolution Inheritance Behaviour Implementation (Object-Oriented)
    68. 68. Compound Result Handler CompoundResultHandler CompoundResultClassifier isNegative() isPositive() AbstractCompoundResultClassifier toNumber() QueensCompoundResultClassifier StandardCompoundResultClassifier isNegative() isNegative() isPositive() isPositive() Commonality Variability ResolutionImplementation None Base Class
    69. 69. Code Visibility
    70. 70. Reading
    71. 71. Reading
    72. 72. ReadingThe Pragmatic Programmer: From Journeyman to MasterAndrew Hunt and Dave ThomasExtreme Programming Explained: Embrace ChangeKent Beck and Cynthia AndresTest Driven Development: By ExampleKent BeckObject-Oriented Software ConstructionBertrand Meyer
    73. 73. ReadingClean Code: A Handbook of Agile SoftwareCraftsmanship Robert C. MartinDesign Patterns: Elements of Reusable Object-OrientedSoftware Erich Gamma, Richard Helm, Ralph Johnson,and John VlissidesMulti-Paradigm Design for C++James O. CoplienLean Architecture: for Agile Software DevelopmentJames O. Coplien and Gertrud Bjørnvig
    74. 74. Photo Creditshttp://www.flickr.com/photos/27558040@N00/4151899795/http://www.flickr.com/photos/popilop/331357312/http://www.flickr.com/photos/arlette/3260468/http://www.flickr.com/photos/36829973@N04/3546657245/
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×