Object Oriented design for a live auction taking in bidders
up vote
1
down vote
favorite
My goal is to design an Auction that will take in data like this:
Bidder A - ( StartingBid , AutoIncrement , MaxBid)
Bidder B - ( StartingBid , AutoIncrement , MaxBid)
This Auction will generate a winner based on the bidders entered. The Auction algorithm will automatically increment a bidder's starting bid given he has a relative losing position to other Bidders. However, the algorithm should never increment a user's bid automatically if the max bid would be surpassed!
Here is my design. These are all the classes I created. Please let me know If there is a better object oriented design.
public class Auction {
private boolean isLive = true;
private List<Bidder> bidders;
private String itemName;
private Bidder winner;
public Auction(List<Bidder> bidders, String itemName) {
this.bidders = bidders;
}
public boolean isLive() {
return isLive;
}
public void setLive(boolean isLive) {
this.isLive = isLive;
}
public List<Bidder> getBidders() {
return bidders;
}
public void setBidders(List<Bidder> bidders) {
this.bidders = bidders;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public Bidder findWinner() {
// In Case of Tie Maintain a map that correlates a bidder with a
// position
// Valid Bids are the ones where they have not surpassed their capacity
int validBids = bidders.size();
// Determine Current Maximum Bid
Collections.sort(bidders);
double initialMax = bidders.get(bidders.size() - 1).getCurrentAmount();
Map.Entry<Bidder, Double> winningEntry = processBids(validBids, initialMax);
Bidder winningBidder = null;
winningBidder = winningEntry.getKey();
winningBidder.setCurrentAmount(winningEntry.getValue());
return winningBidder;
}
/**
* Main Processing which increments bids based on if they have capacity and
* if the currentAmount < max bid If there is a current tie where both bids
* are equal to the max then we break that by checking a list that gets
* populated when a tie occurs
*
* A bid is marked as a loser if it no longer has capacity to increase its
* bid and its less than the current max bid
*
* @param validBids
* @param max
* @return
*/
private Map.Entry<Bidder, Double> processBids(int validBids, double max) {
HashMap<Bidder, Double> maxBids = new HashMap<Bidder, Double>();
for (Bidder participant : bidders) {
double maxMinusInitial = participant.getMaxBid() - participant.getCurrentAmount();
if (maxMinusInitial % participant.getAutoIncrement() == 0) {
maxBids.put(participant, participant.getMaxBid());
} else {
maxBids.put(participant, participant.getMaxBid() - (maxMinusInitial % participant.getAutoIncrement()));
}
}
// Create a list from elements of HashMap
List<Map.Entry<Bidder, Double>> list = new LinkedList<Map.Entry<Bidder, Double>>(maxBids.entrySet());
// Sort the list
Collections.sort(list, new Comparator<Map.Entry<Bidder, Double>>() {
public int compare(Map.Entry<Bidder, Double> o1, Map.Entry<Bidder, Double> o2) {
return (o1.getValue()).compareTo(o2.getValue());
}
});
Map.Entry<Bidder, Double> winningEntry = list.get(list.size() - 1);
Bidder winningBidder = winningEntry.getKey();
Map.Entry<Bidder, Double> secondPlaceEntry = list.get(list.size() - 2);
// Resolve Ties
boolean ties = resolveTies(winningEntry, secondPlaceEntry);
if (ties) {
return secondPlaceEntry;
}
double secondPlaceMaxBet = secondPlaceEntry.getValue();
double maxMinusInitial = secondPlaceMaxBet - winningEntry.getKey().getCurrentAmount();
if (maxMinusInitial % winningEntry.getKey().getAutoIncrement() == 0) {
winningEntry.setValue(secondPlaceMaxBet + winningBidder.getAutoIncrement());
} else {
double remainder = secondPlaceMaxBet % winningBidder.getAutoIncrement();
secondPlaceMaxBet = secondPlaceMaxBet + remainder;
winningEntry.setValue(secondPlaceMaxBet);
}
return winningEntry;
}
private boolean resolveTies(Entry<Bidder, Double> winningEntry, Entry<Bidder, Double> secondPlaceEntry) {
// TODO Auto-generated method stub
if (winningEntry.getValue() == secondPlaceEntry.getValue()) {
if (secondPlaceEntry.getKey().getPositionInAuction() < winningEntry.getKey().getPositionInAuction()) {
return true;
}
return false;
} else {
return false;
}
}
public Bidder getWinner() {
return winner;
}
public void setWinner(Bidder winner) {
this.winner = winner;
}
}
public final class AuctionResult {
private Bidder winningBidder;
public AuctionResult(Bidder winningBidder) {
this.winningBidder = winningBidder;
}
/**
* Display the Auction Result
*/
public void displayResults() {
System.out.println("The auction c was won by " + winningBidder.getName() + " for the amount of $ " + winningBidder.getCurrentAmount());
}
public double getWinningAmount() {
return winningBidder.getCurrentAmount();
}
}
/**
* A bidder will have a one to one association with a bid object.
*
* @author agoel
*
*/
public class Bidder implements Comparable<Bidder> {
private double maxBid;
private boolean loser;
private String name;
private double autoIncrement;
private double currentAmount;
private int positionInAuction;
public Bidder(double currentAmount, double maxBid, String name, double autoIncrement , int positionInAuction) {
this.maxBid = maxBid;
this.currentAmount = currentAmount;
this.setAutoIncrement(autoIncrement);
this.name = name;
this.positionInAuction = positionInAuction;
}
public double getMaxBid() {
return maxBid;
}
public void setMaxBid(double maxBid) {
this.maxBid = maxBid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getAutoIncrement() {
return autoIncrement;
}
public void setAutoIncrement(double autoIncrement) {
this.autoIncrement = autoIncrement;
}
public int getPositionInAuction() {
return positionInAuction;
}
public void setPositionInAuction(int positionInAuction) {
this.positionInAuction = positionInAuction;
}
public double getCurrentAmount() {
return currentAmount;
}
public void setCurrentAmount(double currentAmount) {
this.currentAmount = currentAmount;
}
@Override
public int compareTo(Bidder otherBid) {
if (this.currentAmount < otherBid.getCurrentAmount()) {
return -1;
}
else if (this.currentAmount == otherBid.getCurrentAmount()) {
return 0;
}
else {
return 1;
}
}
@Override
public int hashCode() {
return Double.valueOf(currentAmount).hashCode();
}
@Override
public boolean equals(Object otherBid) {
if (otherBid == this) {
return true;
}
if (!(otherBid instanceof Bidder)) {
return false;
}
Bidder bid = (Bidder) otherBid;
if (this.currentAmount == bid.getCurrentAmount()) {
return true;
}
return false;
}
public boolean isLoser() {
return loser;
}
public void setLoser(boolean loser) {
this.loser = loser;
}
}
import java.util.List;
import com.goel.model.Auction;
import com.goel.model.Bidder;
public class AuctionBuilder {
/**
* Realistically an Auction should be built by pieces
* @param bidders
* @param itemName
* @return
*/
public Auction buildAuction(List<Bidder> bidders, String itemName) {
return new Auction(bidders, itemName);
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.goel.model.Auction;
import com.goel.model.AuctionResult;
import com.goel.model.Bidder;
/**
* This class will handle the heavylighting and be a facade to the backend. It
* will operate on an Auction object
* result in an immutable class on completion of the Auction
*
* @author agoel
*
*/
public class AuctionProcessor {
private Auction auction;
public Auction getAuction() {
return auction;
}
public void setAuction(Auction auction) {
this.auction = auction;
}
public AuctionProcessor(Auction auction) {
this.auction = auction;
}
public AuctionResult execute() {
Bidder winningBidder = auction.findWinner();
return new AuctionResult(winningBidder);
}
}
import java.util.ArrayList;
import java.util.List;
import com.goel.model.Auction;
import com.goel.model.AuctionResult;
import com.goel.model.Bidder;
public class AuctionCoordinator {
public static void main(String args) {
AuctionBuilder auctionBuilder = new AuctionBuilder();
Bidder linda = new Bidder(170.0d, 240.0d, "Linda", 3.0d, 1);
Bidder dave = new Bidder(160.0d, 243.0d, "Dave", 7.0d, 2);
Bidder eric = new Bidder(190.0d, 240.0d, "Matt", 4.0d, 3);
List<Bidder> bidders = new ArrayList<Bidder>();
bidders.add(linda);
bidders.add(dave);
bidders.add(eric);
Auction auction = auctionBuilder.buildAuction(bidders, "Record Player");
AuctionProcessor processor = new AuctionProcessor(auction);
AuctionResult result = processor.execute();
result.displayResults();
}
}
java object-oriented
New contributor
Ankit Goel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
up vote
1
down vote
favorite
My goal is to design an Auction that will take in data like this:
Bidder A - ( StartingBid , AutoIncrement , MaxBid)
Bidder B - ( StartingBid , AutoIncrement , MaxBid)
This Auction will generate a winner based on the bidders entered. The Auction algorithm will automatically increment a bidder's starting bid given he has a relative losing position to other Bidders. However, the algorithm should never increment a user's bid automatically if the max bid would be surpassed!
Here is my design. These are all the classes I created. Please let me know If there is a better object oriented design.
public class Auction {
private boolean isLive = true;
private List<Bidder> bidders;
private String itemName;
private Bidder winner;
public Auction(List<Bidder> bidders, String itemName) {
this.bidders = bidders;
}
public boolean isLive() {
return isLive;
}
public void setLive(boolean isLive) {
this.isLive = isLive;
}
public List<Bidder> getBidders() {
return bidders;
}
public void setBidders(List<Bidder> bidders) {
this.bidders = bidders;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public Bidder findWinner() {
// In Case of Tie Maintain a map that correlates a bidder with a
// position
// Valid Bids are the ones where they have not surpassed their capacity
int validBids = bidders.size();
// Determine Current Maximum Bid
Collections.sort(bidders);
double initialMax = bidders.get(bidders.size() - 1).getCurrentAmount();
Map.Entry<Bidder, Double> winningEntry = processBids(validBids, initialMax);
Bidder winningBidder = null;
winningBidder = winningEntry.getKey();
winningBidder.setCurrentAmount(winningEntry.getValue());
return winningBidder;
}
/**
* Main Processing which increments bids based on if they have capacity and
* if the currentAmount < max bid If there is a current tie where both bids
* are equal to the max then we break that by checking a list that gets
* populated when a tie occurs
*
* A bid is marked as a loser if it no longer has capacity to increase its
* bid and its less than the current max bid
*
* @param validBids
* @param max
* @return
*/
private Map.Entry<Bidder, Double> processBids(int validBids, double max) {
HashMap<Bidder, Double> maxBids = new HashMap<Bidder, Double>();
for (Bidder participant : bidders) {
double maxMinusInitial = participant.getMaxBid() - participant.getCurrentAmount();
if (maxMinusInitial % participant.getAutoIncrement() == 0) {
maxBids.put(participant, participant.getMaxBid());
} else {
maxBids.put(participant, participant.getMaxBid() - (maxMinusInitial % participant.getAutoIncrement()));
}
}
// Create a list from elements of HashMap
List<Map.Entry<Bidder, Double>> list = new LinkedList<Map.Entry<Bidder, Double>>(maxBids.entrySet());
// Sort the list
Collections.sort(list, new Comparator<Map.Entry<Bidder, Double>>() {
public int compare(Map.Entry<Bidder, Double> o1, Map.Entry<Bidder, Double> o2) {
return (o1.getValue()).compareTo(o2.getValue());
}
});
Map.Entry<Bidder, Double> winningEntry = list.get(list.size() - 1);
Bidder winningBidder = winningEntry.getKey();
Map.Entry<Bidder, Double> secondPlaceEntry = list.get(list.size() - 2);
// Resolve Ties
boolean ties = resolveTies(winningEntry, secondPlaceEntry);
if (ties) {
return secondPlaceEntry;
}
double secondPlaceMaxBet = secondPlaceEntry.getValue();
double maxMinusInitial = secondPlaceMaxBet - winningEntry.getKey().getCurrentAmount();
if (maxMinusInitial % winningEntry.getKey().getAutoIncrement() == 0) {
winningEntry.setValue(secondPlaceMaxBet + winningBidder.getAutoIncrement());
} else {
double remainder = secondPlaceMaxBet % winningBidder.getAutoIncrement();
secondPlaceMaxBet = secondPlaceMaxBet + remainder;
winningEntry.setValue(secondPlaceMaxBet);
}
return winningEntry;
}
private boolean resolveTies(Entry<Bidder, Double> winningEntry, Entry<Bidder, Double> secondPlaceEntry) {
// TODO Auto-generated method stub
if (winningEntry.getValue() == secondPlaceEntry.getValue()) {
if (secondPlaceEntry.getKey().getPositionInAuction() < winningEntry.getKey().getPositionInAuction()) {
return true;
}
return false;
} else {
return false;
}
}
public Bidder getWinner() {
return winner;
}
public void setWinner(Bidder winner) {
this.winner = winner;
}
}
public final class AuctionResult {
private Bidder winningBidder;
public AuctionResult(Bidder winningBidder) {
this.winningBidder = winningBidder;
}
/**
* Display the Auction Result
*/
public void displayResults() {
System.out.println("The auction c was won by " + winningBidder.getName() + " for the amount of $ " + winningBidder.getCurrentAmount());
}
public double getWinningAmount() {
return winningBidder.getCurrentAmount();
}
}
/**
* A bidder will have a one to one association with a bid object.
*
* @author agoel
*
*/
public class Bidder implements Comparable<Bidder> {
private double maxBid;
private boolean loser;
private String name;
private double autoIncrement;
private double currentAmount;
private int positionInAuction;
public Bidder(double currentAmount, double maxBid, String name, double autoIncrement , int positionInAuction) {
this.maxBid = maxBid;
this.currentAmount = currentAmount;
this.setAutoIncrement(autoIncrement);
this.name = name;
this.positionInAuction = positionInAuction;
}
public double getMaxBid() {
return maxBid;
}
public void setMaxBid(double maxBid) {
this.maxBid = maxBid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getAutoIncrement() {
return autoIncrement;
}
public void setAutoIncrement(double autoIncrement) {
this.autoIncrement = autoIncrement;
}
public int getPositionInAuction() {
return positionInAuction;
}
public void setPositionInAuction(int positionInAuction) {
this.positionInAuction = positionInAuction;
}
public double getCurrentAmount() {
return currentAmount;
}
public void setCurrentAmount(double currentAmount) {
this.currentAmount = currentAmount;
}
@Override
public int compareTo(Bidder otherBid) {
if (this.currentAmount < otherBid.getCurrentAmount()) {
return -1;
}
else if (this.currentAmount == otherBid.getCurrentAmount()) {
return 0;
}
else {
return 1;
}
}
@Override
public int hashCode() {
return Double.valueOf(currentAmount).hashCode();
}
@Override
public boolean equals(Object otherBid) {
if (otherBid == this) {
return true;
}
if (!(otherBid instanceof Bidder)) {
return false;
}
Bidder bid = (Bidder) otherBid;
if (this.currentAmount == bid.getCurrentAmount()) {
return true;
}
return false;
}
public boolean isLoser() {
return loser;
}
public void setLoser(boolean loser) {
this.loser = loser;
}
}
import java.util.List;
import com.goel.model.Auction;
import com.goel.model.Bidder;
public class AuctionBuilder {
/**
* Realistically an Auction should be built by pieces
* @param bidders
* @param itemName
* @return
*/
public Auction buildAuction(List<Bidder> bidders, String itemName) {
return new Auction(bidders, itemName);
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.goel.model.Auction;
import com.goel.model.AuctionResult;
import com.goel.model.Bidder;
/**
* This class will handle the heavylighting and be a facade to the backend. It
* will operate on an Auction object
* result in an immutable class on completion of the Auction
*
* @author agoel
*
*/
public class AuctionProcessor {
private Auction auction;
public Auction getAuction() {
return auction;
}
public void setAuction(Auction auction) {
this.auction = auction;
}
public AuctionProcessor(Auction auction) {
this.auction = auction;
}
public AuctionResult execute() {
Bidder winningBidder = auction.findWinner();
return new AuctionResult(winningBidder);
}
}
import java.util.ArrayList;
import java.util.List;
import com.goel.model.Auction;
import com.goel.model.AuctionResult;
import com.goel.model.Bidder;
public class AuctionCoordinator {
public static void main(String args) {
AuctionBuilder auctionBuilder = new AuctionBuilder();
Bidder linda = new Bidder(170.0d, 240.0d, "Linda", 3.0d, 1);
Bidder dave = new Bidder(160.0d, 243.0d, "Dave", 7.0d, 2);
Bidder eric = new Bidder(190.0d, 240.0d, "Matt", 4.0d, 3);
List<Bidder> bidders = new ArrayList<Bidder>();
bidders.add(linda);
bidders.add(dave);
bidders.add(eric);
Auction auction = auctionBuilder.buildAuction(bidders, "Record Player");
AuctionProcessor processor = new AuctionProcessor(auction);
AuctionResult result = processor.execute();
result.displayResults();
}
}
java object-oriented
New contributor
Ankit Goel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Is this just a design or does it actually do something? Did you test whether it works?
– Mast
22 mins ago
Yeah if you look at AuctionCoordinator class it builds an Auction and passes it to the AuctionProcessor which executes and returns an AuctionResult
– Ankit Goel
19 mins ago
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
My goal is to design an Auction that will take in data like this:
Bidder A - ( StartingBid , AutoIncrement , MaxBid)
Bidder B - ( StartingBid , AutoIncrement , MaxBid)
This Auction will generate a winner based on the bidders entered. The Auction algorithm will automatically increment a bidder's starting bid given he has a relative losing position to other Bidders. However, the algorithm should never increment a user's bid automatically if the max bid would be surpassed!
Here is my design. These are all the classes I created. Please let me know If there is a better object oriented design.
public class Auction {
private boolean isLive = true;
private List<Bidder> bidders;
private String itemName;
private Bidder winner;
public Auction(List<Bidder> bidders, String itemName) {
this.bidders = bidders;
}
public boolean isLive() {
return isLive;
}
public void setLive(boolean isLive) {
this.isLive = isLive;
}
public List<Bidder> getBidders() {
return bidders;
}
public void setBidders(List<Bidder> bidders) {
this.bidders = bidders;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public Bidder findWinner() {
// In Case of Tie Maintain a map that correlates a bidder with a
// position
// Valid Bids are the ones where they have not surpassed their capacity
int validBids = bidders.size();
// Determine Current Maximum Bid
Collections.sort(bidders);
double initialMax = bidders.get(bidders.size() - 1).getCurrentAmount();
Map.Entry<Bidder, Double> winningEntry = processBids(validBids, initialMax);
Bidder winningBidder = null;
winningBidder = winningEntry.getKey();
winningBidder.setCurrentAmount(winningEntry.getValue());
return winningBidder;
}
/**
* Main Processing which increments bids based on if they have capacity and
* if the currentAmount < max bid If there is a current tie where both bids
* are equal to the max then we break that by checking a list that gets
* populated when a tie occurs
*
* A bid is marked as a loser if it no longer has capacity to increase its
* bid and its less than the current max bid
*
* @param validBids
* @param max
* @return
*/
private Map.Entry<Bidder, Double> processBids(int validBids, double max) {
HashMap<Bidder, Double> maxBids = new HashMap<Bidder, Double>();
for (Bidder participant : bidders) {
double maxMinusInitial = participant.getMaxBid() - participant.getCurrentAmount();
if (maxMinusInitial % participant.getAutoIncrement() == 0) {
maxBids.put(participant, participant.getMaxBid());
} else {
maxBids.put(participant, participant.getMaxBid() - (maxMinusInitial % participant.getAutoIncrement()));
}
}
// Create a list from elements of HashMap
List<Map.Entry<Bidder, Double>> list = new LinkedList<Map.Entry<Bidder, Double>>(maxBids.entrySet());
// Sort the list
Collections.sort(list, new Comparator<Map.Entry<Bidder, Double>>() {
public int compare(Map.Entry<Bidder, Double> o1, Map.Entry<Bidder, Double> o2) {
return (o1.getValue()).compareTo(o2.getValue());
}
});
Map.Entry<Bidder, Double> winningEntry = list.get(list.size() - 1);
Bidder winningBidder = winningEntry.getKey();
Map.Entry<Bidder, Double> secondPlaceEntry = list.get(list.size() - 2);
// Resolve Ties
boolean ties = resolveTies(winningEntry, secondPlaceEntry);
if (ties) {
return secondPlaceEntry;
}
double secondPlaceMaxBet = secondPlaceEntry.getValue();
double maxMinusInitial = secondPlaceMaxBet - winningEntry.getKey().getCurrentAmount();
if (maxMinusInitial % winningEntry.getKey().getAutoIncrement() == 0) {
winningEntry.setValue(secondPlaceMaxBet + winningBidder.getAutoIncrement());
} else {
double remainder = secondPlaceMaxBet % winningBidder.getAutoIncrement();
secondPlaceMaxBet = secondPlaceMaxBet + remainder;
winningEntry.setValue(secondPlaceMaxBet);
}
return winningEntry;
}
private boolean resolveTies(Entry<Bidder, Double> winningEntry, Entry<Bidder, Double> secondPlaceEntry) {
// TODO Auto-generated method stub
if (winningEntry.getValue() == secondPlaceEntry.getValue()) {
if (secondPlaceEntry.getKey().getPositionInAuction() < winningEntry.getKey().getPositionInAuction()) {
return true;
}
return false;
} else {
return false;
}
}
public Bidder getWinner() {
return winner;
}
public void setWinner(Bidder winner) {
this.winner = winner;
}
}
public final class AuctionResult {
private Bidder winningBidder;
public AuctionResult(Bidder winningBidder) {
this.winningBidder = winningBidder;
}
/**
* Display the Auction Result
*/
public void displayResults() {
System.out.println("The auction c was won by " + winningBidder.getName() + " for the amount of $ " + winningBidder.getCurrentAmount());
}
public double getWinningAmount() {
return winningBidder.getCurrentAmount();
}
}
/**
* A bidder will have a one to one association with a bid object.
*
* @author agoel
*
*/
public class Bidder implements Comparable<Bidder> {
private double maxBid;
private boolean loser;
private String name;
private double autoIncrement;
private double currentAmount;
private int positionInAuction;
public Bidder(double currentAmount, double maxBid, String name, double autoIncrement , int positionInAuction) {
this.maxBid = maxBid;
this.currentAmount = currentAmount;
this.setAutoIncrement(autoIncrement);
this.name = name;
this.positionInAuction = positionInAuction;
}
public double getMaxBid() {
return maxBid;
}
public void setMaxBid(double maxBid) {
this.maxBid = maxBid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getAutoIncrement() {
return autoIncrement;
}
public void setAutoIncrement(double autoIncrement) {
this.autoIncrement = autoIncrement;
}
public int getPositionInAuction() {
return positionInAuction;
}
public void setPositionInAuction(int positionInAuction) {
this.positionInAuction = positionInAuction;
}
public double getCurrentAmount() {
return currentAmount;
}
public void setCurrentAmount(double currentAmount) {
this.currentAmount = currentAmount;
}
@Override
public int compareTo(Bidder otherBid) {
if (this.currentAmount < otherBid.getCurrentAmount()) {
return -1;
}
else if (this.currentAmount == otherBid.getCurrentAmount()) {
return 0;
}
else {
return 1;
}
}
@Override
public int hashCode() {
return Double.valueOf(currentAmount).hashCode();
}
@Override
public boolean equals(Object otherBid) {
if (otherBid == this) {
return true;
}
if (!(otherBid instanceof Bidder)) {
return false;
}
Bidder bid = (Bidder) otherBid;
if (this.currentAmount == bid.getCurrentAmount()) {
return true;
}
return false;
}
public boolean isLoser() {
return loser;
}
public void setLoser(boolean loser) {
this.loser = loser;
}
}
import java.util.List;
import com.goel.model.Auction;
import com.goel.model.Bidder;
public class AuctionBuilder {
/**
* Realistically an Auction should be built by pieces
* @param bidders
* @param itemName
* @return
*/
public Auction buildAuction(List<Bidder> bidders, String itemName) {
return new Auction(bidders, itemName);
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.goel.model.Auction;
import com.goel.model.AuctionResult;
import com.goel.model.Bidder;
/**
* This class will handle the heavylighting and be a facade to the backend. It
* will operate on an Auction object
* result in an immutable class on completion of the Auction
*
* @author agoel
*
*/
public class AuctionProcessor {
private Auction auction;
public Auction getAuction() {
return auction;
}
public void setAuction(Auction auction) {
this.auction = auction;
}
public AuctionProcessor(Auction auction) {
this.auction = auction;
}
public AuctionResult execute() {
Bidder winningBidder = auction.findWinner();
return new AuctionResult(winningBidder);
}
}
import java.util.ArrayList;
import java.util.List;
import com.goel.model.Auction;
import com.goel.model.AuctionResult;
import com.goel.model.Bidder;
public class AuctionCoordinator {
public static void main(String args) {
AuctionBuilder auctionBuilder = new AuctionBuilder();
Bidder linda = new Bidder(170.0d, 240.0d, "Linda", 3.0d, 1);
Bidder dave = new Bidder(160.0d, 243.0d, "Dave", 7.0d, 2);
Bidder eric = new Bidder(190.0d, 240.0d, "Matt", 4.0d, 3);
List<Bidder> bidders = new ArrayList<Bidder>();
bidders.add(linda);
bidders.add(dave);
bidders.add(eric);
Auction auction = auctionBuilder.buildAuction(bidders, "Record Player");
AuctionProcessor processor = new AuctionProcessor(auction);
AuctionResult result = processor.execute();
result.displayResults();
}
}
java object-oriented
New contributor
Ankit Goel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
My goal is to design an Auction that will take in data like this:
Bidder A - ( StartingBid , AutoIncrement , MaxBid)
Bidder B - ( StartingBid , AutoIncrement , MaxBid)
This Auction will generate a winner based on the bidders entered. The Auction algorithm will automatically increment a bidder's starting bid given he has a relative losing position to other Bidders. However, the algorithm should never increment a user's bid automatically if the max bid would be surpassed!
Here is my design. These are all the classes I created. Please let me know If there is a better object oriented design.
public class Auction {
private boolean isLive = true;
private List<Bidder> bidders;
private String itemName;
private Bidder winner;
public Auction(List<Bidder> bidders, String itemName) {
this.bidders = bidders;
}
public boolean isLive() {
return isLive;
}
public void setLive(boolean isLive) {
this.isLive = isLive;
}
public List<Bidder> getBidders() {
return bidders;
}
public void setBidders(List<Bidder> bidders) {
this.bidders = bidders;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public Bidder findWinner() {
// In Case of Tie Maintain a map that correlates a bidder with a
// position
// Valid Bids are the ones where they have not surpassed their capacity
int validBids = bidders.size();
// Determine Current Maximum Bid
Collections.sort(bidders);
double initialMax = bidders.get(bidders.size() - 1).getCurrentAmount();
Map.Entry<Bidder, Double> winningEntry = processBids(validBids, initialMax);
Bidder winningBidder = null;
winningBidder = winningEntry.getKey();
winningBidder.setCurrentAmount(winningEntry.getValue());
return winningBidder;
}
/**
* Main Processing which increments bids based on if they have capacity and
* if the currentAmount < max bid If there is a current tie where both bids
* are equal to the max then we break that by checking a list that gets
* populated when a tie occurs
*
* A bid is marked as a loser if it no longer has capacity to increase its
* bid and its less than the current max bid
*
* @param validBids
* @param max
* @return
*/
private Map.Entry<Bidder, Double> processBids(int validBids, double max) {
HashMap<Bidder, Double> maxBids = new HashMap<Bidder, Double>();
for (Bidder participant : bidders) {
double maxMinusInitial = participant.getMaxBid() - participant.getCurrentAmount();
if (maxMinusInitial % participant.getAutoIncrement() == 0) {
maxBids.put(participant, participant.getMaxBid());
} else {
maxBids.put(participant, participant.getMaxBid() - (maxMinusInitial % participant.getAutoIncrement()));
}
}
// Create a list from elements of HashMap
List<Map.Entry<Bidder, Double>> list = new LinkedList<Map.Entry<Bidder, Double>>(maxBids.entrySet());
// Sort the list
Collections.sort(list, new Comparator<Map.Entry<Bidder, Double>>() {
public int compare(Map.Entry<Bidder, Double> o1, Map.Entry<Bidder, Double> o2) {
return (o1.getValue()).compareTo(o2.getValue());
}
});
Map.Entry<Bidder, Double> winningEntry = list.get(list.size() - 1);
Bidder winningBidder = winningEntry.getKey();
Map.Entry<Bidder, Double> secondPlaceEntry = list.get(list.size() - 2);
// Resolve Ties
boolean ties = resolveTies(winningEntry, secondPlaceEntry);
if (ties) {
return secondPlaceEntry;
}
double secondPlaceMaxBet = secondPlaceEntry.getValue();
double maxMinusInitial = secondPlaceMaxBet - winningEntry.getKey().getCurrentAmount();
if (maxMinusInitial % winningEntry.getKey().getAutoIncrement() == 0) {
winningEntry.setValue(secondPlaceMaxBet + winningBidder.getAutoIncrement());
} else {
double remainder = secondPlaceMaxBet % winningBidder.getAutoIncrement();
secondPlaceMaxBet = secondPlaceMaxBet + remainder;
winningEntry.setValue(secondPlaceMaxBet);
}
return winningEntry;
}
private boolean resolveTies(Entry<Bidder, Double> winningEntry, Entry<Bidder, Double> secondPlaceEntry) {
// TODO Auto-generated method stub
if (winningEntry.getValue() == secondPlaceEntry.getValue()) {
if (secondPlaceEntry.getKey().getPositionInAuction() < winningEntry.getKey().getPositionInAuction()) {
return true;
}
return false;
} else {
return false;
}
}
public Bidder getWinner() {
return winner;
}
public void setWinner(Bidder winner) {
this.winner = winner;
}
}
public final class AuctionResult {
private Bidder winningBidder;
public AuctionResult(Bidder winningBidder) {
this.winningBidder = winningBidder;
}
/**
* Display the Auction Result
*/
public void displayResults() {
System.out.println("The auction c was won by " + winningBidder.getName() + " for the amount of $ " + winningBidder.getCurrentAmount());
}
public double getWinningAmount() {
return winningBidder.getCurrentAmount();
}
}
/**
* A bidder will have a one to one association with a bid object.
*
* @author agoel
*
*/
public class Bidder implements Comparable<Bidder> {
private double maxBid;
private boolean loser;
private String name;
private double autoIncrement;
private double currentAmount;
private int positionInAuction;
public Bidder(double currentAmount, double maxBid, String name, double autoIncrement , int positionInAuction) {
this.maxBid = maxBid;
this.currentAmount = currentAmount;
this.setAutoIncrement(autoIncrement);
this.name = name;
this.positionInAuction = positionInAuction;
}
public double getMaxBid() {
return maxBid;
}
public void setMaxBid(double maxBid) {
this.maxBid = maxBid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getAutoIncrement() {
return autoIncrement;
}
public void setAutoIncrement(double autoIncrement) {
this.autoIncrement = autoIncrement;
}
public int getPositionInAuction() {
return positionInAuction;
}
public void setPositionInAuction(int positionInAuction) {
this.positionInAuction = positionInAuction;
}
public double getCurrentAmount() {
return currentAmount;
}
public void setCurrentAmount(double currentAmount) {
this.currentAmount = currentAmount;
}
@Override
public int compareTo(Bidder otherBid) {
if (this.currentAmount < otherBid.getCurrentAmount()) {
return -1;
}
else if (this.currentAmount == otherBid.getCurrentAmount()) {
return 0;
}
else {
return 1;
}
}
@Override
public int hashCode() {
return Double.valueOf(currentAmount).hashCode();
}
@Override
public boolean equals(Object otherBid) {
if (otherBid == this) {
return true;
}
if (!(otherBid instanceof Bidder)) {
return false;
}
Bidder bid = (Bidder) otherBid;
if (this.currentAmount == bid.getCurrentAmount()) {
return true;
}
return false;
}
public boolean isLoser() {
return loser;
}
public void setLoser(boolean loser) {
this.loser = loser;
}
}
import java.util.List;
import com.goel.model.Auction;
import com.goel.model.Bidder;
public class AuctionBuilder {
/**
* Realistically an Auction should be built by pieces
* @param bidders
* @param itemName
* @return
*/
public Auction buildAuction(List<Bidder> bidders, String itemName) {
return new Auction(bidders, itemName);
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.goel.model.Auction;
import com.goel.model.AuctionResult;
import com.goel.model.Bidder;
/**
* This class will handle the heavylighting and be a facade to the backend. It
* will operate on an Auction object
* result in an immutable class on completion of the Auction
*
* @author agoel
*
*/
public class AuctionProcessor {
private Auction auction;
public Auction getAuction() {
return auction;
}
public void setAuction(Auction auction) {
this.auction = auction;
}
public AuctionProcessor(Auction auction) {
this.auction = auction;
}
public AuctionResult execute() {
Bidder winningBidder = auction.findWinner();
return new AuctionResult(winningBidder);
}
}
import java.util.ArrayList;
import java.util.List;
import com.goel.model.Auction;
import com.goel.model.AuctionResult;
import com.goel.model.Bidder;
public class AuctionCoordinator {
public static void main(String args) {
AuctionBuilder auctionBuilder = new AuctionBuilder();
Bidder linda = new Bidder(170.0d, 240.0d, "Linda", 3.0d, 1);
Bidder dave = new Bidder(160.0d, 243.0d, "Dave", 7.0d, 2);
Bidder eric = new Bidder(190.0d, 240.0d, "Matt", 4.0d, 3);
List<Bidder> bidders = new ArrayList<Bidder>();
bidders.add(linda);
bidders.add(dave);
bidders.add(eric);
Auction auction = auctionBuilder.buildAuction(bidders, "Record Player");
AuctionProcessor processor = new AuctionProcessor(auction);
AuctionResult result = processor.execute();
result.displayResults();
}
}
java object-oriented
java object-oriented
New contributor
Ankit Goel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Ankit Goel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 21 mins ago
Mast
7,43863686
7,43863686
New contributor
Ankit Goel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked 3 hours ago
Ankit Goel
62
62
New contributor
Ankit Goel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Ankit Goel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Ankit Goel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Is this just a design or does it actually do something? Did you test whether it works?
– Mast
22 mins ago
Yeah if you look at AuctionCoordinator class it builds an Auction and passes it to the AuctionProcessor which executes and returns an AuctionResult
– Ankit Goel
19 mins ago
add a comment |
Is this just a design or does it actually do something? Did you test whether it works?
– Mast
22 mins ago
Yeah if you look at AuctionCoordinator class it builds an Auction and passes it to the AuctionProcessor which executes and returns an AuctionResult
– Ankit Goel
19 mins ago
Is this just a design or does it actually do something? Did you test whether it works?
– Mast
22 mins ago
Is this just a design or does it actually do something? Did you test whether it works?
– Mast
22 mins ago
Yeah if you look at AuctionCoordinator class it builds an Auction and passes it to the AuctionProcessor which executes and returns an AuctionResult
– Ankit Goel
19 mins ago
Yeah if you look at AuctionCoordinator class it builds an Auction and passes it to the AuctionProcessor which executes and returns an AuctionResult
– Ankit Goel
19 mins ago
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Ankit Goel is a new contributor. Be nice, and check out our Code of Conduct.
Ankit Goel is a new contributor. Be nice, and check out our Code of Conduct.
Ankit Goel is a new contributor. Be nice, and check out our Code of Conduct.
Ankit Goel is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208400%2fobject-oriented-design-for-a-live-auction-taking-in-bidders%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Is this just a design or does it actually do something? Did you test whether it works?
– Mast
22 mins ago
Yeah if you look at AuctionCoordinator class it builds an Auction and passes it to the AuctionProcessor which executes and returns an AuctionResult
– Ankit Goel
19 mins ago