Best way to remove multiple if-else
<p>So the similar type of questions are answered elsewhere but here I am expecting the best way to omit if else chain for the given situation.</p>

<p><strong>CURRENT CODE</strong></p>

<pre><code>private ViewModel getViewModel(Receipt receipt) {
  String receiptType = receipt.type;

  if(receiptType.equals("HOTEL")) {
    return new HotelReceiptViewModel(receipt));
  } else if(receiptType.equals("CAR")) {
    return new CarReceiptViewModel(receipt));
  }
  .
  .
  .
  } else if(receiptType.equals("LUNCH")) {
    return new FoodReceiptViewModel(receipt));
  }
}
</code></pre>

<p>where all the view models extend a class called <code>ReceiptViewModel</code>. e.g.</p>

<pre><code>public class HotelReceiptViewModel extends ReceiptViewModel implements ViewModel {
    public HotelReceiptViewModel(Receipt receipt) {
        super(receipt);
        this.receiptNumber = receipt.getDocumentNumber();
        this.receiptHeading = "HOTEL";
    }
}
</code></pre>

<p>There are currently 5 types of receipts and there will be 3-4 more types of receipts in future.</p>

<p><strong>POSSIBLE SOLUTIONS</strong></p>

<ol>
<li>Use of <code>HashMap</code></li>
<li>Use of <code>Enum</code></li>
<li>Use Strategy Pattern or Command Pattern</li>
<li>Use of Reflection</li>
</ol>

<p>Let's see pros and cons of each approach</p>

<hr>

<p><strong>1. Use of HashMap</strong></p>

<pre><code>private ReceiptViewModel getViewModel(Receipt receipt) {
  Map&lt;String, ReceiptViewModel&gt; map = getViewModelsMap();

  String receiptType = receipt.type;
  ReceiptViewModel viewModel = map.get(receiptType);
  if(viewModel != null) {
    viewModel.setReceipt(receipt);
  }

  return viewModel;
}

private Map&lt;String, ReceiptViewModel&gt; getViewModelsMap() {
  Map&lt;String, ReceiptViewModel&gt; map = new HashMap&lt;String, ReceiptViewModel&gt;();
  map.add("HOTEL"), new HotelReceiptViewModel());
  map.add("CAR"), new CarReceiptViewModel());
  map.add("LUNCH"), new FoodReceiptViewModel());
}
</code></pre>

<p>and <code>ReceiptViewModel</code> classes will look like</p>

<pre><code>public class HotelReceiptViewModel extends ReceiptViewModel implements ViewModel {
  public HotelReceiptViewModel(Receipt receipt) {
    super(receipt);
    this.receiptNumber = receipt.getDocumentNumber();
    this.receiptHeading = "HOTEL";
  }
}
</code></pre>

<p><em>PROS</em>
Faster, Easier, Extensible.</p>

<p><em>CONS</em>
<code>ReceiptViewModel</code> object does not require an object of <code>Receipt</code> type in the constructor. <code>Receipt</code> is rather set using a setter, where all the logic of initializing the <code>ReceiptViewModel</code> class will move now.</p>

<hr>

<p><strong>2. Use of Enum</strong></p>

<pre><code>private ReceiptViewModel getViewModel(Receipt receipt) {
  String receiptType = receipt.type;
  ReceiptViewModel viewModel = 
        ReceiptViewModels.valueOf(receiptType).getReceiptViewModel(receipt);

  return viewModel;
}
</code></pre>

<p>And Enum will look like</p>

<pre><code>public enum ReceiptViewModels {
   HOTEL(
       ReceiptViewModel getReceiptViewModel(Receipt receipt) {
           return new HotelReceiptViewModel(receipt);
       }
    ),
   CAR(
       ReceiptViewModel getReceiptViewModel(Receipt receipt) {
           return new CarReceiptViewModel(receipt);
       }
    ),
    .
    .
    .
   LUNCH(
       ReceiptViewModel getReceiptViewModel(Receipt receipt) {
           return new FoodReceiptViewModel(receipt);
       }
    ),

    public abstract ReceiptViewModel getReceiptViewModel(Receipt receipt);
 }
</code></pre>

<p><em>PROS</em>
Fast, Probably Easy.</p>

<p><em>CONS</em>
Size of Enum will keep on increasing as the receipt types increase, resulting in non-maintainable code.</p>

<p><code>ReceiptViewModels.valueOf(receiptType)</code> expects a known receipt type. If a new receipt type comes as a response from server, it will result in an <code>IllegalArgumentException</code></p>

<hr>

<p><strong>3. Use of Reflection</strong></p>

<pre><code>Class&lt;? extends ReceiptViewModel&gt; viewModel = Class.
            forName(receiptType + name + "ReceiptViewModel").asSubclass(ReceiptViewModel.class);
        ReceiptViewModel receiptViewModel = viewModel .newInstance();
</code></pre>

<p><em>CONS</em> 
1. Slower</p>

<ol start="2">
<li><p>Cannot be used when the class names are different. e.g. For LUNCH type the view model class name is FoodReceiptViewModel</p></li>
<li><p>Logic of getting values from receipt is moved to a setter instead of constructor as in case of HashMap</p></li>
</ol>

<hr>

<p><strong>4. Use of <a href="http://www.tutorialspoint.com/design_pattern/strategy_pattern.htm" rel="noreferrer">Strategy Pattern</a> or <a href="http://www.tutorialspoint.com/design_pattern/template_pattern.htm" rel="noreferrer">Template Pattern</a></strong></p>

<p><em>PROS</em> Easy to understand and faster than Reflection </p>

<p><em>CONS</em> Probably an overkill. A new class will be added for each type of receipt.</p>

<hr>

<p>Considering all the above points, which would be the best approach for my use case to remove the multiple if-else blocks?</p>