Design a musical jukebox using OO principles

Design a musical juke box using object oriented principles.

My initial thoughts:

  1. Create some hash to map titles/artists/albums to songs.
  2. There are a few states of a jukebox, namely STANDBY, COIN_IN and PLAYING. Different functions should be placed in different states.
  3. Some user-friendly UI.

My initial codes:

	public class Song {
		private int id;
		private String artist;
		private String title;
		private String album;
		private final static long DURATION = 10000;
		private long current = -1;

		public int getId() {
			return id;
		}

		public void setId(int id) {
			this.id = id;
		}

		public String getArtist() {
			return artist;
		}

		public void setArtist(String artist) {
			this.artist = artist;
		}

		public String getTitle() {
			return title;
		}

		public void setTitle(String title) {
			this.title = title;
		}

		public String getAlbum() {
			return album;
		}

		public void setAlbum(String album) {
			this.album = album;
		}

		public long getCurrent() {
			return current;
		}

		public void setCurrent(long current) {
			this.current = current;
		}

		public void play() {
			// play the music
		}

		public boolean finished() {
			return current == DURATION;
		}
	}

	public enum State {
		STANDBY, COIN_IN, PLAYING
	}

	public class JukeBox {

		private Map<Integer, Song> idMap;
		// artist -> album -> title
		private Map<String, Map<String, Map<String, Song>>> artistMap;
		// title -> artist
		private Map<String, Map<String, Song>> titleMap;

		private State state;
		private boolean powerOn;
		private double COST = 0.25;

		private String currentArtist;
		private String currentTitle;
		private String currentAlbum;
		private Integer currentId;
		private Song currentSong;

		public Song select() {
			if (currentId != null)
				return idMap.get(currentId);
			else if (currentTitle != null && currentArtist != null)
				return titleMap.get(currentTitle).get(currentArtist);
			else if (currentArtist != null && currentAlbum != null
					&& currentTitle != null)
				return artistMap.get(currentArtist).get(currentAlbum)
						.get(currentTitle);
			else
				return null;
		}

		public void displayWelcomeMsg() {

		}

		public boolean handleCoinIn() {
			// connect to hardware
			return false;
		}

		public double getAmount() {
			// connect to hardware to get the amount of inserted coins
			return 0.0;
		}

		public void getSongUI() {
			/*
			 * UI display to let user select music
			 * i.e. populate currentArtist, currentTitle
			 * currentAlbum and/or currentID.
			 */
		}

		public void run() {
			while (powerOn) {
				switch (state) {
				case STANDBY: {
					displayWelcomeMsg();
					if (handleCoinIn())
						state = State.COIN_IN;
					break;
				}
				case COIN_IN: {
					currentSong = select();
					if (currentSong != null) {
						currentSong.play();
						state = State.PLAYING;
					}
					if (getAmount() >= COST) {
						getSongUI();
					} else {
						System.out.println("COST: " + COST + " current: "
								+ getAmount());
					}
					break;
				}
				case PLAYING: {
					if (currentSong.finished())
						state = State.STANDBY;
					else
						System.out
								.printf("%s - %s - %s\n",
										currentSong.getTitle(),
										currentSong.getArtist(),
										currentSong.getAlbum());
					break;
				}
				}
			}
		}
	}

Solution:


	public class CD {
	}

	public class CDPlayer {
		private Playlist p;
		private CD c;

		public Playlist getPlaylist() {
			return p;
		}

		public void setPlaylist(Playlist p) {
			this.p = p;
		}

		public CD getCD() {
			return c;
		}

		public void setCD(CD c) {
			this.c = c;
		}

		public CDPlayer(Playlist p) {
			this.p = p;
		}

		public CDPlayer(CD c, Playlist p) {
			// TODO
		}

		public CDPlayer(CD c) {
			this.c = c;
		}

		public void playTrack(MySong s) {
			// TODO
		}
	}

	public class JukeBox {
		private CDPlayer cdPlayer;
		private User user;
		private Set<CD> cdCollection;
		private TrackSelector ts;

		public JukeBox(CDPlayer cdPlayer, User user, Set<CD> cdCollection,
				TrackSelector ts) { // TODO

		}

		public MySong getCurrentTrack() {
			return ts.getCurrentSong();
		}

		public void processOneUser(User u) {
			this.user = u;
		}
	}

	public class Playlist {
		private MySong track;
		private Queue<MySong> queue;

		public Playlist(MySong track, Queue<MySong> queue) { // TODO

		}

		public MySong getNextTrackToPlay() {
			return queue.peek();
		}

		public void queueUpTrack(MySong s) {
			queue.add(s);
		}
	}

	public class Song {
		private String songName;
	}

	public class TrackSelector {
		private MySong currentSong;

		public TrackSelector(MySong s) {
			currentSong = s;
		}

		public void setTrack(MySong s) {
			currentSong = s;
		}

		public MySong getCurrentSong() {
			return currentSong;
		}
	}

	public class User {
		private String name;

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public long getID() {
			return ID;
		}

		public void setID(long iD) {
			ID = iD;
		}

		private long ID;

		public User(String name, long iD) { // TODO

		}

		public User getUser() {
			return this;
		}

		public User addUser(String name, long iD) {// TODO
			return null;
		}
	}

Comments:

  1. Apparently, you need have functionality of playlist which I didn’t come up.
  2. I don’t understand why we need User class.
  3. Perhaps we are thinking about two kinds of ‘jukebox’?
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: