Lesson 8

Designing and implementing java applications.

Objectives

Understand how to apply OOP principles for designing and implementing Java applications.

Documentation

Exercises

Exercise 1

Create UML class diagram for application in package oop.banca.

Exercise 2

Create UML class diagram for application in package oop.senzor.

Exercise 3

Train traffic simulator java application is presented in the listing bellow. Implement and run the program and then resolve the requirements at the end of the program.

import java.util.*;
 
public class Simulator {
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
 
		//build station Cluj-Napoca
		Controler c1 = new Controler("Cluj-Napoca");
 
		Segment s1 = new Segment(1);
		Segment s2 = new Segment(2);
		Segment s3 = new Segment(3);
 
		c1.addControlledSegment(s1);
		c1.addControlledSegment(s2);
		c1.addControlledSegment(s3);
 
		//build station Bucuresti
		Controler c2 = new Controler("Bucuresti");
 
		Segment s4 = new Segment(4);
		Segment s5 = new Segment(5);
		Segment s6 = new Segment(6);
 
		c2.addControlledSegment(s4);
		c2.addControlledSegment(s5);
		c2.addControlledSegment(s6);
 
		//connect the 2 controllers
 
		c1.setNeighbourController(c2);
		c2.setNeighbourController(c1);
 
		//testing
 
		Train t1 = new Train("Bucuresti", "IC-001");
		s1.arriveTrain(t1);
 
		Train t2 = new Train("Cluj-Napoca","R-002");
		s5.arriveTrain(t2);
 
 
		c1.displayStationState();
		c2.displayStationState();
 
		System.out.println("\nStart train control\n");
 
                //execute 3 times controller steps
		for(int i = 0;i<3;i++){
			System.out.println("### Step "+i+" ###");
			c1.controlStep();
			c2.controlStep();
 
			System.out.println();
 
			c1.displayStationState();
			c2.displayStationState();
		}		
	}
 
}
 
class Controler{
 
	String stationName;
 
	Controler neighbourController;
 
	//storing station train track segments
	ArrayList<Segment> list = new ArrayList<Segment>(); 
 
	public Controler(String gara) {
		stationName = gara;
	}
 
	void setNeighbourController(Controler v){
		neighbourController = v;
	}
 
	void addControlledSegment(Segment s){
		list.add(s);
	}
 
	/**
         * Check controlled segments and return the id of the first free segment or -1 in case there is no free segment in this station
         * 
	 * @return
	 */
	int getFreeSegmentId(){
		for(Segment s:list){
			if(s.hasTrain()==false)
				return s.id;
		}
		return -1;
	}
 
	void controlStep(){
			//check which train must be sent
 
			for(Segment segment:list){
				if(segment.hasTrain()){
					Train t = segment.getTrain();
 
					if(t.getDestination().equals(neighbourController.stationName)){
						//check if there is a free segment
						int id = neighbourController.getFreeSegmentId();
						if(id==-1){
							System.out.println("Trenul +"+t.name+"din gara "+stationName+" nu poate fi trimis catre "+neighbourController.stationName+". Nici un segment disponibil!");
							return;
						}
						//send train
						System.out.println("Trenul "+t.name+" pleaca din gara "+stationName +" spre gara "+neighbourController.stationName);
						segment.departTRain();
						neighbourController.arriveTrain(t,id);
					}
 
				}
			}//.for
 
		}//.
 
 
	public void arriveTrain(Train t, int idSegment){
		for(Segment segment:list){
			//search id segment and add train on it
			if(segment.id == idSegment)
				if(segment.hasTrain()==true){
					System.out.println("CRASH! Train "+t.name+" colided with "+segment.getTrain().name+" on segment "+segment.id+" in station "+stationName);
					return;
				}else{
					System.out.println("Train "+t.name+" arrived on segment "+segment.id+" in station "+stationName);
					segment.arriveTrain(t);
					return;
				}			
		}
 
		//this should not happen
		System.out.println("Train "+t.name+" cannot be received "+stationName+". Check controller logic algorithm!");
 
	}
 
 
	public void displayStationState(){
		System.out.println("=== STATION "+stationName+" ===");
		for(Segment s:list){
			if(s.hasTrain())
				System.out.println("|----------ID="+s.id+"__Train="+s.getTrain().name+" to "+s.getTrain().destination+"__----------|");
			else
				System.out.println("|----------ID="+s.id+"__Train=______ catre ________----------|");
		}
	}
}
 
 
class Segment{
	int id;
	Train train;
 
	Segment(int id){
		this.id = id;
	}
 
	boolean hasTrain(){
		return train!=null;
	}
 
	Train departTRain(){
		Train tmp = train;
		this.train = null;
		return tmp;
	}
 
	void arriveTrain(Train t){
		train = t;
	}
 
	Train getTrain(){
		return train;
	}
}
 
class Train{
	String destination;
	String name;
 
	public Train(String destinatie, String nume) {
		super();
		this.destination = destinatie;
		this.name = nume;
	}
 
	String getDestination(){
		return destination;
	}
 
}

Requirements:

  • Create UML class diagram for the application above;
  • Modify the application so that a controller to communicate with an unlimited number of neighbor controllers;
  • Modify main method to demonstrate to behavior of the new application and crate a network of 3 stations interconnected one to each-other.

Exercise 4

Implement a home automation simulator application based on the following requirements:

  1. Home automation system is composed of: control unit, temperature sensor, fire sensor, alarm unit, heating unit, cooling unit, gsm unit;
  2. Fire rule: if fire sensor is activated then start alarm and call owner
  3. Temperature rules: if temperature is lower than a preset value then start heating unit; if temperature is higher than a preset value then start cooling unit;
  4. System includes one temperature sensor but multiple fire sensors;
  5. All controller actions are stored in an system_logs.txt;
  6. Use Singleton design pattern for the control unit;
  7. All system actions are simulated by simple console messages;
  8. For testing your application use the provided code bellow.
import java.util.Random;
 
public class HomeAutomation {
 
     public static void main(String[] args){
 
         //test using an annonimous inner class 
         Home h = new Home(){
             protected void setValueInEnvironment(Event event){
                System.out.println("New event in environment "+event); 
             }
             protected void controllStep(){
                 System.out.println("Control step executed");
             }
         };
         h.simulate();
     }
}
 
abstract class Home {
    private Random r = new Random();
    private final int SIMULATION_STEPS = 20;
 
    protected abstract void setValueInEnvironment(Event event);
    protected abstract void controllStep();
 
    private Event getHomeEvent(){
        //randomly generate a new event;            
        int k = r.nextInt(100);
        if(k<30)
            return new NoEvent();
        else if(k<60)
            return new FireEvent(r.nextBoolean());
        else
            return new TemperatureEvent(r.nextInt(50));              
    }   
 
    public void simulate(){
        int k = 0;
        while(k <SIMULATION_STEPS){
            Event event = this.getHomeEvent();
            setValueInEnvironment(event);
            controllStep();
 
            try {
                Thread.sleep(300);
            } catch (InterruptedException ex) {
               ex.printStackTrace();
            }
 
            k++;
        }
    }
 
}
 
abstract class Event {
 
    EventType type;
 
    Event(EventType type) {
        this.type = type;
    }
 
    EventType getType() {
        return type;
    }
 
}
 
class TemperatureEvent extends Event {
 
    private int vlaue;
 
    TemperatureEvent(int vlaue) {
        super(EventType.FIRE.TEMPERATURE);
        this.vlaue = vlaue;
    }
 
    int getVlaue() {
        return vlaue;
    }
 
    @Override
    public String toString() {
        return "TemperatureEvent{" + "vlaue=" + vlaue + '}';
    }        
 
}
 
class FireEvent extends Event {
 
    private boolean smoke;
 
    FireEvent(boolean smoke) {
        super(EventType.FIRE);
        this.smoke = smoke;
    }
 
    boolean isSmoke() {
        return smoke;
    }
 
    @Override
    public String toString() {
        return "FireEvent{" + "smoke=" + smoke + '}';
    }
 
}
 
class NoEvent extends Event{
 
    NoEvent() {
        super(EventType.NONE);
    }    
 
    @Override
    public String toString() {
        return "NoEvent{}";
    }   
}
 
enum EventType {
    TEMPERATURE, FIRE, NONE;
}
)}