はてなキーワード: インターフェイスとは
コロナがきっかけで家で仕事するようになって最初は何もないシンプルなデスクだったけど、趣味でPCを使うことも多いから、だんだんと使いやすく、見た目もいい環境にしていきたくなって、2年かけていろいろ揃えてきたんだよね。
YouTubeでオススメされてるものを見ては良さそうなもの買ってみたけど、最近はもう欲しいものがなくて少し物足りない気持ちになってる。
確かにもっと良いもの、最新のものを買うこともできるけど、置く場所もないし、買い換えても費用対効果を考えるとうーんってなることが多くなったんだよね。
スタンディングデスクにはじまり、バカ高いオフィスチェア、4K高リフレッシュレートのモニター、高いキーボードやマウス、サウンドバー、コンデンサーマイク、モニターライト、左手デバイスなどなど、いろいろ買い集めた。この辺までは使ってる。
LEDテープとかライティングもちょっと試したけど、ほとんどつけてない。ヘッドホンは無線だからオーディオインターフェイスはいらない。壁も空いてないからプロジェクターも要らないし、iPadも使いこなせてない。
5年前ならともかく、今は全然そんなことはないです
それはそうですが、Rustがオブジェクト指向の言語かどうかには関係ありませんね
「Rustがオブジェクト指向言語なのか?」という話題においては、traitがインターフェースの機能をより一般化して強力にした機能であるとか、
そのあたりの方が「誰がどのプロダクトを作ったか」より遥かに重要ですね
実際にどんなサービスを作ったとかの話になるの
「Rustがオブジェクト指向言語なのか?」という話題においては、なりませんね
君その辺空っぽだよね
コードを簡潔に保つにはモジュール化が必須である。しかし同じモジュールに関係のない機能が含まれていたりすると混乱の元になる。
一方で、関数というのは引数の細かな仕様に依存せずに、汎用的に呼び出せた方が何かと好都合だ。引数になんらかのオブジェクトを渡し、そのオブジェクトしか持ち得ないような特殊な情報で処理を行なったりすると、関数とオブジェクトが互いに依存しあってしまう。
これはモジュールの結合度と呼ぶ。
高い凝集度、低い結合度によってモジュールを作れば、保守性は上がる。
さらにモジュール内では、公開する必要のない関数はprotectedまたはprivateにするべきだ。
そのためにはモジュールが公開すべき関数についてインターフェイスを作り、公開関数に対するユニットテストを書いておくのが良いだろう。
module_name.pyみたいなモジュールごとにファイル分割して、インターフェイスだけ公開してその他はdef _funcみたいにprotected(or private)にしとく。
でも「共通性がありそうだから共通関数にする」はアンチパターンだな。たまたま共通してただけの場合は分岐コードが増えて共通関数の保守コストが上がる。
あとありがちなのは、php開発者が関数分割しないですべてメインコードにべた書きするケース。こういうのはやめないと保守が大変。
とっておきのクズがやりがちなのは、神オブジェクトを作るとかだな。Userクラスのフィールドに関係する機能が多いからといって、コンポジションなどによるクラス分割をせずにユーザークラスにあらゆるフィールドとメソッドを追加して、さらに進むとユーザーとは無関係な機能も含めすべてをユーザークラスに定義するアフォ。こうなってしまったら、後から修正するのが難しくなる。
先に手を打つことが、プログラマーの素質「怠惰」につながるのであり、面倒臭いといって後回しにするのは美徳でもなんでもない。
ChatGPT is fine-tuned from GPT-3.5, a language model trained to produce text.
OpenAI ChatGPT is a language model developed by OpenAI that is built on the GPT (Generative Pre-trained Transformer) architecture.
https://dzone.com/articles/comprehensive-guide-on-integrating-openai-chatgpt
お前のいう通り書いたったわ(C#だが)。
//宇宙 namespace Universe { //あらゆる神の根底に存在する唯一神とその司る運(スーパークラス) public class GodLuck { public string Name { get; } //神の名前 public string Power { get; } //神の力 public string Plan { get; } //神の計画 public string Factor { get; } //運の要因 public GodLuck(string name, string power, string plan, string factor) { Name = name; //神の名前 Power = power; //神の力 Plan = plan; //神の計画 Factor = factor; //運の要因 } //神が何かを創造するメソッド public void Create(string thing) { Console.WriteLine($"{Name} created {thing}."); } //神が何かに対して支配や介入をするメソッド public void Control(string thing, string action) { Console.WriteLine($"{Name} {action} {thing}."); } //運が何かに対して影響を与えるメソッド public void Affect(string thing, string outcome) { Console.WriteLine($"{Name} affected {thing} and the outcome was {outcome}."); } } //恵比須様 public class EbisuSama : GodLuck { public EbisuSama() : base("恵比須様", "商売繁盛や五穀豊穣の力", "人々に幸せを与える計画", "商売繁盛や五穀豊穣の要因") { } //作物を守る public void Save(string crops) { Control(crops, "守る"); } //人間を成功させる public void MakeSuccessful(string person) { Affect(person, "成功"); } } }
(大いなる力を別のクラスに移譲したくなったが、神と大いなる力は同一のオブジェクトという要件があるからやめた)
//宇宙 namespace Universe { //神の振る舞いを定義したインターフェイス public interface IGodLuck { public string Name { get; } public string Power { get; } public string Plan { get; } public string Factor { get; } //神が何かを創造するメソッド public void Create(string thing); //神が何かに対して支配や介入をするメソッド public void Control(string thing, string action); //運が何かに対して影響を与えるメソッド public void Affect(string thing, string outcome); } //恵比須様 public class EbisuSama : IGodLuck { public string Name { get; } //神の名前 public string Power { get; } //神の力 public string Plan { get; } //神の計画 public string Factor { get; } //運の要因 public EbisuSama() { Name = "恵比須様"; //神の名前 Power = "商売繁盛や五穀豊穣の力"; //神の力 Plan = "人々に幸せを与える計画"; //神の計画 Factor = "商売繁盛や五穀豊穣の要因"; //運の要因 } //神が何かを創造するメソッド public void Create(string thing) { Console.WriteLine($"{Name} created {thing}."); } //神が何かに対して支配や介入をするメソッド public void Control(string thing, string action) { Console.WriteLine($"{Name} {action} {thing}."); } //運が何かに対して影響を与えるメソッド public void Affect(string thing, string outcome) { Console.WriteLine($"{Name} affected {thing} and the outcome was {outcome}."); } //物を守る public void Save(string thing) { Control(thing, "守る"); } //人間を成功させる public void MakeSuccessful(string person) { Affect(person, "成功"); } } }
オブジェクト指向とかかっこいい言い方をしても無駄だ。従来の構造化プログラミングから進歩したことなど一つもない。オブジェクト指向がなぜダメであるのか、それを今から話すぜ。
1. データと処理をまとめるという発想。
データと処理をまとめてクラスとして置くという発想がある。しかし、このようなことをしなくとも、モジュールという単位で利用データと処理の集合をまとめればよかったので、クラスを使う必要はない。しかもクラスはインスタンス化のときに、不要な情報まで持ってくるのでメモリ効率が明らかに悪い。コンピュータが進化しているからメモリのことはあまり考える必要がないとはいえ、必要ない処理をまとめて閉じ込めるのは無駄が多い。なぜクラスという名詞で概念分類できると考え始めたのかは不明だが、アルゴリズムとデータ構造という構造化プログラミングの手法を、クラスと型というパラダイムに変換することで型にうるさいC++馬鹿を生み出し、彼らが発狂することになってしまった。しかもデータと処理にわざわざ依存関係を持たせて、変更に対する柔軟性を失わせている。
2. 継承
継承によって既存の構造を持ってこようとする必要性が全く無い。それどころか、継承を使うことによってプログラムがスパゲティ化し、依存関係のグラフがややこしくなってしまう。継承など使わず、必要な情報はスコープの限られた共通の変数、または関数の引数として用意しておけば良い。もしクラスをどうしても使いたければ、共通のインターフェイスをもたせたほうがマシである。インターフェイスを使えば、クラス利用者が意識すべきpublicメソッドがなんであるか把握できる。
3. カプセル化
オブジェクト指向の中で役立つ概念はカプセル化だけである。しかし、カプセル化はクラスなしで構造化プログラミングの方法で実装できる。pythonでは、モジュールの中でアンダースコアから始まる関数を用意しておけば、それがprotectedやprivateと似たように機能させることができる。オブジェクト指向がなぜカプセル化が独自の概念だと言い始めたかは謎。
4. ポリモーフィズム
同じ名前のメソッドを、入力に応じて処理の内容を変える。このようなことはオブジェクト指向などと誇大宣伝をするほどのことでもない。構造化プログラミングで似たようなことができる。
技術的な内容を増田に書くという実験のために、試しに検索エンジンの仕組みについて書く。
検索エンジンは、大雑把に言ってクロールするパート、インデクシングするパート、検索インターフェイスを出力するパートに分かれる。
インデクシング時に使っている基本手法は「転置インデックス」と呼ばれ、文書内のngramを文書IDと対応付ける辞書を保存する。
インデクシングの別の種類としては、文書をエンコーダからベクトルへ変換し、それを近似最近傍検索できるようにするものもある。
インデクシングされたものがキーワードマッチ的に絞り込まれると、さらに精密な手法が使われる。
クエリとドキュメントから特徴量設計し、関連性の高いものを引っ張るような訓練をする方法はLearning to rankという。
Learning to rankの中に使われる特徴量の一つにPage Rankがあるが、これは初期の検索エンジンで画期的とされた量で、「リンクされるページの価値は高い」「高価値ページにリンクされると価値が高い」という基準からマルコフ連鎖で計算する。
Page Rankは人間が論文を評価するときと似たような評価手順であるとされる。
Learning to rankの中にエンコーダからのベクトルを特徴量として組み込むことも可能であり、そのようなエンコーダの初期の例がBERTである。
こうやって絞り込まれた文書に対して、さらに有用な情報を表示するモデルがいくつか使われる。
情報抽出モデルでは、クエリを質問と見做してその回答を文書から抽出することがある。
あるいはクエリが人物名や組織名、場所名などであれば、そのエンティティの詳細情報をデータベースから取得することもでき、これはナレッジグラフとも呼ぶ。