Ogromnie Obrzydliwy Paradygmat
Co sądzisz o OOP?
- Rejestracja: dni
- Ostatnio: dni
- Postów: 750
- Rejestracja: dni
- Ostatnio: dni
Propsy za przemyślaną ankietę 👍🏻

- Rejestracja: dni
- Ostatnio: dni
- Postów: 358
Ja nigdy nie rozumiem o co chodzi z tym OOP.
W C++ dodali struktury tak, że metody są przyczepione do struktury i nie trzeba szukać.
Ja lubię OOP nie wiem czy o to chodzi, ale dobrze jest jak masz MemoryManagment i po prostu jakaś klasa odpowiada za to, lubię struktrualnie pisać, ale jak jest kod ładnie upakowany edytor umie podpowiadać bo jak są struktury to nie umie, ale od c++ struktura === klasa, a na poziomie assemblera to i tak zawsze było tym samym, nigdy nie było różnicy tylko łatwiej idzie tym zarządzać.
W C++ struktura i klasa czyli obiekt jak się utworzy z tej klasy jest tym samym, edytor czyli language server umie podpowiadać dobrze jak wie, że dane są ze sobą ściśle powiązane czyli jak w obiekcie.
W C++ struktura też może mieć metody jak w obiekcie czyli edytor możę łatwo przewidywać jakie funkcje dla danej struktury możesz użyć.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 8488
.GodOfCode. napisał(a):
language server umie podpowiadać dobrze jak wie, że dane są ze sobą ściśle powiązane czyli jak w obiekcie.
Language server to protokoł, a nie coś absolutnego. Jeśli istniejąca do danego języka implementacja language servera jest słaba, to można zrobić lepszą.
W C++ struktura też może mieć metody jak w obiekcie czyli edytor możę łatwo przewidywać jakie funkcje dla danej struktury możesz użyć.
Tutaj trzeba spojrzeć szerzej. To, o czym piszesz, to ograniczenia toolingu, a nie paradygmatu.
Pisząc w C++ jesteś ograniczony składnią C++, która wywiera wpływ na to, jak to jest dalej parsowane i jak dobry masz tooling. Być może w innym, bardziej statycznie typowanym, języku będziesz mieć lepszy tooling.
Chyba, że mówisz po prostu o tym, że klasa jest przestrzenią nazw i dając foo. już wiadomo, że trzeba podpowiedzieć coś związanego z foo. a nie totalnie wszystko. Ale... dla mnie to jest zagadnienie poboczne do całego paradygmatu. W programowaniu proceduralnym też możesz mieć przestrzenie nazw.
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: U krasnoludów - pod górą
- Postów: 4712
krsp napisał(a):
Czy DDD jest oparte na OOP? DDD też nie lubimy?
DDD to dopiero naprawdę nie lubimy, OOP przy tym to pestka.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 833
krsp napisał(a):
Czy DDD jest oparte na OOP?
Nie. DDD to zestaw wzorców i praktyk, nie implementacji. Strategiczne DDD nie ma nic wspólnego z kodem. W taktycznym DDD nie ma znaczenia w jakim paradygmacie piszesz agregaty, value objecty czy encje. Jak poszukasz to znajdziesz przykłady implementacji DDD w językach funkcyjnych, bo DDD to sposób myślenia o architekturze aplikacji, nie konkretnej technologii czy metodyce programowania.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 2553
Po co wymyślać coś nowego skoro klienci i tak kupią więcej RAMu, żeby program mógł przerzucać ogromnymi obiektami xd.
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: U krasnoludów - pod górą
- Postów: 4712
Czitels napisał(a):
Po co wymyślać coś nowego skoro klienci i tak kupią więcej RAMu, żeby program mógł przerzucać ogromnymi obiektami xd.
Jeśli jakoś przespałeś ostatnie kilka lat to mały update - obecnie rzadko kiedy klienci kupują RAM. Wynajmują sobie, a nawet to my im wynajmujemy - żeby nie musieli się martwić.
1.5 terabajta wystarczy każdemu.
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Silesia/Marki
- Postów: 5550
W Javie mam wrażenie iż nigdy OOP nie pyknął. JEE i a później Spring promowały anemiczny model dziedziny, encje i serwisy, później encje i serwisy bezstanowe. Z OOP ma to tylko tyle wspólnego iż serwisy mają często interfejs. Jakby w Javie zakazano dziedziczyć po klasach to pewnie by w 75% projektów nie zauważyli. A przecież od razu widać iż encje i serwisy to już prawie, w zasadzie rekordy i modułu z funkcjami. A więc enterprisowym projektom javowym bliżej do FP niż do OOP. Może jakbym został C#powcem to bym zrozumiał OOP, ale tak to nie mialem potrzeby
UPDATE w javie jedyne OOP jakie spotkałem to to iż trzeba umieć recytować SOLID na rekrutacjach. Nie wiem po co, ale tech liderzy Javy lubią słuchać recytacji SOLID
- Rejestracja: dni
- Ostatnio: dni
- Postów: 5227
OOP to najbardziej wpływowy zbiór konceptów dot. modelowania fragmentów świata rzeczywistego za pomocą języków programowania.
Umożliwił on przez ostatnie dekady milionom programistów wykonanie cyfrowej transformacji i przeniesienie wielu procesów w świat komputerów m.in ze względu na swoją prostotę i łatwość mapowania konceptów rzeczywistych z ich cyfrowym modelem (oczywiście w 99% uproszczonym modelem).
OOP jak każdy inny paradygmat może być różnie interpretowany, dlatego widzimy różnice w OOPie pomiędzy różnymi językami programowania implementującymi w różnym stopniu ten paradygmat (np. C++owy friend).
Czy krytyka OOP jest zasadna? uważam że nie do końca, OOP ma swoje wady np. zbyt duże pchanie się w koncepty dziedziczenia którymi łatwo sobie zrobić krzywdę, jednakże koniec końców wyszedł na PLUS dla świata.
Nagonka na OOP bardziej wygląda tak, że kilku hipsterów naczytało się na 4p dwóch czy trzech pozytywnych postów o innych paradygmatach, o których zapomnieli 2 flaszki po zaliczonej kartkówce z "Paradygmatów programowania" w koledżu, ale teraz chcą się pobrandzlować :D
- Rejestracja: dni
- Ostatnio: dni
- Postów: 10227
Zacznijmy od tego że dwadzieścia osób kiedy mówi o OOP to ma na myśli różne rzeczy. Geneza , zaszłośc historyczne, osobiste uprzedzenia , dopowiedzenia.
Rozmowa o tym bez jakichś konkretnych określeń o czym mowa - nie ma sensu.
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Silesia/Marki
- Postów: 5550
Riddle napisał(a):
Rozmowa o tym bez jakichś konkretnych określeń o czym mowa - nie ma sensu.
A teraz skandujemy - Definicja, definicja, definicja!
- Rejestracja: dni
- Ostatnio: dni
- Postów: 32
Z takimi tematami jest jak z magia. Magik przybywa do firmy aby prawic prawdy objawione, wszyscy kiwaja glowami, a po szkoleniu wracamy do tego, co bylo.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 10227
KamilAdam napisał(a):
Riddle napisał(a):
Rozmowa o tym bez jakichś konkretnych określeń o czym mowa - nie ma sensu.
A teraz skandujemy - Definicja, definicja, definicja!
Nie chodzi mi o definicję, tylko o jakieś przekonanie że mówimy o tym samym.
Wyobrażam sobie że jak ktoś używa określenia "OOP", to zależnie od swojej wiedzy, umiejętności, i tego się uczył może mieć na myśli, paradygmat, ale może ten paradygmat rozumieć różnorako, np.:
- Może to rozumieć tak, że po prostu otwiera projekt, widzi same klasy i myśli: "o, to jest OOP"
- Może to rozumieć jak Robert Martin, że OOP to jest "dyscyplina nałożona na niebezpośredni transfer kontroli"
- Może mieć w głowie slogany: enkapsulacja, dziedziczenie, polimorfizm
- Może to rozumieć przez pryzmat języków Java i C# gdzie (przynajmniej we wczesnych wersjach) kod dało się tylko pisać jako członek klasy
- Może po prostu woleć pisać
classniżfunction, i twierdzi że to jest OOP - Może myśleć o milionie wzorców, dekoratory, kompozyt, etc.
- Może na to patrzeć przez pryzmat tych dziwnych relacji is-a, has-a
- Może utożsamia OOP z interfejsami z javy które potem poszły na inne języki (i twierdzi że jak jest
interfaceto jest to polimorfizm, a duck-typing już polimorfizmem nie jest). - Jeszcze inni mogą myśleć że OOP jest tylko wtedy kiedy wystąpi słowo
classw kodzie, a jeśli zrobimy np funkcje w JS która zwraca dictinoary z domknięciami to już obiektem nie jest (bo jestfunctionzamiatclass). - Może do tego podchodzić niskopoziomowo, i rozumieć to tak że obiekt to jest cokolwiek co żyje na stercie.
- Może na to patrzeć że dziedziczenie da się załatwić strukturami, a enkapsulację funkcjami, więc jedyne co wnosi OOP "nowego" to jest polimorfizm (z tą różnicą że polimorfizm da się też ogarnąć anonimowymi funkcjami które zacierają granice między obiektem i funkcją).
Nie mówiąc o tym że ktoś może mieć milion uprzedzeń i naleciałości. Ja osobiście uważam że tylko ostatnia pozycja jest prawdziwa, a pozostałe nie; ale to jest moja opinia. Inni mogą mieć inne.
Więc moim zdaniem ta dyskusja nie ma sensu, bez sprecyzowania o "które" OOP chodzi. Określenie OOP jest bardzo popularne, i ludzie bardzo łatwo lubią podpinać swoje przekonania pod taki popularny banner.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 2553
dr.hard napisał(a):
Z takimi tematami jest jak z magia. Magik przybywa do firmy aby prawic prawdy objawione, wszyscy kiwaja glowami, a po szkoleniu wracamy do tego, co bylo.
To jest dość życiowe xd Szczególnie na tych wszystkich szkoleniach z wzorców, wielowątkowości itd.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1023
OOP to rozmyte podejście, które w sumie nie oznacza nic przez to, że OOP jest wszędzie. Idąc od najbardziej (według mnie) oczywistości do bardziej kontrowersyjnych:
- OOP to paradygmat, który ułatwia łatwe łączenie kodu z danymi. Takie coś da się osiągnąć w każdym języku. Najlepszym przykładem są generyczne struktury danych, które mają złożony stan wewnętrzny, który musi być modyfikowany i czytany w określony sposób. Niezależnie od paradygmatu czy to imperatywny czy funkcyjny: enkapsulacja i wyznaczone funkcje do czytania/modyfikowania to konieczność
- OOP to paradygmat, który pozwala na jakikolwiek polimorfizm pod postacią jakiegoś interfejsu. Takie coś mamy w praktycznie każdym nowoczesnym języku. Haskell pozwala na statyczny polimorfizm. Dobrym kontr przykładem jest C, który pozwala na polimorfizm dynamiczny (poprzez strukturę zawierającą wskaźniki do funkcji), ale jest to nie wygodne, więc to może być argument, że C nie jest OOP
- OOP to paradygmat z enkapsulacją, Enkapsulacja IMO jest dobra dla dowolnego bytu czy to klasa, struktura czy pojedyncza funkcja, więc odrzucam ten argument
- OOP to paradygmat, która ma dynamiczny polimorfizm. Argumentem przeciwnym jest to, że możemy bardzo łatwo zamienić taki dynamiczny polimorfizm na statyczny i według mnie nie stracimy magii OOP. Dobrym przykładem jest Rust, gdzie bardzo łatwo żonglować jednym i drugim rodzajem według potrzeb
- OOP to język, który ma klasy. Dobrym kont przykładem jest Go, gdzie metody i interfejsy możemy podpiąc pod każdy typ. Choć najczęściej są tą rzeczywiście struktury, to da się napisać kod, wyglądający jak OOP, używać polimorfizmu i nie
- OOP to paradygmat, który ma dziedziczenie. Według mnie to nie prawda, bo każdy przykład dziedziczenia można zamienić na interfejs + kompozycja (punkt 2), gdzie popularnym stwierdzeniem jest to, że taka konstrukcja jest po prostu lepsza z wielu różnych powodów: większa rozszerzalność, lepsza enkapsulacja, bardziej eleganckie z uwagi na użycie mniejszej ilości ficzerów języka
- OOP to paradygmat, który
means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. Mało języków wspiera taki paradygmat, boextreme late-bindingimessagingsprawiają, że taka implementacja jest wolna i dynamicznie typowana a w dzisiejszych czasach bardzo kładziemy na wydajność i statyczną poprawność programu
Moja opinia: zgadzam się w 100% tylko z dwoma pierwszymi punktami. Niestety (albo stety) każdy nowoczesny język według tej wykładni jest OOP.
Wydaje mi się, że język, które ewoluuje zgodnie z tradycją OOP jest OOP cokolwiek to miałoby znaczyć. Ewolucja w każdej dziedzinie nie wyklucza radykalnych zmian, które mogą sprawić, że następca jest dalej od oryginału niż mogłoby się to wydawać na pierwszy rzut oka. Pies i delfin są dużo bardziej zgodni genetycznie, ale delfin swoim stylem życia i przystowaniem bardziej przypomina rybę z uwagi na to jak zadziałała ewolucja w tym konkretnym przypadku
- Rejestracja: dni
- Ostatnio: dni
- Postów: 750
WeiXiao napisał(a):
OOP to najbardziej wpływowy zbiór konceptów dot. modelowania fragmentów świata rzeczywistego
Skończyłem czytać w tym miejscu.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 5227
Satanistyczny Awatar napisał(a):
WeiXiao napisał(a):
OOP to najbardziej wpływowy zbiór konceptów dot. modelowania fragmentów świata rzeczywistego
Skończyłem czytać w tym miejscu.
cuz? paradygmat zbiera do kupy koncepty, te koncepty są implementowane przez języki jako takie "basic primitives", które następnie są używane do modelowania problemów/fragmentów świata przez programistów.
Allegro/ebay, uber, tinder, stock market, facebook, etc... To wszystko to koncepty/procesy/zjawiska które zostały w jakimś stopniu przeniesione z świata rzeczywistego do komputera, poprzez ich zamodelowanie.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 480
Piękna sprawa i tyle. Nie mielibyście gdzie narzekać gdy nie OOP.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 252
Co to do (...) jest OOP? To jedno z najbardziej rozmytych określeń w programowaniu, każdy rozumie przez nie co innego. Chyba OOP jest jeszcze bardziej wieloznaczne niz FP, a już samo FP, wbrew pozorom, ma wiele defnicji.
MOIM ZDANIEM najbardziej użyteczna definicja OOP byłaby chyba taka: Jest to paradygmat zdefiniowany przez klasyków takich jak Martin, Fowler, Feathers, Beck, Cohn, etc, i ich książki takie jak Clean Code, Clean Architecture, Working Effectively with Legacy Code, etc. Im bliżej jesteśmy zaleceń zawartych w tych książkach, tym bardziej OOP jest nasz kod.
Wydaje mi się, że taka definicja byłaby dostatecznie blisko tego, co większość ludzi intuicyjnie rozumie przez OOP.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 5227
czemu akurat ich? to jakiś contest influencerów i ewangelistów? :D
- Rejestracja: dni
- Ostatnio: dni
- Postów: 252
WeiXiao napisał(a):
czemu akurat ich? to jakiś contest influencerów i ewangelistów? :D
Bo wydaje mi się, że ludzie zazwyczaj własnie od nich czerpią pomysły, jak powinien wyglądać kod OOP. Z kolei pomysły inne niż te przedstawiane przez przeze mnie wymienionych influencerów zazwyczaj nie są uważane za OOP. Na przykład clean architecture jest powszechnie uważany za OOP, podczas gdy konkurencyjny vertical slice już raczej nie jest uważany za OOP i raczej jest po części na fali oporu przeciwko OOP.
Zresztą influencerzy przeze mnie wymienieni chyba stworzyli wspólnie dość spójną 'szkołę' programowania, swego czasu cytowali się wzajemnie dość sporo.
Again nie chodziło mi o definicję, która z jakiegoś teoretycznego, purystycznego punktu widzenia byłaby najsensowniejsza. Ile raczej o to, jak można w maks kilku zdaniach streścić, co wydaje mi się, że ludzie zazwyczaj za OOP uważają. A wydaje mi się, że ludzie za OOP uważają to, co jest w tamtych książkach.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 32
YetAnohterone napisał(a):
Zresztą influencerzy przeze mnie wymienieni chyba stworzyli wspólnie dość spójną 'szkołę' programowania, swego czasu cytowali się wzajemnie dość sporo.
Usilowalem sluchac / ogladac krajowych influencerow branzowych. Jedni uzywaja takiego jezyka ktorego nie da sie zwyczajnie sluchac. Drudzy robia z siebie guru po to aby sprzedawac szkolenia dla ulicy czy chodzic po firmach i mowic z wiezy jak rozwiazac rozne problemy bez wnikania w detale ktore badz co badz maja spore znaczenie.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 750
OOP jest jak im pasuje. Jak im nie pasuje to wtedy nie jest OOP.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 358
Ciekawe, ja namiętnie czytam assemblera i obiekty są takie same jak struktury niczym się nie różnią, dla mnie obiekty to zwykłe miejsce w pamięci gdzie przechowujemy jakieś zmienne i tak jest rzeczywiście nie wiem czemu ludzie nie lubią OOP pewnie nie rozumieją assemblera...
Edit: proszę się nie czepiać, że nie wiem czym jest OOP :>
- Rejestracja: dni
- Ostatnio: dni
- Postów: 5
Obiektowa wersja programu w Ruby, czyż nie wygląda pięknie i czytelnie?
class Game
CHOICES = ["kamień", "papier", "nożyczki"]
def initialize
@user_score = 0
@computer_score = 0
end
def play
loop do
user_choice = get_user_choice
computer_choice = get_computer_choice
puts "Twój wybór: #{user_choice}"
puts "Wybór komputera: #{computer_choice}"
result = determine_winner(user_choice, computer_choice)
puts result
update_scores(result)
display_scores
break unless play_again?
end
end
private
def get_user_choice
puts "Wybierz: kamień, papier, nożyczki"
choice = gets.chomp.downcase
until CHOICES.include?(choice)
puts "Nieprawidłowy wybór. Wybierz: kamień, papier, nożyczki"
choice = gets.chomp.downcase
end
choice
end
def get_computer_choice
CHOICES.sample
end
def determine_winner(user_choice, computer_choice)
if user_choice == computer_choice
"Remis!"
elsif (user_choice == "kamień" && computer_choice == "nożyczki") ||
(user_choice == "papier" && computer_choice == "kamień") ||
(user_choice == "nożyczki" && computer_choice == "papier")
"Wygrałeś!"
else
"Przegrałeś!"
end
end
def update_scores(result)
case result
when "Wygrałeś!"
@user_score += 1
when "Przegrałeś!"
@computer_score += 1
end
end
def display_scores
puts "Wynik: Ty - #{@user_score}, Komputer - #{@computer_score}"
end
def play_again?
puts "Czy chcesz zagrać ponownie? (tak/nie)"
answer = gets.chomp.downcase
answer == "tak"
end
end
game = Game.new
game.play
Obiektowość w Swift też dobrze wygląda.
import Foundation
class Game {
let choices = ["kamień", "papier", "nożyczki"]
var userScore = 0
var computerScore = 0
func play() {
while true {
let userChoice = getUserChoice()
let computerChoice = getComputerChoice()
print("Twój wybór: \(userChoice)")
print("Wybór komputera: \(computerChoice)")
let result = determineWinner(userChoice: userChoice, computerChoice: computerChoice)
print(result)
updateScores(result: result)
displayScores()
if !playAgain() {
break
}
}
}
private func getUserChoice() -> String {
var choice: String?
repeat {
print("Wybierz: kamień, papier, nożyczki")
choice = readLine()?.lowercased()
} while choice == nil || !choices.contains(choice!)
return choice!
}
private func getComputerChoice() -> String {
return choices.randomElement()!
}
private func determineWinner(userChoice: String, computerChoice: String) -> String {
if userChoice == computerChoice {
return "Remis!"
} else if (userChoice == "kamień" && computerChoice == "nożyczki") ||
(userChoice == "papier" && computerChoice == "kamień") ||
(userChoice == "nożyczki" && computerChoice == "papier") {
return "Wygrałeś!"
} else {
return "Przegrałeś!"
}
}
private func updateScores(result: String) {
switch result {
case "Wygrałeś!":
userScore += 1
case "Przegrałeś!":
computerScore += 1
default:
break
}
}
private func displayScores() {
print("Wynik: Ty - \(userScore), Komputer - \(computerScore)")
}
private func playAgain() -> Bool {
print("Czy chcesz zagrać ponownie? (tak/nie)")
let answer = readLine()?.lowercased()
return answer == "tak"
}
}
let game = Game()
game.play()
Teraz porównanie wersji funkcyjnej Rust
use std::io;
fn main() {
let mut user_score = 0;
let mut computer_score = 0;
loop {
let user_choice = get_user_choice();
let computer_choice = get_computer_choice();
println!("Twój wybór: {}", user_choice);
println!("Wybór komputera: {}", computer_choice);
match determine_winner(&user_choice, &computer_choice) {
Outcome::UserWins => {
println!("Wygrałeś!");
user_score += 1;
}
Outcome::ComputerWins => {
println!("Przegrałeś!");
computer_score += 1;
}
Outcome::Draw => {
println!("Remis!");
}
}
display_scores(user_score, computer_score);
if !play_again() {
break;
}
}
}
fn get_user_choice() -> String {
loop {
println!("Wybierz: kamień, papier, nożyczki");
let mut choice = String::new();
io::stdin().read_line(&mut choice).expect("Nie udało się odczytać wyboru");
let choice = choice.trim().to_lowercase();
if ["kamień", "papier", "nożyczki"].contains(&choice.as_str()) {
return choice;
} else {
println!("Nieprawidłowy wybór. Spróbuj ponownie.");
}
}
}
fn get_computer_choice() -> &'static str {
let choices = ["kamień", "papier", "nożyczki"];
let random_index = rand::random::<usize>() % choices.len();
choices[random_index]
}
fn determine_winner(user_choice: &str, computer_choice: &str) -> Outcome {
if user_choice == computer_choice {
Outcome::Draw
} else if (user_choice == "kamień" && computer_choice == "nożyczki") ||
(user_choice == "papier" && computer_choice == "kamień") ||
(user_choice == "nożyczki" && computer_choice == "papier") {
Outcome::UserWins
} else {
Outcome::ComputerWins
}
}
fn display_scores(user_score: u32, computer_score: u32) {
println!("Wynik: Ty - {}, Komputer - {}", user_score, computer_score);
}
fn play_again() -> bool {
println!("Czy chcesz zagrać ponownie? (tak/nie)");
let mut answer = String::new();
io::stdin().read_line(&mut answer).expect("Nie udało się odczytać odpowiedzi");
answer.trim().to_lowercase() == "tak"
}
enum Outcome {
UserWins,
ComputerWins,
Draw,
}
- Rejestracja: dni
- Ostatnio: dni
- Postów: 5
Czy taki program w językach funkcyjnych jak Haskell, Scala, Elixir jest lepszy, składnia jest bardziej czytelna lepiej to wygląda?
import System.Random (randomRIO)
import Control.Monad (when)
data Choice = Rock | Paper | Scissors deriving (Show, Eq)
main :: IO ()
main = do
putStrLn "Witaj w grze w Papier, Kamień, Nożyczki!"
playGame 0 0
playGame :: Int -> Int -> IO ()
playGame userScore computerScore = do
userChoice <- getUserChoice
computerChoice <- getComputerChoice
putStrLn $ "Twój wybór: " ++ show userChoice
putStrLn $ "Wybór komputera: " ++ show computerChoice
let result = determineWinner userChoice computerChoice
putStrLn result
let (newUserScore, newComputerScore) = updateScores result userScore computerScore
putStrLn $ "Wynik: Ty - " ++ show newUserScore ++ ", Komputer - " ++ show newComputerScore
playAgain newUserScore newComputerScore
getUserChoice :: IO Choice
getUserChoice = do
putStrLn "Wybierz: kamień, papier, nożyczki"
choice <- getLine
case choice of
"kamień" -> return Rock
"papier" -> return Paper
"nożyczki" -> return Scissors
_ -> do
putStrLn "Nieprawidłowy wybór. Spróbuj ponownie."
getUserChoice
getComputerChoice :: IO Choice
getComputerChoice = do
randomIndex <- randomRIO (0, 2) :: IO Int
return $ case randomIndex of
0 -> Rock
1 -> Paper
2 -> Scissors
determineWinner :: Choice -> Choice -> String
determineWinner user computer
| user == computer = "Remis!"
| (user == Rock && computer == Scissors) ||
(user == Paper && computer == Rock) ||
(user == Scissors && computer == Paper) = "Wygrałeś!"
| otherwise = "Przegrałeś!"
updateScores :: String -> Int -> Int -> (Int, Int)
updateScores result userScore computerScore =
case result of
"Wygrałeś!" -> (userScore + 1, computerScore)
"Przegrałeś!" -> (userScore, computerScore + 1)
_ -> (userScore, computerScore)
playAgain :: Int -> Int -> IO ()
playAgain userScore computerScore = do
putStrLn "Czy chcesz zagrać ponownie? (tak/nie)"
answer <- getLine
when (answer == "tak") $ playGame userScore computerScore
Scala 3
import scala.io.StdIn
import scala.util.Random
enum Choice:
case Rock, Paper, Scissors
object PaperRockScissors:
def main(args: Array[String]): Unit =
println("Witaj w grze w Papier, Kamień, Nożyczki!")
playGame(0, 0)
def playGame(userScore: Int, computerScore: Int): Unit =
val userChoice = getUserChoice()
val computerChoice = getComputerChoice()
println(s"Twój wybór: $userChoice")
println(s"Wybór komputera: $computerChoice")
val result = determineWinner(userChoice, computerChoice)
println(result)
val (newUserScore, newComputerScore) = updateScores(result, userScore, computerScore)
println(s"Wynik: Ty - $newUserScore, Komputer - $newComputerScore")
if playAgain() then
playGame(newUserScore, newComputerScore)
def getUserChoice(): Choice =
println("Wybierz: kamień, papier, nożyczki")
StdIn.readLine().toLowerCase match
case "kamień" => Choice.Rock
case "papier" => Choice.Paper
case "nożyczki" => Choice.Scissors
case _ =>
println("Nieprawidłowy wybór. Spróbuj ponownie.")
getUserChoice()
def getComputerChoice(): Choice =
Random.nextInt(3) match
case 0 => Choice.Rock
case 1 => Choice.Paper
case 2 => Choice.Scissors
def determineWinner(user: Choice, computer: Choice): String =
if user == computer then "Remis!"
else (user, computer) match
case (Choice.Rock, Choice.Scissors) => "Wygrałeś!"
case (Choice.Paper, Choice.Rock) => "Wygrałeś!"
case (Choice.Scissors, Choice.Paper) => "Wygrałeś!"
case _ => "Przegrałeś!"
def updateScores(result: String, userScore: Int, computerScore: Int): (Int, Int) =
result match
case "Wygrałeś!" => (userScore + 1, computerScore)
case "Przegrałeś!" => (userScore, computerScore + 1)
case _ => (userScore, computerScore)
def playAgain(): Boolean =
println("Czy chcesz zagrać ponownie? (tak/nie)")
StdIn.readLine().toLowerCase == "tak"
Elixir funkcyjnie
defmodule PaperRockScissors do
@choices ["kamień", "papier", "nożyczki"]
def start do
IO.puts("Witaj w grze w Papier, Kamień, Nożyczki!")
play_game(0, 0)
end
defp play_game(user_score, computer_score) do
user_choice = get_user_choice()
computer_choice = get_computer_choice()
IO.puts("Twój wybór: #{user_choice}")
IO.puts("Wybór komputera: #{computer_choice}")
result = determine_winner(user_choice, computer_choice)
IO.puts(result)
{new_user_score, new_computer_score} = update_scores(result, user_score, computer_score)
IO.puts("Wynik: Ty - #{new_user_score}, Komputer - #{new_computer_score}")
if play_again() do
play_game(new_user_score, new_computer_score)
end
end
defp get_user_choice do
IO.puts("Wybierz: kamień, papier, nożyczki")
choice = String.trim(IO.gets("> ")) |> String.downcase()
if choice in @choices do
choice
else
IO.puts("Nieprawidłowy wybór. Spróbuj ponownie.")
get_user_choice()
end
end
defp get_computer_choice do
Enum.random(@choices)
end
defp determine_winner(user, computer) do
cond do
user == computer -> "Remis!"
(user == "kamień" && computer == "nożyczki") or
(user == "papier" && computer == "kamień") or
(user == "nożyczki" && computer == "papier") -> "Wygrałeś!"
true -> "Przegrałeś!"
end
end
defp update_scores(result, user_score, computer_score) do
case result do
"Wygrałeś!" -> {user_score + 1, computer_score}
"Przegrałeś!" -> {user_score, computer_score + 1}
_ -> {user_score, computer_score}
end
end
defp play_again do
IO.puts("Czy chcesz zagrać ponownie? (tak/nie)")
answer = String.trim(IO.gets("> ")) |> String.downcase()
answer == "tak"
end
end
PaperRockScissors.start()
- Rejestracja: dni
- Ostatnio: dni
- Postów: 7
Ciekawe dlaczego zawsze do nauki obiektowości polecają Javę. Jest tyle lepszych języków obiektowych jak Dart, C#, Ruby, TS, obiektowość w tych językach nie jest tak zagmatwana jak w Javie. Obiektowość w Javie jest tak zawiła i rozwlekła że często idzie się w tym zagubić. Może trzeba szukać nowych lepszych alternatyw do OOP jak język Lucee na JVM?
https://www.lucee.org/
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1365
Lucee napisał(a):
Ciekawe dlaczego zawsze do nauki obiektowości polecają Javę. Jest tyle lepszych języków obiektowych jak Dart, C#, Ruby, TS, obiektowość w tych językach nie jest tak zagmatwana jak w Javie
W Javie masz pierdyliard projektów do utrzymania. W Darcie 2, w Rubym 3, a C# uczy się podobnie jak Javy