探検


オブジェクト指向はオワコン? part2

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2026/08/13(木) 14:38:03.02ID:pdAcKRXu
前スレ
オブジェクト指向はオワコン?
https://mevius.5ch.io/test/read.cgi/tech/1721393540/
232デフォルトの名無しさん
垢版 |
2026/08/16(日) 17:26:17.84ID:4EyRDcWH
>>230
RustやJavaにあるような抽象的な契約の考えをZigに持ち込むのがそもそもパターンとして間違ってる
2026/08/16(日) 17:36:12.25ID:D1LzEAcA
>>231
Zigで型をanytypeと書く暇があったら代わりにinterface名を書けばいいよね
そこでのコードの長さは変わらなくてZigは可読性の低下だけ招いてるような
Zigが節約できたのはinterface宣言つまりmethod名と型signatureを列挙することだけかな
可読性の低下と引き換えにZigが得たものが小さすぎて割に合わない気がする
234デフォルトの名無しさん
垢版 |
2026/08/16(日) 18:50:20.61ID:4EyRDcWH
>>233
間違ってないよ 可読性や保守性の問題は抱えている
それと型安全性とは別の話だよねってこと
2026/08/16(日) 19:37:14.99ID:uznes1x1
Zig方式だと異なるインターフェース相当の同一型メソッドを区別できずに混ざってしまうため型安全性も落ちる
236デフォルトの名無しさん
垢版 |
2026/08/16(日) 21:15:59.83ID:8yz0P3zw
・構造的型付けは性質の一致をみる
・名前的型付けは概念(性質の集合)の一致をみる
ものだとすると、構造的型付けの方がロジックバグを作りやすいのはそのとおりだと思う

型安全という概念はプログラムの実行時に未定義の操作(存在しないメソッドの呼び出しなど)を起こさないというものなのでどちらも型安全ではあるってことなんじゃないかな
237デフォルトの名無しさん
垢版 |
2026/08/16(日) 21:32:38.32ID:8yz0P3zw
型安全じゃないなら何と表現するのが良いのかな、意図安全?
2026/08/16(日) 21:38:31.47ID:3V/Fi6zs
Zigはそのanytypeの時に複数の異なる型がやって来るわけだけど
生成コードは単相化?それとも動的ディスパッチ?
2026/08/16(日) 22:34:55.59ID:Co7DsicL
Zigとかどうでもよくね
思想が他と違うだろあれ
2026/08/16(日) 22:37:18.88ID:SoMBue1h
>>202
>>177を見れば一目瞭然だけどRustでも問題起きてるよ
Fragile Base Class Problemと同じFragile Trait Problem
Rustと違ってGoでは起きないけどね
2026/08/16(日) 23:34:48.38ID:4RZhk79G
それ起きるのなぜかfinalがないRustだけだろ
2026/08/17(月) 00:16:26.92ID:38V+3mdM
そもそもRustでは起きない
2026/08/17(月) 00:19:02.71ID:O4jJSPJp
>>242
どうしてそう考えるの?
2026/08/17(月) 09:45:51.74ID:UewEXcwQ
>>242
主語や目的語を誤魔化しているところを見ると
「(複おじの考える問題は)Rustでは起きない」ということなんだろう

Rustで起きないならJavaならなおさら起きないけどね
2026/08/17(月) 12:16:16.38ID:CJr3tgZ2
論破されても同じ主張を根拠無く延々と繰り返す
それが複おじ!!
246デフォルトの名無しさん
垢版 |
2026/08/17(月) 13:29:22.69ID:wAb5rDbA
で、お前ら実際にクラス継承なんか使ってんのか?
2026/08/17(月) 13:37:49.96ID:GxsMwSQY
なるべく使わないがそれが何か
248デフォルトの名無しさん
垢版 |
2026/08/17(月) 14:03:56.79ID:rUdNNfGv
必要がない機能がないなら用足りないっつってもいいが
使いもしない機能が余計についてるだけのことでとやかく語って何が楽しいの?
249デフォルトの名無しさん
垢版 |
2026/08/17(月) 14:12:17.93ID:9dsT8/CZ
>>248
お前のその斜に構えた態度がクソダセーって話でお前がいないところでみんな盛り上がってるから心配すんな楽しいぞ
250デフォルトの名無しさん
垢版 |
2026/08/17(月) 14:13:30.75ID:rUdNNfGv
時間の無駄
251デフォルトの名無しさん
垢版 |
2026/08/17(月) 14:20:40.34ID:9dsT8/CZ
5ch見て時間の無駄は草
2026/08/17(月) 14:58:45.13ID:GxsMwSQY
>>249
それどこよ?
253デフォルトの名無しさん
垢版 |
2026/08/17(月) 15:01:13.59ID:9dsT8/CZ
>>252
うそやで
2026/08/17(月) 15:03:07.13ID:GxsMwSQY
>>247
害が少なくて役に立つところには、たまにor稀に使う
そうじゃないと多用したらプログラムがわかりにくくなってしょうがない
拡張などメンテでは解読とあっちこっち目を通して整合させたり手が掛かるし
2026/08/17(月) 15:03:50.96ID:GxsMwSQY
>>253
だよな
つかはったりもええ加減にせーや
2026/08/17(月) 15:05:08.29ID:GxsMwSQY
>>254
バグ紛れ込むし見つけにくいし
257デフォルトの名無しさん
垢版 |
2026/08/17(月) 15:52:04.48ID:DZRCEu47
今まで単に使う場面が無かったから使ったことがないな
2026/08/17(月) 17:38:40.01ID:hu6Kc+Um
みんな仕事したことないのか
259デフォルトの名無しさん
垢版 |
2026/08/17(月) 18:00:39.50ID:9dsT8/CZ
いやまあライブラリ作るのでない限り継承が必要になることはないでしょ
お仕事では既存のライブラリを使ってアプリ作るほうが圧倒的に多いだろうしそんなもんじゃないかな
2026/08/17(月) 18:37:49.03ID:GiCS5tuu
そんな小規模な開発じゃ使わないからw
2026/08/17(月) 19:17:05.30ID:P355WQDR
大規模な開発で濫用すると滅びるぞ
2026/08/17(月) 19:25:42.72ID:pTNaMQne
大規模ならインターフェース実装と委譲
263デフォルトの名無しさん
垢版 |
2026/08/17(月) 19:26:11.71ID:fHDv2p6M
traitの中に実装を書くのがそもそもアホ
264デフォルトの名無しさん
垢版 |
2026/08/17(月) 20:25:04.55ID:9dsT8/CZ
Unit Test書いてCIする時代なんだし好きに書いたら良い
まさかUnit Test書いてCIしてないやつはいないよな?
俺はどっちもやってないけどな
2026/08/17(月) 22:32:08.18ID:kjYhoonu
>>217 >>218 2012年ころ試しに書いたFiizBuzzのPerlコード見つかった

for (1..20) {
 $a = '';
 $a = 'fizz' if 0 == $_ % 3;
 $a .= 'buzz' if 0 == $_ % 5;
 $a ||= $_;
 print "$a\n";
}


$ perl FizzBuzz.pl
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
16
17
fizz
19
buzz
266デフォルトの名無しさん
垢版 |
2026/08/18(火) 06:20:16.09ID:9HbNxAXp
>>265
きたねー言語だなぁ
2026/08/18(火) 07:06:16.69ID:mY9waEio
>>266
綺麗に書いてみて
2026/08/18(火) 07:09:42.79ID:mY9waEio
抽象型やinterfaceやtraitやZigを活用したらどのくらいきれいになるんだろう
2026/08/18(火) 07:52:58.90ID:qWsaXKMs
そりゃ文字列"fizzbuzz"は直書きせずともcomptimeで生成だろ
270デフォルトの名無しさん
垢版 |
2026/08/18(火) 09:09:48.18ID:CwdGUKcu
>>267
見せてやるよ
オブジェクト指向の真髄ってやつをな
https://paiza.io/projects/jndrJpCJ34RQgtrNFNvG9g?locale=ja-jp
271デフォルトの名無しさん
垢版 |
2026/08/18(火) 09:21:01.28ID:s6UVuJiP
テンポラリ変数嫌いすぎて可読性落とす書き方するやつってけっこういるよな
2026/08/18(火) 09:49:26.70ID:dgmmJ4dW
10行で書けるけどそれだと金にならないから100行に水増ししてかっこいい雰囲気を醸し出せる
それがオブジェクト指向
273デフォルトの名無しさん
垢版 |
2026/08/18(火) 10:05:16.38ID:kPRCdywZ
オブジェクト指向前だって#defineがズラズラ並んでる見づらいコードだったけど
2026/08/18(火) 10:53:18.24ID:gcpAV276
>>270
目的の関数とメイン関数は分けなければいけない
今回は無限FizzBuzzイテレータを返すだけの関数を分離すると望ましい
データ生成とそのデータのビューアーも分離しなければいけない
文字列化するのはビューアーの役目であり途中のデータは可能な限り軽い小さなものにする
固有のロジック部分の分離も望ましい
今回はもちろんFizzBuzzへの変換部分を分ける
2026/08/18(火) 11:29:29.44ID:mY9waEio
>>270
ヒー、よくこんな糞コードを人前に晒せるな
笑いをとるネタでやってるなら役者だわ
2026/08/18(火) 11:39:15.61ID:mY9waEio
凝った技術を使って 後退している感じ
まあ遊びとしてはありかな
2026/08/18(火) 11:44:50.67ID:FI1FzRN/
>>271
長い数式や条件式がある場合は短く分けて意味が分かる一時変数名を付けることが必須だけど>>270に一時変数が必要な部分はないよ
役目毎に関数を分けて意味が分かる関数名を付ける必要はあるけどね
278デフォルトの名無しさん
垢版 |
2026/08/18(火) 11:58:25.60ID:s6UVuJiP
>>277
この内容で関数分けは逆にやりすぎだよ
2026/08/18(火) 12:03:00.45ID:mr91AiPO
>>278
Mainに本体を書くやつは恥
20個という前提にない指定が本体に紛れ込んでいるのも恥
280デフォルトの名無しさん
垢版 |
2026/08/18(火) 12:09:50.58ID:s6UVuJiP
>>279
レビューポイントがずれてるところ見ると例の人か
2026/08/18(火) 12:12:44.41ID:yVjtC2wq
ビュー部分とロジック部分は分けるべきだろうね
2026/08/18(火) 12:12:55.79ID:mY9waEio
レビュー言ってる人が書くともっとヒデ―んだろうな…
2026/08/18(火) 12:22:41.95ID:zZZZox/S
ノウハウが盗まれないように最初から難読化しているのに、
それをextendsがevilだといわれちゃうと心外ですよねぇ笑。
それは単なるtrapだ。trapに引っかかるようなバカは不要という世界。
2026/08/18(火) 12:25:26.30ID:Wbf7Xhfh
少なくとも個別テストができるレベルでの関数分けは常に義務付けられる。
データ生成部分とデータ表示部分を分離しなさいという常識も、混在は可読性を下げるだけでなくテストを困難にするためだ。
2026/08/18(火) 12:30:03.24ID:zZZZox/S
test firstはtestを先に書け、ということではなく、
testすること/できることを前提に設計しろ、ということ。
Unit testできないもの、integration testできないプログラムはゴミでしかない。
2026/08/18(火) 12:41:42.10ID:mY9waEio
結局、カルトな迷信から抜け出せないのね
2026/08/18(火) 12:54:55.98ID:BvR5dCBy
文字列への変換はできる限り遅延させて可能なら表示の直前まで遅延させることが望ましいという原則
これは抽象的なデータとして持っていた方が可読性と保守性に勝るだけでなく
高速化や省メモリ化の観点からでもあるね
文字列にして持っていると格納メモリが増えて比較も遅くなっちゃう
2026/08/18(火) 12:56:42.55ID:zZZZox/S
Fizz buzzについては、wikipediaのルールを基準として、それを仕様とみなせば、
仕様をみたしていないプログラムが多い(日本語版wikipediaを含む)。
これを試験に出すとすると、仕様というものを理解できていない会社が多い。
結果が同じであればよいのではなく、保守や運用を考えると仕様を満たしていることが必要。
2026/08/18(火) 14:51:02.89ID:mY9waEio
wikipediaのルールが実は違ったらどーすんの?
290デフォルトの名無しさん
垢版 |
2026/08/18(火) 16:49:24.64ID:CwdGUKcu
>>288
FizzBuzzじゃなくてFizz Buzzが正しいんだとかそういうこと?
291デフォルトの名無しさん
垢版 |
2026/08/18(火) 16:50:03.29ID:CwdGUKcu
>>275
…はー…我慢!我慢!
2026/08/18(火) 17:04:30.03ID:mY9waEio
もしかして頑張って書いてくれたんだ、ゴメンチャイ
2026/08/18(火) 18:16:51.47ID:zZZZox/S
wikipediaに仕様は書かれていないので、仕様は自分で書き起こすことになる。
そこでhttps://rosettacode.org/wiki/FizzBuzzあたりから仕様を持ってくる。
3の倍数のときはFizz、
5の倍数のときはBuzz、
3と5の倍数のときはFizzBuzz。
このルールの優先順位は不明だ。混乱する。
wikipediaではreplaceすることになっており、さらに混乱は増す。
3つ目のルールは1・2を前提にしておらず、仕様の変更によって別の文言になる可能性がある。
仕様の曖昧さとバージョンアップの可能性を、出題者に確認しないで作り進めた場合は、
0点だろう。
また、確認したら逆切れされた、とかいう場合は、その会社には行かない/やめることが重要だ笑。
2026/08/18(火) 18:45:23.15ID:UHB640UT
>>291
あのフリからのあのコードだから普通の人はネタだと分かるから心配しなさんな
2026/08/18(火) 19:03:06.87ID:mY9waEio
>>293
かたいのはチンチンだけにした方がいいよ
2026/08/18(火) 19:07:28.34ID:1F5abdGh
>>278
関数分けされてないことだけが今回のコードの問題点だよ
少なくともテストができるように分離かな
テストではなくprintするだけにしてもメイン側に書いていいことは1から20までやprintのみ
2026/08/18(火) 19:37:50.56ID:4nWkMale
ネタで5chに晒すトイプログラムは、あれこれ欲張って機能付帯するよりエッセンスだけ凝縮したような物でいいと思うがな
極論だが、one linerでも話のネタになればそれでもいいんジャマイカと思う
2026/08/18(火) 20:26:22.86ID:IKbB6EpN
>>270は普通に書かれているだけでネタには全くなってない
299デフォルトの名無しさん
垢版 |
2026/08/18(火) 22:36:43.09ID:xbj6Xdrn
>>295
そっちは硬くならない
300デフォルトの名無しさん
垢版 |
2026/08/19(水) 01:07:10.28ID:LbA7Fa3/
結果だけなら無限ジェネレータ、イテレータ使うのがシンプルで無駄ないけど
初学者が分岐と文字列出力駆使してコーディングできるかのお題だから
経験者はあたたかくみまもるのが正解
2026/08/19(水) 01:17:33.88ID:76BzD64w
>>268
Rustはこんな感じ

use std::fmt;

struct FizzBuzz(usize);

impl fmt::Display for FizzBuzz {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let fizz = self.0 % 3 == 0;
if fizz {
write!(f, "Fizz")?;
}
let buzz = self.0 % 5 == 0;
if buzz {
write!(f, "Buzz")?;
}
if !fizz && !buzz {
write!(f, "{}", self.0)?;
}
Ok(())
}
}
2026/08/19(水) 05:08:00.70ID:jKqAYIeP
use v5.26;
use feature 'signatures'; no warnings 'experimental::signatures';

# Y combinator
my $Y = sub ($f) {
 (sub ($x) { $x->($x) })->(sub ($x) {
   $f->(sub (@args) { $x->($x)->(@args) })
 })
};

# generator
my $fizzbuzz_gen = sub ($recurse) {
 sub ($n) {
  return if $n > 20;
  
  my $a = "";
  $a = "fizz" if 0 == $n % 3;
  $a .= "buzz" if 0 == $n % 5;
  $a ||= $n;
  print "$a\n";
  
  $recurse->($n + 1);
 }
};

$Y->($fizzbuzz_gen)->(1);
2026/08/19(水) 05:27:50.54ID:jKqAYIeP
use v5.26; use feature 'signatures'; no warnings 'experimental::signatures';

my $Y = sub($f){ (sub($x){ $x->($x) })->(sub($x){ $f->(sub(@a){ $x->($x)->(@a) }) }) };

$Y->(sub($r){ sub($n=20){
 $n && $r->($n - 1) . print((('fizz')[$n%3].('buzz')[$n%5] || $n)."\n")
}})->();
2026/08/19(水) 05:53:05.29ID:jKqAYIeP
>>299
添え木するか ト
2026/08/19(水) 06:06:15.93ID:jKqAYIeP
ttps://ja.wikipedia.org/wiki/%E4%B8%8D%E5%8B%95%E7%82%B9%E3%82%B3%E3%83%B3%E3%83%93%E3%83%8D%E3%83%BC%E3%82%BF
306デフォルトの名無しさん
垢版 |
2026/08/19(水) 06:57:23.62ID:PkKxELQ5
>>301-303
どれも汚くて読みにくい言語だなぁ

やっぱりBASIC言語がいいな
307デフォルトの名無しさん
垢版 |
2026/08/19(水) 09:25:42.01ID:zfDVRijx
>>306
はよ
2026/08/19(水) 09:26:57.21ID:AOQ3QAZ6
>>301
これは明らかにやっちゃいけない役割分担
>>287や>>300でRustの自演お膳立てしておいてこれはない
2026/08/19(水) 11:30:51.59ID:JEHGtM5b
オブジェクト指向をバカにしてるやつ(≒苦手にしてるやつ)ほど役割分担下手だよな
2026/08/19(水) 11:32:25.08ID:jKqAYIeP
>>309
>>268
2026/08/19(水) 12:47:31.88ID:6v15mJkM
>>309
めちゃくちゃわかる
脳の使い方に違いがありそう
2026/08/19(水) 13:00:20.84ID:IT0gHGzs
Javaは書いたことがないけど、>>270の内容は大体分かる(と思う)。分かるんだけど、たとえば>>265みたいなごくシンプルなコードと比べて、コード量が増えたことに見合うだけのメリットがあるのかよくわからない。
2026/08/19(水) 13:13:14.33ID:Wk2G6dYo
>>308
FizzBuzzは数値をあるルールで文字列に変換する問題だよね
そしてRustで文字列に変換する時はDisplayトレイトを実装するのがお約束
>>301のコード以外に適切な方法ある?
314デフォルトの名無しさん
垢版 |
2026/08/19(水) 13:25:34.76ID:DVblsqcj
>>312
前者は数列処理にFizzBuzzのルールを与えたプログラム
後者はFizzBuzzの問題を解く為に構成されたプログラムという理解
メリットは…なんだろう
315デフォルトの名無しさん
垢版 |
2026/08/19(水) 14:46:16.71ID:zfDVRijx
>>306
はよ
https://www.jdoodle.com/execute-freebasic-online
2026/08/19(水) 15:09:53.60ID:clBhGGD3
>>313
煽られただけだと思うよ
317デフォルトの名無しさん
垢版 |
2026/08/19(水) 16:47:55.93ID:GgmociGN
やるとしたらfmt::Displayの実装とFizzBuzz判定の実装を別々に分担するくらいか?
あと個人的にはifじゃなくてmatchでよくね?と
2026/08/19(水) 17:22:08.92ID:76BzD64w
>>301は最小限のコードを書いたので
もう少しFizzBuzzオブジェクトに肉付けすると

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
struct FizzBuzz(usize);

impl FizzBuzz {
fn is_fizz(&self) -> bool {
self.0 % 3 == 0
}
fn is_buzz(&self) -> bool {
self.0 % 5 == 0
}
fn iter() -> impl Iterator<Item = FizzBuzz> {
(1..).map(|x| FizzBuzz(x))
}
}

impl fmt::Display for FizzBuzz {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.is_fizz() {
write!(f, "Fizz")?;
}
if self.is_buzz() {
write!(f, "Buzz")?;
}
if !self.is_fizz() && !self.is_buzz() {
write!(f, "{}", self.0)?;
}
Ok(())
}
}
2026/08/19(水) 17:27:41.72ID:76BzD64w
他の例のように20まで表示したい時は

fn main() {
for z in FizzBuzz::iter().take(20) {
println!("{z}");
}
}

>>317
FizzBuzzのルール
3で割り切れる時はFizzと言い
5で割り切れる時はBuzzと言い
結果として15で割り切れる時はFizzBuzzと言うことになる
これをそのまま実装したのが>>318
2026/08/19(水) 17:35:12.55ID:1B1Sgr4M
// java21, import略, rosettacodeの仕様による。3と5の倍数の場合、3や5のwordと関係ないものとみなして独立。改行詰め,、改行が多いだと!
public class FizzBuzz {
private static final int IntMin = 1;
private static final int IntMaxClosed = 100;
private static final String Fizz = "Fizz";
private static final String Buzz = "Buzz";
private static final String FizzBuzz = "FizzBuzz";
private static final BigInteger bigInteger15 = BigInteger.valueOf(15);
private final int value;
private FizzBuzz(int value) { this.value = value; }
static Stream<FizzBuzz> generator() {
return IntStream.rangeClosed(IntMin, IntMaxClosed).mapToObj(FizzBuzz::new);
}
int gcd15() {
return BigInteger.valueOf(value).gcd(bigInteger15).intValue();
}
String toText() {
return switch (gcd15()) {
case 3 -> Fizz;
case 5 -> Buzz;
case 15 -> FizzBuzz;
default -> toString();
};
}
@Override
public String toString() { return Integer.toString(value); }
public static void main(String[] args) { generator().map(fb -> fb.toText()).forEach(System.out::println); }
}
2026/08/19(水) 18:32:05.09ID:h5yOG9hX
これは想定外の重症度
汚コード複製おじさん酷すぎだろ
2026/08/19(水) 19:33:00.25ID:1B1Sgr4M
immutableなclassとstreamでmonadicに、各methodは1行の式とした例。
改行制限と空白制限で、ちょっとおかしな表記になっている。
2026/08/19(水) 19:34:16.89ID:HQ3bB/34
>>320
100までとか
main関数とか
なぜclass FizzBuzzの中にあるんだよ草
2026/08/19(水) 19:40:28.85ID:1B1Sgr4M
くすくす。仕様を満たすためだよ。
2026/08/19(水) 19:48:00.60ID:yaDN1rR6
ここはオブジェクト指向でFizzBuzzを書くとどうなるかの話だよな
class FizzBuzzに属するものと外部のものを分けないとな
2026/08/19(水) 20:06:36.33ID:1B1Sgr4M
generator込みの完結したclassだがね。UnitTestにも対応してるし。
プログラム書いたことある?
2026/08/19(水) 20:31:50.49ID:xLZSPR7N
>>318は改行しまくりスカスカでも収まってるのに
>>320は改行を詰めてぎっしりコード量が多くて見にくいのはなぜ?
328デフォルトの名無しさん
垢版 |
2026/08/19(水) 20:47:05.92ID:gE5f7kH9
糞言語ってことよ
2026/08/19(水) 22:27:30.40ID:KYbvI00a
>>320はgcd最大公約数を求めてるけど
その方が速いとか有利とか何かあるの?
2026/08/19(水) 22:31:51.05ID:1B1Sgr4M
https://paiza.io/projects/zW-QQAk1SV2qaU7Iv3Kqtw
FizzBuzz classがMain classになっちゃったけど、しかたない。
最大公約数で扱ったほうが楽だし、意味的にはGCD使ったほうが正しい。
2026/08/19(水) 22:41:50.65ID:1B1Sgr4M
generator().map(fb -> fb.toText()).forEach(System.out::println);
generator()で発生させたFizzBuzz(Main)オブジェクトをtoText()してprintlnの関手を与える。
ただそれだけ。
toText()は15とのGCD取って、結果でFizz,Buzz,FizzBuzz,その他の文字列を返すだけ。
return switch (gcd15()) {
case 3 -> Fizz;
case 5 -> Buzz;
case 15 -> FizzBuzz;
default -> toString();
};
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況