Use which design pattern to rewrite the code?

Lang Tuo :

Q:For the following code snippets, identify which design pattern should have been used to improve the quality of the code. Rewrite the code using design pattern that you’ve identified. Your answer should include i) the statement to describe the design pattern ii) the rewritten Java code, and iii) the test result from the rewritten Java code.

public class FitnessCustomer {
 private static enum Level {
 BRONZE, SILVER, GOLD
 }
 private Level level;
public void setLevel(Level level) {
this.level = level;
}
 public double getFees() {
 switch (level) {
 case BRONZE: return CustomerConstants.BRONZE_FEES;
 case SILVER: return CustomerConstants.SILVER_FEES;
 case GOLD: return CustomerConstants.GOLD_FEES;
 }
 throw new IllegalStateException("How did I get here?");
}
 public boolean canAccessPool() {
 return (level == Level.SILVER || level == Level.GOLD);
}
 public boolean hasOwnLocker() {
 return (level == Level.GOLD);
}
 public double getEquipmentDiscount() {
 switch (level) {
 case BRONZE: return CustomerConstants.BRONZE_DISCOUNT;
 case SILVER: return CustomerConstants.SILVER_DISCOUNT;
 case GOLD: return CustomerConstants.GOLD_DISCOUNT;
 }
 throw new IllegalStateException("How did I get here?");
 }

I'm an fresh man to study the design pattern, and know some patterns likes observe-pattern,decorate-pattern and factory pattern... But, honestly, I'm not really understand how to identify and use them to improve the codes. For the question, I think the code can be improved by the template pattern cause the fitness-customer can be as the skeleton. And BRONZE, SILVER, GOLD can be as the sub-classes for the fitness-customer. I'm not sure it's correct for the question. And the codes are below:

FitnessCustomer.class:

package ASS2_Q2;

public abstract class FitnessCustomer {
    private Level level;

    public final void setLevel(Level level){
        this.level = level
    }

    public final double getFees(){
        switch(level){
            case BRONZE: return CustomerConstants.BRONZE_FEES;
            case SILVER: return CustomerConstants.SILVER_FEES;
             case GOLD: return CustomerConstants.GOLD_FEES; 
        }
        throw new IllegalStateException("How did I get here?");
    }

    public final double getEquipmentDiscount(){
        switch(level){
            case BRONZE: return CustomerConstants.BRONZE_DISCOUNT;
            case SILVER: return CustomerConstants.SILVER_DISCOUNT;
            case GOLD: return CustomerConstants.GOLD_DISCOUNT;
        }
        throw new IllegalStateException("How did I get here?");
    }

    public abstract  boolean canAccessPool();

    public abstract boolean hasOwnLocker();


}

BRONZE.class:

package ASS2_Q2;

public class BRONZE extends FitnessCustomer{
    public BRONZE(){
        this.level = "BRONZE";
    }


    @Override
    public boolean canAccessPool(){
        return false;
    }

    @Override
    public boolean hasOwnLocker(){
        return false;
    }


}

GOLD.class:

package ASS2_Q2;

public class GOLD extends FitnessCustomer{
    public GOLD(){
        this.level = "GOLD";
    }

    @Override
    public boolean canAccessPool(){
        return true;
    }

    @Override
    public boolean hasOwnLocker(){
        return true;
    }

}

SILVER.class:

package ASS2_Q2;

public class SILVER extends FitnessCustomer{

    public SILVER(){
        this.level = "SILVER";
    }


    @Override
    public boolean canAccessPool(){
        return true;
    }

    @Override
    public boolean hasOwnLocker(){
        return false;
    }



}

I want to ask whether the answer is right or not?Please help me! Thanks!

Tarun :

I am not using any particular design pattern but I think we could design it in following manner:

You can have following interfaces:

CustomerWithLockerAccess
CustomerWithPoolAccess
CustomerWithEquipmentDiscount

This interfaces ensures that we can have customer with any combinations of access.

Since every customer has a level and they have to pay a fee, You can create an abstract class FitnessCustomer as follow:

public abstract class FitnessCustomer {
    private static final Level level;

    public FitnessCustomer(Level level){
       this.level = level
    }

    public Level getLevel(){ return this.level};

    public final double getFees();
  }

Then you can design your classes as follows:

GoldCustomer extends FitnessCustomer implements CustomerWithLockerAccess, CustomerWithPoolAccess, CustomerWithEquipmentDiscount


SilverCustomer extends FitnessCustomer implements CustomerWithPoolAccess, CustomerWithEquipmentDiscount

BronzeCustomer extends FitnessCustomer implements CustomerWithEquipmentDiscount

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=403514&siteId=1