Czy istnieje alternatywa dla wielu małych funkcji?

0

Hejoo, istnieje może fajna alternatywa dla wielu małych funkcji, które załóżmy mają po dwie-trzy linijki kodu? 10 voidów, a potem wywoływanie ich po sobie w mainie brzydko wygląda, a wręcz podejrzanie. Wiecie coś? Pozdro!

0

klasy

1

Jeśli niektóre z tych 10 funkcji są ze sobą spójne biznesowo, np flushCache(), revalidateCache() oraz setDefaultCache() możesz je połączyć w jedną clearCache().

Jeśli natomiast nie są związane biznesowo (w co mi ciężko uwierzyć), czyli każda robi coś innego, no to cóż, to źle że jest 10 wywołań? Jeśli te 10 rzeczy, za które odpowiadają funkcje faktycznie robią to co powinny, czyli odzwierciedlają intencje programu, to chyba nie jest źle. Po co to ukrywać pod warstwami abstrakcji czy klas i pogarszać specjalnie czytelność kodu.

0

@TomRiddle: Funkcje działają prawidłowo, ale wygląda to po prostu nieczytelnie i w jakiś sposób chciałbym to polepszyć wizualnie. Zobacz:

    Kelvin(temperature);
    Fahrenheit(temperature);
    Rankine(temperature);
    Delisle(temperature);
    Newton(temperature);
    Reaumur(temperature);
    Romer(temperature);

Słabo wygląda takie coś. Chyba, że po prostu ja sobie coś ubzdurałem i wszystko jest w porządku

0

Możesz wkleić jedną z tych funkcji? Rozumiem że one działają podobnie do siebie?

Wygląda to tak jakby każda z nich robiła tą samą rzecz, tylko w kilka róznych sposobów, co oznacza że faktycznie są ze sobą związane biznesowo i najprawdopodoniej można to zrefaktorować tak żeby się tego pozbyć.

0

Brzmi jak możliwość zastosowania wzorca Strategy.

0

Jeśli te funkcje zawsze występują po sobie i w tej samej kolejności, można stworzyć tablicę wskaźników na te funkcje.
std::vector, std::function.

0

Tak to wygląda:


#include <iostream>
#include <conio.h>

std::string cel = "Celsius degrees";
void Kelvin(double temp)
{
    double kelvin = 273.15;
    std::cout << temp << " " << cel << " = " << kelvin+temp << " Kelvin degrees" << std::endl;
}
void Fahrenheit(double temp)
{
    double fahrenheit = 32+1.8*temp;
    std::cout << temp << " " << cel << " = " << fahrenheit << " Fahrenheit degrees" << std::endl;
}
void Rankine(double temp)
{
    double rankine = temp+273.15;
    std::cout << temp << " " << cel << " = " << rankine*1.8 << " Rankine degrees" << std::endl;
}
void Delisle(double temp)
{
    double delisle = 100 - temp;
    std::cout << temp << " " << cel << " = " << delisle*1.5 << " Delisle degrees" << std::endl;
}
void Newton(double temp)
{
    double newton = temp*33;
    std::cout << temp << " " << cel << " = " << newton / 100 << " Newton degrees" << std::endl;
}
void Reaumur (double temp)
{
    double reaumur = temp*0.8;
    std::cout << temp << " " << cel << " = " << reaumur << " Reaumur degrees" << std::endl;
}
void Romer (double temp)
{
    double romer = temp*21/40+7.5;
    std::cout << temp << " " << cel << " = " << romer << " Romer degrees" << std::endl;
}
int main()
{

    std::cout << "Enter temperature in Celsius: ";
    double temperature;
    std::cin >> temperature;
    Kelvin(temperature);
    Fahrenheit(temperature);
    Rankine(temperature);
    Delisle(temperature);
    Newton(temperature);
    Reaumur(temperature);
    Romer(temperature);
    getch();
    return 0;
}

Jak widać funkcje robią to samo, tylko wzór jest inny.

2

Zauważ że one wszystkie mają postać

void NAZWA(double temp)
{
    double jednostka = // przeliczanie jednostek ;
    std::cout << temp << " " << cel << " = " << jednostka << " NAZWA degrees" << std::endl;
}

To znaczy że to miejsce odpowiedzialne za przeliczanie jednostek można wydzielić, a resztę funkcji użyć ponownie, pisząc ją tylko raz, i przekazywać do niej różne implementacje przeliczania jednostek. Googlaj pod hasłami "C++ polymprhism"/"C++ polimorfizm" albo tak jak proponował kolega "C++ Strategy pattern".

0

Te wzorce projektowe wydają się być super sprawą, na pewno się nimi zainteresuję. Dzięki za sugestie. ;)

0

a nie może być tak ?

#include <iostream>
	#define Fahrenheit(temp) std::cout<<32+(1.8*(temp))<<" Fahrenheit"<<std::endl;

	int a;
int main()
{
	std::cin >> a;
	Fahrenheit(a);
}

dla reszty nie chciało mi się wypisywać xD
możesz też zrobić ja to nazywam "składaka" ale tutaj nie chce mi się opisywać... poza tym to chyba w newbie ( taki dział forum ja się nie znam xD )
ale to newbie chyba znaczy że początkujący więc robienie składaków może być trudniejsze :P w każdym razie "Działanie" matematyczne oraz tekst
możesz też przechować w zmiennych i np. utworzyć se coś na wzór struktury która po prostu dostaje symbol jak np. d f m ( double , flo .. .. ) i sama
sobie daje rade z przeliczeniem :P oraz dobraniem odpowiedniego słowa pod koniec xD lel...

skasuj { } i twoje rozwiązanie też będzie dobre :P przy okazji jak chcesz skasować jeszcze więcej linii kodu to możesz zrobić tag:

void Romer (double temp){
    std::cout << temp << " " << cel << " = " << temp*21/40+7.5 << " Romer degrees" << std::endl;}

też zadziała a masz tylko 2 linijki kodu xD na upartego można to jeszcze zmniejszyć :P

wystarczy zrobić se strukturę w której przechowasz końcówki zdania ( "Romer" , "Newton" ... ... ... ); oraz działania matematyczne
no ale to nieco zabawniejsza metoda xD poza tym alternatywą dla wielu małych funkcji mogła by być duża klasa ? :P

0

Mi się wydaję, że sporym problemem jest sam przykład. Jeśli jedyną funkcją tego programu jest przeliczenie i wyświetlanie temperatur, to na dobrą sprawę nawet funkcje nie są potrzebne bo i po co? Gdyby jednak uzyskiwane dane miały sens z punktu widzenia dalszego działania programu (funkcje zwracały by wartość zamiast void), wtedy można myśleć o np. tworzeniu struktur, grupowaniu funkcji w kontenerach, klasach czy cokolwiek innym czyniącym nasz kod ładniejszym.

0

Każdą z tych funkcji da się opisać jako jakieś ax + b, tak więc wszystko to można łatwo wrzucić do tablicy.

0
enedil napisał(a):

Każdą z tych funkcji da się opisać jako jakieś ax + b, tak więc wszystko to można łatwo wrzucić do tablicy.

To jest szczególny przypadek, nie zawsze będą miały taką postać.

3

Jej ... nad czym tu tak deliberować. Wzorce!?

// .... 
int main()
{
    std::cout << "Enter temperature in Celsius: ";
    double temperature;
    std::cin >> temperature;

    for(auto & func: { Kelvin, Fahrenheit, Rankine, Delisle, Newton, Reaumur, Romer} ) {
		func(temperature);
    }
}

Można jeszcze ew. foldin'giem zwinąć ale bez przesady. Do takiego "wyzwania" zbędne jest klepanie opakowania.

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