March 19, 2024

Queue and BuyerQueue

 

Rather than attempt to implement a queue with OrderedCollection it has been necessary to start from scratch. There is too much baggage in the form of unwanted messages for OrderedCollection to be directly used as a queue. But it certainly has its uses, as you will see.

Cordelia has insisted on certain requirements, but she has not completely stymied reuse of the Smalltalk class library. This is not the first time that Macroconcepts have needed to model queues.

They have previously developed the Queue class as a general purpose class. If subsequently they need to produce something more particular, Queue can be reused and subclassed. The new class BuyerQueue is an example of such a subclass. Note that Queue inherits directly from Object.

Object
  Queue
    BuyerQueue

So how is the Queue class implemented?

The trick is to give Queue an instance variable, elements, which references an instance of OrderedCollection. By encapsulating this object inside the instance of Queue we can prevent access to the messages that will cause violation of the requirement, "Don't you dare lose one of my buyers".

Queue has been given a protocol having a number of selectors for accessing (first, size), adding (add:), removing (remove), testing (isEmpty)and iterating (do:, detect:ifNone:). It also has an initialize method.

To get an idea of how this works here are some of these methods.

initialize
   "Set the collection to an empty OrderedCollection."

   elements := OrderedCollection new

add: anObject
   "Add anObject to the end of the collection."

   ^elements add: anObject

remove
   "Remove the first element of the collection."

   ^elements removeFirst

The class method new also needs implementing with the usual

^super new initialize

Unfortunately the job is unfinished. Cordelia, being a somewhat fickle creature, tends to adjust her priorities and those of her buyers with alarming regularity. Macroconcepts realise that buyers need a priority rating. You may have guessed by now that there is a Buyer class. This class is responsible for recording not only details of names, telephone numbers and other contact details, but it also, by means of an instance variable priority, gives a priority rating to a buyer. By referencing an integer, say between 1 and 10, the gallery can provide its buyers with their position in the pecking order of a queue. By the time that Steve Gideon had flown out of Heathrow, he had bagged a 10 and Harvey J. Endelstein had been reduced to a 9.

Furthermore, the system contains another class, Order. An order will usually contain information on the buyer, say buyerID and the purchases they have made, referenced by (for example) artworkID, an order date date and an orderNumber. I don't want to elaborate too much on this. You will be dealing with these concepts in Software Analysis and Design, but purchasing systems will often categorise in this manner. The artworld produces an unusual set of circumstances. Buyers sometimes want to purchase a piece of art by a particular artist, but the work doesn't yet exist. Neither they nor the gallery knows what to expect, or when it will be delivered.

Let us accept that orders for Walker's paintings have been placed. These orders will contain the buyer's identity, which references some unique value. A message in the Order class, buyer, returns an instance of Buyer. Each of these Buyer instances has a priority instance variable.

For this to work, a new queueing class is required. An instance of this class will store instances of Order. These orders will be sorted according to the priority rating of each buyer.

BuyerQueue, by virtue of its subclassing from Queue, inherits the instance variable elements, which references a SortedCollection instance. The sorting mechanism associated with elements must be modified. To implement this, the initialize method is overridden.

initialize
   "Create and assign to elements a new empty sorted collection and
    define the sort block."

   elements := SortedCollection new.
   elements sortBlock: [:predecessor :successor |
           (predecessor buyer priority) >= (successor buyer priority)]

Everything is now in place. The gallery can add the five orders (referenced by order1 etc.) that have been placed for Walker's pictures.

bWalkerBuyers := BuyerQueue new.
bWalkerBuyers add: order1;
              add: order2;
              add: order3;
              add: order4;
              add: order5

Let us assume that Steve Gideon's order is referenced by order5 and that he has the highest priority.

bWalkerBuyers remove answers with order5, the queue is reduced in size to 4 and I am afraid that the others will have to wait.

Next page » An iteration exercise

Previous page « Queues

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Up to top of page