Poprawa i rozbudowa konwertera

0

Napisałam program który ma przeliczać PLN na USD i EUR ze stale przypisanymi wartościami danych walut. Program działa, ale chciałam się zapytać czy można to zrobić lepiej( lub w ogóle naprawić).
Wydaje mi się, że jest za dużo zmiennych, a eclipse podkreśla mi zmienne MoneyFromUser i MoneyFromUser2 na żółto i mówi, że wartość pola nie jest używana, a gdy je usuwam to pojawiają się błędy. W tytule tematu jest też mowa o rozbudowie, ale o tym napiszę później, bo najpierw chce się upewnić że tu wszystko dobrze zrobiłam.

Jeszcze te obliczenia w konstruktorze, nie wiem czy można tak robić, wstawiłam i działa, ale kto wie...

Program zawiera dwie klasy Converter.java i ConverterMain.java

package pl.wioletta.converter;

import java.util.Scanner;


public class ConverterMain {
	

	public static void main(String[] args) {
		
		
		Scanner scannerin = new Scanner(System.in);
		
		
		System.out.println("Podaj 1 kwotę w PLN: ");
		double MoneyFromUser = takeData(scannerin) ; 
		
		System.out.println("Podaj 2 kwotę w PLN: ");
		double MoneyFromUser2 = takeData(scannerin) ; 
		
		
		
		Converter firstObject = new Converter(MoneyFromUser, MoneyFromUser2 );
		
		System.out.println("1 kwota PLN wynosi: " + firstObject.getEURfromPLN() + " EUR, 2 kwota PLN wynosi: " + firstObject.getEURfromPLN2() + " EUR"  );
		System.out.println("1 kwota PLN wynosi: " + firstObject.getUSDfromPLN() + " USD, 2 kwota PLN wynosi: " + firstObject.getUSDfromPLN2() + " USD"  );
	}

	
	public static double takeData(Scanner scannerin) 
	{
	    return scannerin.nextDouble();
	}
	
	
}
package pl.wioletta.converter;

public class Converter {

	private final double EUR = 4.37 ;
	private final double USD = 3.93 ;
	private double EURfromPLN ;
	private double EURfromPLN2 ;
	private double USDfromPLN ;
	private double USDfromPLN2 ;	
	private double MoneyFromUser ;
	private double MoneyFromUser2 ;
	
	
	public Converter(double MoneyFromUser, double MoneyFromUser2)
	  
	 {
	        this.MoneyFromUser=MoneyFromUser;
	        this.MoneyFromUser2=MoneyFromUser2;
			
	        EURfromPLN = MoneyFromUser * EUR;			
	        EURfromPLN2 = MoneyFromUser2 * EUR;
	        
	        USDfromPLN = MoneyFromUser * USD;
	        USDfromPLN2 = MoneyFromUser2 * USD;
	        
	        
	    }
	    
	    public double getEURfromPLN() {
	    	return EURfromPLN;
	    }
	    public double getEURfromPLN2() {
	    	return EURfromPLN2;
	    }
	    
	    public double getUSDfromPLN() {
	    	return USDfromPLN;
	    }
	    public double getUSDfromPLN2() {
	    	return USDfromPLN2;
	    }
	    
	    

}
2

Gdybyś miała obsłużyć dziesięć walut to wygenerowałabyś dwadzieścia metod i dziesięcioargumentowy konstruktor?

Niech klasa konwertera będzie:

  1. ... albo miała metodę double convert(double value, enum conversionType) przyjmującą jedną liczbę oraz enuma określającego rodzaj konwersji (bądź dwa enumy - czyli waluta wejściowa oraz waluta wyjściowa), a zwracająca już przekonwertowaną liczbę (tym samym zamieniając klasę na czysto statyczną),
  2. ... albo miała metody double convertEurToPln(double eur), double convertPlnToUsd(double pln) i tak dalej przyjmujące i zwracające jedną liczbę bez setterów oraz getterów (podobnie jak wyżej, efektywnie tworząc z niej klasę statyczną),
  3. ... albo, jeśli lubisz masturbację kodem, utwórz interfejs zawierający metodę double convert(double value), a następnie twórz setki klas dla każdego rodzaju przeliczania - co kto lubi.
    Poza tym po co Ci metoda takeData?
    Abstrahując od błędnego nazewnictwa (przyjmowanie danych od użytkownika określa czasownik read), scannerin.nextDouble() pisze się za długo czy może za mało czytelnie? Nie kombinuj pod górkę.

No i ktoś jeszcze mógłby się doczepić o to, że nie powinno się liczyć finansów wykorzystując liczby zmiennoprzecinkowe - nad tym także wypadałoby pomyśleć.

2

Ja bym to zaprojektował zupełnie inaczej, tak jak napisał @Patryk27 w 1 i 3

  • metoda convert przyjmująca enumy z typem waluty wejściowej oraz z typem waluty wyjściowej, a także wartością (raczej Decimal niż double!)
  • interfejs Converter który ma 2 metody -> toIndependentValue i fromIndependentValue
  • dla każdej waluty mamy implementacje tego interfejsu która to zamienia podaną wartość na jakąś ustaloną walutę "niezależną" oraz z tej niezależnej waluty na daną. Powiedzmy że niezależna będzie PLN więc jeśli euro kosztuje 4zł to EuroConverter w jednej metodzie dzieli wartość przez 4 a w drugiej mnoży przez 4.
  • w klasie converter masz dwie mapy EnumMap<CurrencyEnum, Converter> jedna do konwersji "na" a druga do konwersji "z" danej waluty. Konwersja polega na tym że z mapy do konwersji "z" danej waluty wyciągamy konwerter wejściowy i podaną kwotę zamieniamy na niezależną wartość za pomocą independentValue = converter.toIndependentValue(value), następnie z drugiej mapy wyciągamy konwerter wyjściowy którym zamieniamy niezależną wartość na kwotę w innej walucie za pomocą resultValue = converter.fromIndependentValue(independentValue).

Testy konwerterów powinny być wygodne bo wystarczy sprawdzić czy dla kilku randomowych wartości spełnione jest zawsze converter.toIndependentValue(converter.fromIndependentValue(random)) == random oraz czy converter.fromIndependentValue(converter.toIndependentValue(random)) == random

0

Zanim zacznę to robić waszym sposobem, a zejdzie mi z tym długo bo widzę tu dużo nowych pojęć itp. to chciałam zapytać jak dodać do tego co już napisałam taką funkcjonalność, że po otrzymaniu od użytkownika dwóch kwot, program nie wyświetla od razu przeliczone waluty, tylko pyta na co ma przeliczyć, EUR czy USD i liczy tylko to co użytkownik będzie chciał.

0

Po co się pytasz o gotowe rozwiązania. To są podstawy. Sama spróbuj to ogarnąć, bo inaczej się nie nauczysz. Dopiero jak masz konkretny problem, to pytaj.

0

a właśnie że nie pytałam o gotowe rozwiązanie, nie chce kodu, tylko czego muszę użyć, np. jakich metod(albo jak ich szybko szukać, jest ich dużo, więc do każdego zadania chyba się nie opłaca przeglądać wszystkich po alfabecie) żeby to wyszło, resztę sobie znajdę i będę próbowała zrobić

program i co on ma robić też sobie sama wymyśliłam

0

Już wiem jak to zrobić, wystarczyła pętla if i metoda equals, jest tylko jeden problem, ta pętla z metodą działa mi w innych programach, w tym program przestaje w pewnej chwili działać, a dokładnie konsola nie chce przyjmowac odpowiedzi po pytaniu EUR czy USD

package pl.wioletta.converter;

import java.util.Scanner;


public class ConverterMain {
	

	public static void main(String[] args) {
		
		
		Scanner in = new Scanner(System.in);
		
		
		System.out.println("Podaj 1 kwotę w PLN: ");
		double MoneyFromUser = in.nextInt() ; 
		
		System.out.println("Podaj 2 kwotę w PLN: ");
		double MoneyFromUser2 = in.nextInt() ;
		

		
		Converter firstObject = new Converter(MoneyFromUser, MoneyFromUser2 );
		
		
		String input;
		
		System.out.println("Chcesz przeliczyć na EUR czy USD ? (EUR/USD)");
		input = in.nextLine();

		if (input.equals("EUR"))
		{
			System.out.println("1 kwota PLN wynosi: " + firstObject.getEURfromPLN() + " EUR, 2 kwota PLN wynosi: " + firstObject.getEURfromPLN2() + " EUR"  );
		}
		
		else if (input.equals("USD"))
		{
			System.out.println("1 kwota PLN wynosi: " + firstObject.getUSDfromPLN() + " USD, 2 kwota PLN wynosi: " + firstObject.getUSDfromPLN2() + " USD"  );
		}
		


	}
	
	
	
}
1

Tak jak doradzili Tobie wyżej, zamiast w konstruktorze logikę daj do metody z argumentami jak w konstruktorze i ją wywołuj na tym samym obiekcie Converter.
Poza tym 1 PLN nie kosztuje 4 EUR tylko na odwrót.

Ogólnie ja bym Ci doradzał wzięcie się za jakieś tomisko do Javy, żeby zrozumieć o co w tej obiektowości chodzi. Sam po jakimś kursie napisałem taki program, że jakby się nim pochwalił to bym wygrał nagrodę na najgłupszy program roku ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1