Anda di halaman 1dari 4

jlGui Music Player

Software Architecture and Design

jlGui Architecture:
Selected software project is jlGui Music Player which is a graphical music player that supports JavaSound capabilities: WAV, AU, AIFF, SPEEX, MP3 and OGG Vorbis. The goal of the project is to provide a real-time music player for the Java Plaform, WinAmp skins compliant, with streaming support. jlGui is designed in two layers. BasicPlayer layer provides a high level API - based on JavaSound API- to play, stop, pause, resume and seek audio file or stream. jlGui Player layer is a front-end, WinAmp 2.0 skins compliant, with playlist and equalizer. jlGui Player layer is the front end of jlGui. jlGui BasicPlayer layer is a player API of jlGui. Provides simple features (play, stop, pause, resume, seek) to play audio file or stream. jlGuiPlayer layer is composed of five main packages. They are equalizer, jlGui Player playlist, skin, tag, util and visual. Each package contains its own code for BasicPlayer API user interfaces and logic. Coordination between these Speaker packages are done through two main Java Sound API erers classes PlayerUI and StandalonePlayer. No test classes MP3 SPI Vorbis SPI included. BasicPlayer contains only one package where separate utility classes defined to handle events, exceptions, listeners and a main class where code for above mentioned functions resides. Activities of a jlGui Player is as mentioned in the diagram.

Use case diagram

Package diagram

Bad smells identified in the code:

1. Bad smell: Uncommunicative names Found in: BasicController interface of javazoom.jlgui.basicplayer package public void open(URL url) throws BasicPlayerException; public long seek(long bytes) throws BasicPlayerException; Solution would be to rename them such that the name of the method succinctly describes what that method does. public void openUrlOfSongToPlay(URL UrlOfSongToPlay) public long seek(long bytes) throws BasicPlayerException 2. Bad smell: Long method Found in: initAudioInputStream() method of BasicController interface from javazoom.jlgui.basicplayer package is doing more than initializing as implied in the name Code could have been broken and included in following three methods, initAudioInputStream(), notifyListenersWithAudioFileFormatProperties(Map javaSoudPropertiesOfAudioFile), saveJavaSoundPropertiesOfCurrentAudioFile(Map javaSoudPropertiesOfAudioFile, AudioFileFormat CurrentAudioFileFormat); 3. Bad smell: Comments Found in: several comments used to describe what each part of the methods does
// Add SourceDataLine properties.put("basicplayer.sourcedataline", m_line); Iterator it = m_listeners.iterator(); while (it.hasNext()) { BasicPlayerListener bpl = (BasicPlayerListener); bpl.opened(m_dataSource, properties);

Method names and parameters could have been written more meaningfully so that comments are not necessary. This part could be extracted and defined as a separate method. 4. Bad Smell: Existence of god class Found in: StandalonePlayer class of javazoom.jlgui.player.amp package also acts like a god class Code could have been split into two sub classes. One class to handle play list related issues, Variables: Playlistfound variable Methods: loadPlaylist()







Another class to handle auto run and boot related issues Variable: private boolean autoRun = false; Methods: boot(), setKeyBoardShortcut(), setKeyboardAction(String id, KeyStroke key, Action action) Bad smell: Feature envy Found in: The loadJS():void method in javazoom.jlgui.player.amp.StandalonePlayer is interacting lot with methods in javazoom.jlgui.player.amp.util.Config class. A part of loadJS() could be moved to class and that method can be called from with in loadJS() class in StandalonnePlayer class. Also Found in: The setKeyBoardShortcut():void method in javazoom.jlgui.player.amp.StandalonePlayer is interacting lot with methods in javazoom.jlgui.player.amp.PlayerUI class setKeyBoardShortcut():void method could be moved completely to PlayerUI class. Bad smell: Types being embedded in method name Found in: protected long skipBytes(long bytes) method in BasicPlayer class of javazoom.jlgui.basicplayer package. It forces the developer to change the name if the type changes protected long skipFramesFromInputStream(long LengthOfInputInBytes) could have been a better name. Bad smell: Temporary instance variables Found in: The variable private Image bi; of spectrumTimeAnalyzer class in javazoom.jlgui.player.amp.visual.ui package does not need to be defined as class variable That variable could have been defined in getDoubleBuffer():Image method of the same class and passed to other methods within parameter list when necessary. Bad smell: Indecent exposure Found in: protected Object m_dataSource variable of BasicPlayer class from javazoom.jlgui.basicplayer Found in: protected AudioInputStream m_encodedaudioInputStream variable of BasicPlayer class from javazoom.jlgui.basicplayer These two variables could have been made private rather than protected and access via getters and setters Bad smell: Existence of dead code Found in: of from javazoom.jlgui.player.amp.equalizer.ui packagehas unused variable dt defined as DropTarget dt = new DropTarget(this, DnDConstants.ACTION_COPY, dnd, false ); This dead variable should be removed from the code Bad smell: Only setter being synchronised and not getter Found in: javazoom.jlgui.player.amp.visual.ui.SpectrumTimeAnalyzer.getDisplayMode() is unsynchronized but javazoom.jlgui.player.amp.visual.ui.SpectrumTimeAnalyzer.setDisplayMode(int) is synchronized. . This may result in incorrect behaviour at runtime, as callers of the get method will not necessarily see a consistent state for the object. Making getDisplayMode() method also synchronised.