web-dev-qa-db-ja.com

共有コーディングパラダイムを使用するという観点から、プログラムを言語Yで書くように、言語Xで何かを書くのはなぜ悪いのですか?

少し前に、C++で書かれた何かについてSOについて質問しましたが、問題の答えを得るのではなく、コメントが私のコーディングスタイルに夢中になりました。 [〜#〜] wip [〜#〜] コードの一部であり、後でベースケースを実行しているときにそれをクリーンアップするつもりであることを示しました(私は非常に多くの反対票を得ました) SOはすでにほぼ異常)の私の担当者であるため、私は質問を引き出すことにしました

どうしてそんなにハードなセリフ「お前は初心者だ、自分でやろう」を採用するのかと思った。 JavaのようにC++を書いたと非難されていました。理解できないことや、それでも私を困惑させること。

私は数年の間、かなりの数のOOP言語でプログラミングしていますが、間隔はありますが。使用可能なライブラリと、ジョブに最適な実行環境の観点から、使用する言語を選択します手元にあります。OOPコードでデザインパターンを採用しており、パターンの使用が適切であり、OO賢明に、私はOOPツールボックスを理解していますが、本当に必要な場合にのみツールを使用することを選択します。コードのウィットを表示するための巧妙なトリックを使用するだけではありません。一流ですが、私もn00bレベルではないと思います)。

1行書く前にコードを設計します。テストを定義するために、特定のクラスの目標と、それが遵守しなければならないテスト基準をリストします。シーケンス図を作成してからコードを書く方が簡単なので、インターフェイスが明らかになった後でテストを書くことにしました。

私が質問に投稿したコードの一部では、スマートポインターを使用する代わりに、ポインターをまだ使用していたことを認めなければなりません。 RAIIはできる限り使用します。適切なRAIIはnullポインターから保護することを意味することは知っていますが、徐々に作業します。これは進行中の作業であり、後でクリーンアップするつもりでした。この働き方は強く非難されました。

私の見解では、ベースケースが実行可能な方法であるかどうかを確認できるように、最初に実用的な例が必要です。また、ベースケースが証明された後、コードのクリーンアップはアジャイルのリファクタリングフェーズの典型的なものであると思います。 Cxx標準に徐々に移行しつつありますが、まだ量産コードで習得していない概念を使用するリスクを負うのではなく、私が理解しているものを使用することを好みます。私はたまに新しいものを試しますが、通常はその目的のために、私が味方しているプレイプロジェクトで使用します。

[編集]質問を始める前に行った検索に、gnatの提案[1]が表示されなかったことを明確にしたいと思います。しかし、彼の提案は質問の1つの側面をカバーしていますが、彼がリンクした質問は私の質問の核心に答えるものではなく、その一部にすぎません。私の質問は、自分のコーディングスタイルに対する応答と、さまざまなコーディングスタイルと(見かけの)スキルレベルを処理するための専門的な側面についてです。 SOに関する私の前の質問と、それは適切なケースとしての応答です。[/ edit]

質問は次のとおりです。なぜあなたのコーディングスタイルを使用しない誰かを侮辱するのですか?

私にとって手元にある問題/サブディビジョンは次のとおりです。

  • プロトタイプの状況でエラーが発生しやすいコードを使用すると、後でリファクタリングにより堅牢になる場合、なぜプログラミングがおかしいのでしょうか?
  • C++で作成されたプログラムは、Javaで作成されたプログラムとどのように一致しますか?それが悪いプログラムになる理由は何ですか(現在のスタイルの意図と改善する予定の作業を示したことを考慮して?)
  • 特定のプログラミングパラダイム(OOP/DPなど)で使用されている構造を使用することを選択した場合、どのように私は悪い専門家になりますか?

[1] 高速でバグのある開発を行ってから、エラーを修正するか、コードの各行に注意して遅いですか?

26
Onno

問題のコードを見ずに、C++でJavaコードを書く方法はいくつかありますが、他の方法よりも悪い方法もあります。

  1. 極端な例として、Javaのようなソースのレイアウトがあります。1つのファイル内のすべて、クラス定義内のすべてなどです。
    class HelloWorldApp {
    public:
        void main() {
            cout << "Hello World!" << endl;
        }
    };
    
    これはJavaソースがレイアウトされる方法です。C++では技術的には合法ですが、すべてをヘッダーファイルとインラインに(クラス宣言で定義することにより)入れます) ひどい スタイルとあなたのコンパイルパフォーマンスを殺します。しないでください。
  2. 過度にOO-単純化するために、Javaでは、すべてがオブジェクトである 名詞の王国 です。良い(つまり、慣用的な)C++コードは、すべてをオブジェクトに詰め込むのではなく、無料の関数やテンプレートなどを使用してください。
  3. RAIIなし-既にこれについて言及しました-スマートポインターの代わりにポインターと手動クリーンアップを使用します。 C++はRAIIやスマートポインターなどのツールを提供するため、優れた(つまり、慣用的な)C++コードはこれらのツールを使用します。
  4. 高度なC++なし-JavaとC++の基本は十分似ていますが、より高度な機能(テンプレート、C++のアルゴリズムライブラリなど)に入ると、分岐し始めます。

#1を除いて、これらはいずれもC++プログラムを悪いプログラムにしていますが、C++プログラマーとして作業したい種類のコードでもありません。 (私はまた、非慣用的またはCスタイルのPerl、非慣用的なPythonなどで作業することを楽しんでいません。)言語には独自のツールとイディオムと哲学があり、優れたコードは使用する代わりにそれらのツールとイディオムを使用します最低の共通点、または別の言語のアプローチを再現しようとしています。特定の言語/問題ドメイン/非慣用的なコードを書くことは、誰かを悪いプログラマーにさせないものであれば何でも、その言語/問題ドメイン/何についても学ぶことがもっとあるということです。そして、それは何も悪いことではありません。私がもっと学ぶべきことの非常に長いリストがあり、特にC++には学ぶべきことがたくさんあります。

後でクリーンアップすることを意図してエラーが発生しやすいコードを記述するという特定の質問に関しては、それは白黒ではありません。

  • いくつかのプロトタイプコードがすべての可能な例外とすべての可能なコーナーケースの処理に失敗した場合、それは予期されることです。それを機能させてから、堅牢に機能させます。問題ない。
  • いくつかのプロトタイプコードが単にbad styleまたはbad design(与えられた言語とそのイディオムに悪い、問題の根本的に悪いデザインなど)、それを使い捨ての概念実証として書いていない限り、何も得られません。

例として生のポインタとスマートポインタを使用するには、C++で作業する場合は、RAIIとスマートポインタを使用することが基本であり、高速である必要があります戻って後でそれをクリーンアップするよりも、そのようにコードを書くこと。繰り返しますが、これを怠ったからといって、プログラマが悪い、専門家ではない、などというわけではありませんが、さらに学ぶべきことがあるということです。

27
Josh Kelley

各プログラミング言語には、一連のイディオムとベストプラクティスがあり、通常、エレガントで正確で高性能なコードにつながります。他のいくつかの言語で完全に問題のないいくつかのワーストプラクティスを次に示します。

  • Perlでfor ($i = 0; $i < 42; $i++) { … }と書いても、PHPで書いていないと、私は怒鳴ります
    (Perlでは、変数を宣言する必要があり、そのようなループは範囲を反復する必要があります)
  • new Foo()をC++で書いた場合、正当な理由なしに泣きますが、Javaでは書いていません
    (C++にはガベージコレクションがないため、RAIIを使用する必要があります。それ以外の場合、Noobはメモリリークを起こします)
  • C89、Pascal、JavaScriptを除き、すべての変数を関数の先頭で宣言すると、私はうんざりします。
  • すべての関数をPythonではなくJavaのクラスに入れると、私は直面します。
    (Pythonは「OOP」を強制する代わりにマルチパラダイム言語であり、トップレベルの機能をサポートしています)
  • あなたが泣いたらreturn null Scalaでは、Cのような言語ではない
    (ScalaにはOptionタイプがあるため)
  • Javaで再帰的アルゴリズムを書いてOCamlで書いていないと文句を言います
    (OCamlには末尾呼び出しの最適化があるのに対し、Javaのスタックはすぐにオーバーフローするため)

新しい言語は、あなたが知っているものであるかのように簡単に使用でき、運が良ければそれでも機能します。 「Fortranはどの言語でも作成できます」。しかし、XがUよりも優れている可能性が高いため、X言語が提供する特定の機能を無視したくはありません。

利用可能なライブラリと現在のジョブに最適な実行環境の観点から使用する言語を選択します」–しかし、この言語Xが実際に優れているかどうか目前の仕事での言語Uよりも、その言語にどの程度精通しているか、またはその言語を上手に使用するために十分に精通するまでにかかる時間にも依存します。古いペンナイフが手にぴったり収まるので、実際に古いペンナイフが必要なときに、それが木を最も速く切るというだけで重いチェーンソーを生み出すことはありません。あなたが実際に木を倒したくない限り。

しかし、あなたの質問は文化的な問題に関するものです。すべてのベストプラクティスの学習には時間がかかり、初心者はほとんどの質問をしますが、教祖は答えます。しかし、第一人者にとって明らかなことは、初心者にとっては明らかではなく、教祖たちは時々それを忘れます。初心者の場合、解決策は質問をやめることではありません。ただし、ベストプラクティスを学び、適用するためのオープン性を示すことができます。 試してコードを可能な限りクリーンアップするbeforeそれを表示する他人に。ほとんどの言語には、学習曲線全体が実際に非常に長い場合でも、簡単に習得できるいくつかのコアベストプラクティスがあります。

一般的な問題は、プログラミングに慣れていない人がインデントやその他の書式を無視し、プログラムが機能しないために混乱することです。私も混乱します。プログラムを理解するための最初のステップは、プログラムが完全にレイアウトされていることを確認することです。次に、閉じられた引用符やコンマの欠落などの単純なエラーが突然明らかになります。私はあなたがすでに良いフォーマットを実践していると信じています、そしてこれは他のベストプラクティスの比喩です:ベストプラクティスはエラーを防ぎ、ベストプラクティスはエラーを見つけやすくし、ベストプラクティスを適用することはbefore問題の発見

「後で修正します」と言うのは安すぎます。今すぐ修正すれば問題は解決します(また、伝説の「クリーンアップフェーズ」が発生しない可能性があるため、責任のある唯一のオプションは正しく実行することです。初めて)。少なくとも、他の人に助けを求める前に、コードをできるだけ良いものにしようとすることは、彼らがあなたのコードについて推論することをより簡単にするので、礼儀正しいことです。

43
amon

私は筋金入りのC++開発者ではありませんが...

プロトタイプの状況でエラーが発生しやすいコードを使用すると、後でリファクタリングにより堅牢になる場合、なぜプログラミングがおかしいのでしょうか?

C++のエラーは通常、「未定義の動作」を意味することに注意してください。安全な言語では、起こりうる最悪の事態は、プログラムを即座に終了させる例外です。 C++では、segfaultが発生しても幸運です。プログラムが微妙な問題を起こし続ける可能性は十分にあります。また、しばらくの間正しく動作してバグを明らかにすることもできますし、常に正しく動作し、最終的にすべてのメモリを使い果たすこともあります。

いずれにせよ、プログラムの実行を完全にRailsから未知の領域に移すのは、たった1つの間違いです。常勤のC++開発者にとって、「基本ケース」とは「未定義の動作やメモリリークの可能性はありません。」

C++で作成されたプログラムは、Javaで作成されたプログラムとどのように一致しますか?何がそれを悪いプログラムにしていますか?

私はこれに対する答えがほとんど推測的でなく、説得力がないとは思わない。私がそれを引き受けたいなら、Javaは、すべてがオブジェクトでなければならないという事実のように、いくつかのアンチパターンが関連付けられる傾向があります。他の言語では、ポインタ、ファンクタを渡す場所、または関数、Javaでは、通常、大量の空虚で有用なThingDoersFooFactories、およびIFrobnicatorsが単なる関数です。変装した。

同様に、他の言語で単純なタプルまたは名前のない構造体を渡す場合、Javaで2つのオブジェクトを単純なデータコンテナーにバンドルする場合でも、30行以上のNamedThingクラスを次のように事前定義する必要があります。セッター、ゲッター、およびJavadoc。Javaには比較的機能が不足しているため、プログラマーはオブジェクト指向のダブルバックフリップを実行しなければならないことが時々あります。結果として得られるコードは、Javaの外部ではほとんど使用されません。

次に、C++では、メモリを手動で管理するために非常に簡略化されたオブジェクトグラフが必要であるという事実があります。通常、オブジェクトは他の1つのオブジェクトが所有しています。 Javaでは、ガベージコレクターは、それらへの参照がなくなったときにクリーンアップされることを保証するため、このような厳しい制約に従う必要はありません。したがって、次のような場合は、正しくないメモリ管理のリスクがあります。コードをJavaからC++に変換するだけです。

最後に、それはエリート主義である可能性があります。私はそれらが大多数を占めるふりをするつもりはありませんが、一部のC++開発者の間で、「手を握って、私が愚かなことをするのを防ぐ言語が必要ない」という感情を確実に見ました。彼らの考えでは、C++は「本物の」言語であり、その特異性を処理できない場合、「本物のプログラマ」ではありません。

12
Doval

トピックの回答が少しずれています...

心配しないでください-これはどのエキスパートコミュニティでも一般的な「動作」です。そして、正直に言うと、もしあなたがどんな言語でも上手で、「奇妙な」コードに出会うなら、おそらくそれも批判するでしょう。 (なぜなら、ティーチが欲しいからです)。

私はPerlの世界にいます-次のようなものがいつ表示されますか?

$imax=$#array;
$str=""
for($i=0; $i<$imax; $i++) {
    $str = "$str" . $array[$i];
}

の代わりに:

my $str = join '', @array;

確かにコメントします 読んで:作者に教えてください)join関数について。

とにかく、多すぎる批判はまったく逆効果であり、最良の例の1つは次のものです:(-から入手した---(http:// Perl-begin.org/humour/#How_can_I_switch_off_the_T.V..3F

(このビットは、2011年3月23日にペーストボットに匿名で投稿されました。編集後、後世のためにここに配置されます。)-少し編集もされました

質問:テレビをオンにするにはどうすればよいですか?

OPは何を聞きたいですか?

例:テレビのリモコンのオン/オフボタンを見つけて押します。ボタンは通常赤で、リモコンの一番上の行にあります。

#Perlエキスパートの答え:まず、「スイッチを入れる」とはどういう意味ですか?最初に定義します。テレビ、テレビのリモコン、リビングルームも貼り付けません。

... nopasteの後:

あなたの部屋は醜いです。そして、テレビはひどく見えます。画面でMr. Cleanを使用し、最初にリビングルームを掃除します。 2つではなく3つのクリーニングモップを使用します。本当に必要でない限り、HDMIを使用し、scart(?)コネクタを使用しないでください。テレビのリモコンに判読できないボタンがあります。最初にクリーンアップしてください。あなたは初心者なので、読んでください:

http://experts.blog/how_to_design_a_future_3D_TV.htmlhttp://experts.blog/the_basics_of_tv_repairing.htmlhttp://experts.blog/viruses_in_living_room_short_essay。 htmlhttp://experts.blog/global_chip_replacement_guide.html

IRCゲスト:しかし、私はテレビの専門家になりたくありません。

回答:なぜテレビのスイッチを入れたいのですか?!

6
jm666

プロトタイプの状況でエラーが発生しやすいコードを使用すると、後でリファクタリングによってより堅牢になる場合、なぜプログラミングがおかしいのでしょうか?

後で修正することを念頭に置いてすばやく汚いものを書くとき、修正する必要がある何かを忘れる危険があります。

C++で作成されたプログラムは、Javaで作成されたプログラムと同じようにできますか?何がそれを悪いプログラムにしているのですか(私が現在のスタイルの意図と改善する予定の作業を示したと考えて?)

Javaでは、特定のオブジェクトの所有者を考える必要はありません。参照を渡して、それが何もないように忘れてしまいます。しかし、C++では明確な定義が必要ですオブジェクトの所有者とクリーンアップの責任者。

特定のプログラミングパラダイム(OOP/DPなど)で使用されている構成体を使用することを選択した場合、どのように私は悪い専門家になるでしょうか?

あなたはしません。 C++はマルチパラダイム言語であり、たまたまOOPをサポートしていますが、他の多くのことも実行できます。しかし、そのほとんどは、仕事に適切なツールを使用することになります先のとがったスパイクを木に打ち込む必要があるたびにハンマーを引き出す代わりに。

あなたが悪い反応を得た理由は、SOのほとんどの人は、あなたが求めている言語でどれだけ慣用的にコーディングできるかによってスキルを判断する傾向があるためです。C++に精通している人はひどくジャークする傾向があります彼らが過去に彼らを噛んだ何かのように見える悪いコードを見たとき。

1
ratchet freak