Software Engineering

Written Assignment 2: Design Principles

Due on November 1st at 11:59 PM.

This is an individual assignment. You are to complete this assignment on your own, although you may discuss the lab concepts with your classmates. Remember the Academic Integrity Policy: do not show your work to anyone outside of the course staff and do not look at anyone else’s work for this lab. If you need help, please post on the Piazza forum or contact the instructor. Note that no exception is made for your group members; collaboration with your group members is a violation of the Academic Integrity Policy as much as collaboration with other members of the class. If you have any doubts about what is okay and what is not, it’s much safer to ask than to risk violating the Academic Integrity Policy.

Your Task

For this assignment, write answers to the questions below and upload them to your personal GitHub repository for the assignment. You can find your repository at:

git@github.swarthmore.edu:cs71-f17/written2-<username>.git

where <username> should be replaced by your Swarthmore username. You may add whatever materials to this repository you please, but your answers to each question must be clearly identified.

Design Principles

We discussed several design principles in class: DRY, SRP, OCP, LSP, ISP, and DIP. For each of the following pieces of code, identify the design principle which is being most directly disobeyed, explain why, and clearly describe what can be done to fix the problem.

  1. This method of an Account class charges a visit to the account’s balance.

    public void chargeVisit(String typeOfVisit) {
        if (typeOfVisit.equals("day")) {
            this.balance -= 40;
        } else if (typeOfVisit.equals("overnight")) {
            this.balance -= 150;
            this.stays += 1;
        } else if (typeOfVisit.equals("weekend")) {
            this.balance -= 250;
            this.stays += 2;
        } else {
            throw new IllegalArgumentException("Unknown visit type: " + typeOfVisit);
        }
    }
    
  2. This code fragment configures a series of routes for a Spark server.

    service.get("/step1", stepRoutes[0], new VelocityTemplateEngine());
    service.get("/step2", stepRoutes[1], new VelocityTemplateEngine());
    service.get("/step3", stepRoutes[2], new VelocityTemplateEngine());
    service.get("/step4", stepRoutes[3], new VelocityTemplateEngine());
    service.get("/step5", stepRoutes[4], new VelocityTemplateEngine());
    service.get("/step6", stepRoutes[5], new VelocityTemplateEngine());
    service.get("/step7", stepRoutes[6], new VelocityTemplateEngine());
    service.get("/step8", stepRoutes[7], new VelocityTemplateEngine());
    
  3. This class represents a node in a binary tree of integers.

    public class BinaryTreeNode {
        public final int value;
        public final BinaryTreeNode left;
        public final BinaryTreeNode right;
        public BinaryTreeNode(int value, BinaryTreeNode left, BinaryTreeNode right) {
            this.value = value;
            this.left = left;
            this.right = right;
        }
        public int sum() {
            int total = this.value;
            if (left != null) {
                total += left.sum();
            }
            if (right != null) {
                total += right.sum();
            }
            return total;
        }
    }
    
  4. This function adds a list of numbers and returns the result.

    public int sum(ArrayList<Integer> list) {
        int total = 0;
        for (Integer i : list) {
            total += i;
        }
        return total;
    }
    
  5. This class attempts to define a crude set data structure with \(O(n)\)-time operations.

    public class LinearSet<T> extends ArrayList<T> {
        @Override
        public void add(T t) {
            if (!this.contains(t)) {
                super.add(t);
            }
        }
    }
    
  6. This code defines an interface for audio playback.

    public interface AudioPlayer {
        public AudioTrack loadAudioFile(File file);
        public AudioPlayback playAudioTrack(AudioTrack track);
    }
    
  7. This code defines an API for interacting with a batch computing cluster.

    public interface ClusterManager {
        public int getJobCount();
        public List<JobId> getActiveJobIds();
        public JobId startJob(Job job);
        public double getJobProgress(JobId id);
        public void waitForJobToFinish(JobId id);
        public void pauseJob(JobId id);
        public void resumeJob(JobId id);
        public List<MachineId> getMachineIds();
        public MachineId getMachineIdForJob(JobId id);
        public List<JobId> getJobsOnMachine(MachineId id);
        public double getClusterLoadPercentage();
        public DiagnosticReport runClusterDiagnostics();
        public void restartCluster();
    }
    
  8. This code renders a tile in ChessForge.

    public class GUITile extends MyChessForgeTile {
        private ImageView view;
        public ImageView getImageView() {
            if (view != null) {
                return view;
            }
            Image image;
            Effect effect;
            // ... code here to set image and effect ...
            view = new ImageView(image);
            view.setEffect(effect);
            return view;
        }
    }