In this part of my code refactoring tutorial, we’ll look at how to replace a primitive type with a class.
Type safety is very important! So, what we want to do is to eliminate all operations on values that are not of the appropriate data type by protecting the program from bad input. One way we can do this is by replacing primitive types with classes. I’ll walk you step-by-step through the process. The code below will help you along.
If you like videos like this, it helps to tell Google+ [googleplusone]
Code From the Video
ATMAccessBad.java
public class ATMAccessBad { private String state; public final static String CARD_ENTERED = "CARD ENTERED"; public final static String VALID_CARD = "VALID CARD"; public final static String VALID_PIN = "VALID PIN"; public final static String VALID_CASH_REQUEST = "VALID CASH REQUEST"; public final static String DENIED = "DENIED"; public final static int CARD_NUMBER = 123456789; public final static int PIN_NUMBER = 1234; public final static double CARD_BALANCE = 1000.00; public ATMAccessBad() { state = CARD_ENTERED; } public void verifyCard(int cardNumber) { if (CARD_NUMBER == cardNumber) { state = VALID_CARD; } else state = DENIED; } public void verifyPIN(int pinNumber) { if (PIN_NUMBER == pinNumber) { state = VALID_PIN; } else state = DENIED; } public void verifyWithdrawalAmount(double withdrawalRequest) { if (CARD_BALANCE > withdrawalRequest) { state = VALID_CASH_REQUEST; } else state = DENIED; } public static void main(String[] args){ ATMAccessBad user = new ATMAccessBad(); System.out.println(user.state); user.verifyCard(123456789); System.out.println(user.state); user.verifyPIN(1234); System.out.println(user.state); user.verifyWithdrawalAmount(99); System.out.println(user.state); } }
ATMAccess.java
// Type safety is very important. // We want to eliminate all operations on values that // are not of the appropriate data type by protecting // the program from bad input. // We can do this by replacing primitive types with classes public class ATMAccess { // Define a type safe field private ATMCardState cardState; private void setState(ATMCardState cardState){ this.cardState = cardState; } public ATMAccess() { // Create type safe assignment setState(ATMCardState.CARD_ENTERED); } public String getState() { // REPLACED return state; return cardState.toString(); } // 1. Encapsulation is used public void verifyCard(int cardNumber) { if (getState().equals(ATMCardState.CARD_ENTERED.toString())){ if(cardNumber == ATMCardState.CARD_NUMBER){ // Create type safe assignment setState(ATMCardState.VALID_CARD); } else { setState(ATMCardState.DENIED); } } } public void verifyPIN(int pinNumber) { if (getState().equals(ATMCardState.VALID_CARD.toString())){ if(pinNumber == ATMCardState.PIN_NUMBER){ // Create type safe assignment setState(ATMCardState.VALID_PIN); } else { setState(ATMCardState.DENIED); } } } public void verifyWithdrawalAmount(double withdrawalRequest) { if (getState().equals(ATMCardState.VALID_PIN.toString())){ if(withdrawalRequest <= ATMCardState.CARD_BALANCE){ // Create type safe assignment setState(ATMCardState.VALID_CASH_REQUEST); } else { setState(ATMCardState.DENIED); } } } public static void main(String[] args){ ATMAccess user = new ATMAccess(); System.out.println(user.getState()); user.verifyCard(123456789); System.out.println(user.getState()); user.verifyPIN(1234); System.out.println(user.getState()); user.verifyWithdrawalAmount(1000); System.out.println(user.getState()); } } // Represents the state of a ATMAccess object class ATMCardState{ private final String name; private ATMCardState(String name){ this.name = name; } public String toString(){ return name; } // These type safe constants live in the class and can't be impersonated public final static ATMCardState CARD_ENTERED = new ATMCardState("CARD ENTERED"); public final static ATMCardState VALID_CARD = new ATMCardState("VALID CARD"); public final static ATMCardState VALID_PIN = new ATMCardState("VALID PIN"); public final static ATMCardState VALID_CASH_REQUEST = new ATMCardState("VALID CASH REQUEST"); public final static ATMCardState DENIED = new ATMCardState("DENIED"); public final static int CARD_NUMBER = 123456789; public final static int PIN_NUMBER = 1234; public final static double CARD_BALANCE = 1000.00; }
Hi,
Do you happen to have an aspect oriented programming video tutorial?
I haven’t covered that specific topic yet. Much of the beliefs are incorporated into many of my OOD tutorials, but the specific topic is not
It would be great if you made that specific thing.
I quite accustomed to your easy to understand lessons in OOP design 🙂
Thanks, anyway
Thank you 🙂 I’ll see how I can fit it in. I’m always juggling how to fit topics into my current plans
Hey Derek,
Why not use Enums instead of creating a class as internally an enum is converted to a class and values in enum to objects?
You could definitely do that. I was following a plan of refactoring this time in a different way.
Ok, thanks for clarifying