低レベル言語の代わりにオブジェクト指向言語を使用して、マシンと直接やり取りすることができます。C ++確かに、ただしC#でもアダプターなどがあります。機械部品を制御し、メモリを細かく制御するコードを記述することは、可能な限り低レベルに近づけることが最善です。しかし、この質問が、基幹業務、Webアプリケーション、IOT、Webサービス、および大部分の大量使用アプリケーションのような現在のオブジェクト指向ソフトウェアに関連している場合、...
該当する場合は回答
読者は、サービス指向アーキテクチャ(SOA)を使用してみてください。つまり、DDD、N層、N層、六角形などです。過去10年間で70年代および80年代に説明されたように、大規模ビジネスアプリケーションが「伝統的な」OO(アクティブレコードまたはリッチモデル)を効率的に使用しているのを見たことはありません。(注1を参照)
障害はOPにありませんが、質問にはいくつかの問題があります。
提供する例は、単にポリモーフィズムを示すためのものであり、量産コードではありません。時々、まさにそのような例が文字通りに取られます。
FPおよびSOAでは、データはビジネスロジックから分離されています。つまり、データとロジックは連動しません。ロジックはサービスに入り、データ(ドメインモデル)にはポリモーフィックな動作がありません(注2を参照)。
サービスと機能はポリモーフィックにすることができます。FPでは、関数を値としてではなく他の関数にパラメーターとして頻繁に渡します。CallableやFuncなどの型を使用して、オブジェクト指向言語で同じことを実行できますが、横行することはありません(注3を参照)。FPおよびSOAでは、モデルはポリモーフィックではなく、サービス/機能のみです。(注4を参照)
その例では、ハードコーディングの悪いケースがあります。私は赤い文字列「犬の樹皮」について話しているだけではありません。CatModelとDogModel自体についても話します。羊を追加する場合はどうなりますか?あなたのコードに入り、新しいコードを作成する必要がありますか?どうして?本番コードでは、むしろそのプロパティを備えたAnimalModelのみを表示します。最悪の場合、AmphibianModelとFowlModelのプロパティと処理が大きく異なる場合。
これは、現在の「OO」言語で見られると予想されるものです。
public class Animal
{
public int AnimalID { get; set; }
public int LegCount { get; set; }
public string Name { get; set; }
public string WhatISay { get; set; }
}
public class AnimalService : IManageAnimals
{
private IPersistAnimals _animalRepo;
public AnimalService(IPersistAnimals animalRepo) { _animalRepo = animalRepo; }
public List<Animal> GetAnimals() => _animalRepo.GetAnimals();
public string WhatDoISay(Animal animal)
{
if (!string.IsNullOrWhiteSpace(animal.WhatISay))
return animal.WhatISay;
return _animalRepo.GetAnimalNoise(animal.AnimalID);
}
}
オブジェクト指向のクラスから関数型プログラミングにどのように移行しますか?他の人が言ったように。できますが、実際はそうではありません。上記のポイントは、JavaとC#を実行するときに、クラスを(従来の世界の感覚で)使用するべきではないことを示すことです。サービス指向アーキテクチャ(DDD、階層化、階層化、六角形など)でコードを記述すると、論理関数(サービス)からデータ(ドメインモデル)を分離するため、機能に一歩近づきます。
FPに一歩近づくOO言語
あなたはそれをもう少し進めてSOAサービスを2つのタイプに分けることさえできます。
オプションのクラスタイプ1:エントリポイントの共通インターフェイス実装サービス。これらは、「純粋な」または「不純な」他の機能を呼び出すことができる「不純な」エントリポイントになります。これは、RESTful APIからのエントリポイントかもしれません。
オプションのクラスタイプ2:純粋なビジネスロジックサービス。これらは「純粋な」機能を持つ静的クラスです。FPでは、「純粋」は副作用がないことを意味します。StateまたはPersistenceをどこにも明示的に設定しません。(注5を参照)
したがって、サービス指向アーキテクチャで使用されているオブジェクト指向言語のクラスを考えると、オブジェクト指向コードにメリットがあるだけでなく、関数型プログラミングの理解が非常に簡単になります。
ノート
注1:オリジナルの「リッチ」または「アクティブレコード」オブジェクト指向デザインはまだ存在します。10年以上前に人々が「正しく実行」していた頃のようなレガシーコードがたくさんあります。前回、その種のコード(正しく行われた)が、メモリを正確に制御し、スペースが非常に限られていたビデオゲームのC ++のCodebaseからのものであることがわかりました。FPおよびサービス指向アーキテクチャが獣であり、ハードウェアを考慮するべきではないことは言うまでもありません。しかし、それらは絶えず変化し、維持され、可変のデータサイズを持ち、優先事項として他の側面を持つ能力を置きます。ビデオゲームとマシンAIでは、信号とデータを非常に正確に制御します。
注2:ドメインモデルには多態的な動作はなく、外部依存関係もありません。それらは「分離」されています。それは、彼らが100%貧血である必要があるという意味ではありません。それらは、構築と可変プロパティの変更に関連する多くのロジックを持っている場合があります。Eric EvansとMark SeemannによるDDD「Value Objects」とエンティティを参照してください。
注3:LinqとLambdaは非常に一般的です。しかし、ユーザーが新しい関数を作成するとき、FuncやCallableをパラメーターとして使用することはめったにありませんが、FPでは、そのパターンに従う関数のないアプリを見るのは奇妙です。
注4:ポリモーフィズムと継承を混同しないでください。CatModelは、AnimalBaseを継承して、動物が通常持つプロパティを決定する場合があります。しかし、私が示すように、このようなモデルはコード臭です。このパターンが表示された場合は、それを分解してデータに変換することを検討してください。
注5:純粋な関数は、関数をパラメーターとして受け入れることができます(実際に受け入れます)。入ってくる関数は不純かもしれませんが、純粋かもしれません。テスト目的では、常に純粋です。しかし、本番環境では、純粋として扱われますが、副作用が含まれる場合があります。純粋な関数が純粋であるという事実は変わりません。パラメーター関数は不純かもしれませんが。混乱しない!:D