Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Iterator Pattern Example
class IteratorPatternExample {
companion object {
@JvmStatic
fun main(args: Array<String>) {
val holder = VerifyTickets.getTicketHolder()
/*Printing several tickets*/
println("Printing next tickets...")
holder.ticketIterator.nextTicket()
holder.ticketIterator.nextTicket()
holder.ticketIterator.nextTicket()
/*Find a specific ticket*/
println()
println("Finding tickets...")
holder.ticketIterator.findTicket(10)
holder.ticketIterator.findTicket(55)
/*Update a specific ticket*/
println()
println("Update ticket...")
println("Ticket update successfully :${holder.ticketIterator.updateTicket(1, "Updated Name")}")
println("Ticket update successfully :${holder.ticketIterator.updateTicket(55, "Exception")}")
/*Find a specific ticket*/
println()
println("Find ticket...")
holder.ticketIterator.findTicket(1)
/*Reset the iterator position*/
println()
println("Reset iterator position...")
holder.ticketIterator.resetPositionTo(0)
/*Print all tickets*/
VerifyTickets.printAll(holder)
}
}
}
/**
* A model class that represent a ticket for a bus/train/any other vehicles.
*
* @param id Unique ticket ID.
* @param name Ticket owner name.
*/
data class TicketModel(val id: Int, var name: String = "")
/**
* An interface that define all APIs to store or remove [TicketModel] or list of [TicketModel],
* and provide access to [TicketIterator] to iterate though the list of [TicketModel].
*/
interface TicketHolder {
/*Add a ticket to the ticket holder*/
fun addTicket(ticketModel: TicketModel)
/*Add list of tickets to the ticket holder*/
fun addTickets(ticketModel: MutableList<TicketModel>)
/*Remove a ticket from the ticket holder*/
fun removeTicket(ticketModel: TicketModel)
/*Remove list of tickets from the ticket holder*/
fun removeTickets(ticketModel: MutableList<TicketModel>)
/*Clear all stored tickets*/
fun clearAll(): Boolean
/*Return an initialized instance of TicketIterator*/
val ticketIterator: TicketIterator
}
/**
* Implementation of [TicketHolder], where all APIs logic are defined.
* Initialize [TicketIterator] by providing the [ticketList] as the prerequisites.
*/
class TicketHolderImpl : TicketHolder {
/*Initialize empty holder*/
private var ticketList: MutableList<TicketModel> = ArrayList()
/*Initialize TicketIterator with empty holder*/
private var iterator: TicketIterator = TicketIteratorImpl(ticketList)
override fun addTicket(ticketModel: TicketModel) {
ticketList.add(ticketModel)
}
override fun addTickets(ticketModel: MutableList<TicketModel>) {
ticketList.addAll(ticketModel)
}
override fun removeTicket(ticketModel: TicketModel) {
ticketList.remove(ticketModel)
}
override fun removeTickets(ticketModel: MutableList<TicketModel>) {
ticketList.removeAll(ticketModel)
}
override fun clearAll(): Boolean {
this.ticketList.clear()
return true
}
override val ticketIterator: TicketIterator
get() = iterator
}
/**
* An interface that expose some APIs to the client to access, find, update, traverse
* thorough the elements of Ticket Holder system.
*/
interface TicketIterator {
/*Return the next ticket*/
fun nextTicket(): TicketModel
/*Find a specific ticket*/
fun findTicket(id: Int): TicketModel?
/*Update a specific ticket*/
fun updateTicket(id: Int, name: String): Boolean
/*Check if holder has more tickets or not*/
val hasNextTicket: Boolean
/*Reset the position to 0*/
fun resetPositionTo(newPosition: Int)
}
/**
* Implementation of [TicketIterator] where of APIs logic are defined.
*
* @param ticketList List of [TicketModel] to iterate, return ticket, find a ticket or update a ticket.
*/
class TicketIteratorImpl(private var ticketList: List<TicketModel>) : TicketIterator {
private var position: Int = 0
override fun nextTicket(): TicketModel {
val ticket = ticketList[position]
println("Ticket Info at position : $position - $ticket")
position++
return ticket
}
override fun findTicket(id: Int): TicketModel? =
ticketList.find { it.id == id; }?.apply {
println("Ticket found: $this")
} ?: kotlin.run { println("No ticket found with id :${id}"); null }
override fun updateTicket(id: Int, name: String): Boolean {
return ticketList.find { it.id == id }?.let {
it.name = name
return true
} ?: kotlin.run { println("No ticket found with id :${id}"); return@run false }
}
override val hasNextTicket: Boolean
get() = position >= ticketList.size
override fun resetPositionTo(newPosition: Int) {
this.position = newPosition
println("Position reset to $newPosition")
}
}
/**
* Clients access point to the [VerifyTickets] system.
*/
object VerifyTickets {
private val ticketHolder: TicketHolder = TicketHolderImpl()
fun getTicketHolder(freshStart: Boolean = true): TicketHolder {
if (freshStart) ticketHolder.clearAll(); ticketHolder.addTickets(provideValidBusTickets())
return ticketHolder
}
fun printAll(holder: TicketHolder) {
println()
println("Starting to print....")
while (!holder.ticketIterator.hasNextTicket) {
holder.ticketIterator.nextTicket()
}
println("Ending of print....")
println()
}
/*Return a list of valid Tickets*/
private fun provideValidBusTickets(): MutableList<TicketModel> = mutableListOf(
TicketModel(0).apply { name = "Something $id" },
TicketModel(1).apply { name = "Something $id" },
TicketModel(2).apply { name = "Something $id" },
TicketModel(3).apply { name = "Something $id" },
TicketModel(4).apply { name = "Something $id" },
TicketModel(5).apply { name = "Something $id" },
TicketModel(6).apply { name = "Something $id" },
TicketModel(7).apply { name = "Something $id" },
TicketModel(8).apply { name = "Something $id" },
TicketModel(9).apply { name = "Something $id" },
TicketModel(10).apply { name = "Something $id" },
TicketModel(11).apply { name = "Something $id" }
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment