singleton pattern

Applying the Singleton Pattern to the Case Study

A motivating example: Instantiate tax calculation strategies only once and only when needed


In Chapter 9, I encapsulated the rules about taxes within strategy objects. I have to derive a CalcTax class for each possible tax calculation rule. This means that I need to use the same objects over and over again, just alternating between their uses.

For performance reasons, I might not want to keep instantiating them and throwing them away again and again. And, although I could instantiate all of the possible strategies at the start, this could become inefficient if the number of strategies grew large. (Remember, I may have many other strategies throughout my application.) Instead, it would be best to instantiate them as needed, but only do the instantiation once.

The problem is that I do not want to create a separate object to keep track of what I have already instantiated. Instead, I would like the objects themselves (that is, the strategies) to be responsible for handling their own single instantiation.

Singleton makes objects responsible for themselves

This is the purpose of the Singleton pattern. It enables me to instantiate an object only once, without requiring the client objects to be concerned with whether it already exists.

The Singleton could be implemented in code as shown in Example 21-1. In this example, I create a method (getInstance) that will instantiate at most one USTax object. The Singleton protects against someone else instantiating the USTax object directly by making the constructor private, which means that no other object can access it.

Example 21-1. Java Code Fragment: Singleton Pattern
public class USTax extends Tax {
   private static USTax instance;
   private USTax() { }
   public static USTax getInstance() {
      if (instance== null) instance= new USTax();
      return instance;
   }
}

Singleton with polymorphism


In this case study, however, I actually need the SalesOrder to ask the Tax object which Tax object to use. The reason for this is that the SalesOrder does not want to know which particular tax object is present. There are two notions being combined here:

  1. Hide which concrete class I use (the factory in a method in the Tax class)

  2. Hide how many instantiations of each class I have (the Singleton in the USTax and other Tax concrete classes).

I show this in Example 21-2.

Example 21-2. Java Code Fragment: Singleton Pattern in the Context of the E-Commerce System
abstract public class Tax {
   static private Tax instance;
   protected Tax() { };

   abstract double calcTax(
      double qty, double price);

   public static Tax getInstance() {
      // use whatever rule you use to determine
      // which tax object to use.  For now,
      // let's create a USTax object.
      instance= USTax.getInstance();

      return instance;
   }
}
public class USTax extends Tax {
   private static USTax instance;
   private USTax() { }
   // Note in the following, I had to change USTax
   // to Tax since I used the same "getInstance"
   // name.
   public static Tax getInstance() {
      if (instance== null) instance= new USTax();
      return instance;
   }
}

The Singleton Pattern: Key Features

Intent

You want to have only one of an object, but there is no global object that controls the instantiation of this object. You also want to ensure that all entities are using the same instance of this object, without passing a reference to all of them.

Problem

Several different client objects need to refer to the same thing, and you want to ensure that you do not have more than one of them.

Solution

Guarantees one instance.

Participants and collaborators

Clients create an instance of the Singleton solely through the getInstance method.

Consequences

Clients need not concern themselves whether an instance of the Singleton exists. This can be controlled from within the Singleton.

Implementation

  • Add a private static member of the class that refers to the desired object. (Initially, it is null.)

  • Add a public static method that instantiates this class if this member is null (and sets this member's value) and then returns the value of this member.

  • Set the constructor's status to protected or private so that no one can directly instantiate this class and bypass the static constructor mechanism.


Figure 21-1. Generic structure of the Singleton pattern.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值