タグ付けされた質問 「encapsulation」

6
メソッド連鎖とカプセル化
メソッドチェーンと「単一アクセスポイント」メソッドの古典的なOOP問題があります。 main.getA().getB().getC().transmogrify(x, y) 対 main.getA().transmogrifyMyC(x, y) 最初の方法には、各クラスがより小さな操作セットのみを担当し、すべてをよりモジュール化するという利点があるようです-Cにメソッドを追加しても、A、B、またはCでそれを公開する労力は必要ありません。 もちろん、欠点はカプセル化が弱いことです。これは2番目のコードで解決されます。これで、Aはそれを通過するすべてのメソッドを制御し、必要に応じてフィールドに委任できます。 単一の解決策はなく、もちろんコンテキストに依存することはわかっていますが、2つのスタイルのその他の重要な違いについて、またどのような状況でどちらを好むべきかについて、いくつかの意見を聞きたいと思います。いくつかのコードを設計するために、引数を使用してどちらかの方法を決定していないように感じます。

5
カプセル化を壊さずに依存性注入を使用できますか?
ここに私のソリューションとプロジェクトがあります: BookStore (ソリューション) BookStore.Coupler (プロジェクト) Bootstrapper.cs BookStore.Domain (プロジェクト) CreateBookCommandValidator.cs CompositeValidator.cs IValidate.cs IValidator.cs ICommandHandler.cs BookStore.Infrastructure (プロジェクト) CreateBookCommandHandler.cs ValidationCommandHandlerDecorator.cs BookStore.Web (プロジェクト) Global.asax BookStore.BatchProcesses (プロジェクト) Program.cs Bootstrapper.cs: public static class Bootstrapper.cs { // I'm using SimpleInjector as my DI Container public static void Initialize(Container container) { container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>), typeof(CreateBookCommandHandler).Assembly); container.RegisterDecorator(typeof(ICommandHandler<>), typeof(ValidationCommandHandlerDecorator<>)); container.RegisterManyForOpenGeneric(typeof(IValidate<>), AccessibilityOption.PublicTypesOnly, (serviceType, …

7
クラス変数を渡すクラスメソッドを作成したのは悪い考えですか?
ここに私が意味するものがあります: class MyClass { int arr1[100]; int arr2[100]; int len = 100; void add(int* x1, int* x2, int size) { for (int i = 0; i < size; i++) { x1[i] += x2[i]; } } }; int main() { MyClass myInstance; // Fill the arrays... myInstance.add(myInstance.arr1, myInstance.arr2, myInstance.len); } addクラスメソッドなので、必要なすべての変数に既にアクセスできますが、これは悪い考えですか?これを行うべき、またはすべきでない理由はありますか?

1
フレンドクラスを使用してプライベートメンバー関数をC ++でカプセル化する-良い習慣ですか?
だから私は、次のようなことをすることでヘッダーにプライベート関数を置くことを避けることが可能であることに気付きました: // In file pred_list.h: class PredicateList { int somePrivateField; friend class PredicateList_HelperFunctions; public: bool match(); } // In file pred_list.cpp: class PredicateList_HelperFunctions { static bool fullMatch(PredicateList& p) { return p.somePrivateField == 5; // or whatever } } bool PredicateList::match() { return PredicateList_HelperFunctions::fullMatch(*this); } プライベート関数はヘッダーで宣言されることはなく、ヘッダーをインポートするクラスのコンシューマーは、それが存在することを知る必要はありません。これは、ヘルパー関数がテンプレートの場合に必要です(代替方法はヘッダーに完全なコードを配置することです)。これが、私がこれを「発見」した方法です。プライベートメンバ関数を追加/削除/変更する場合、ヘッダーを含むすべてのファイルを再コンパイルする必要がないというもう1つの利点があります。すべてのプライベート関数は.cppファイルにあります。 そう... これは有名なデザインパターンですか? 私にとって(Java / C#のバックグラウンドから来て、自分の時間でC …


5
内部データ構造を常に完全にカプセル化する必要がありますか?
このクラスを考慮してください: class ClassA{ private Thing[] things; // stores data // stuff omitted public Thing[] getThings(){ return things; } } このクラスは、データを保存するために使用する配列を、関心のあるクライアントコードに公開します。 作業中のアプリでこれを行いました。sのChordProgressionシーケンスを格納するクラスがありましたChord(その他の処理も行います)。Chord[] getChords()コードの配列を返すメソッドがありました。データ構造を(配列からArrayListに)変更する必要がある場合、すべてのクライアントコードが破損しました。 これは私に考えさせられた-多分次のアプローチが優れている: class ClassA{ private Thing[] things; // stores data // stuff omitted public Thing[] getThing(int index){ return things[index]; } public int getDataSize(){ return things.length; } public void setThing(int …

4
カプセル化の過剰使用に悩まされますか?
さまざまなプロジェクトのコードに、コードの臭いや悪いことのように見える何かに気づきましたが、対処できません。 「きれいなコード」を書き込もうとしている間、コードを読みやすくするためにプライベートメソッドを使いすぎる傾向があります。問題は、コードが確かにきれいであるが、テストするのが難しいことです(そう、私はプライベートメソッドをテストできることを知っています...)、一般的に私には悪い習慣のようです。 次に、.csvファイルからデータを読み取り、顧客のグループ(さまざまなフィールドと属性を持つ別のオブジェクト)を返すクラスの例を示します。 public class GroupOfCustomersImporter { //... Call fields .... public GroupOfCustomersImporter(String filePath) { this.filePath = filePath; customers = new HashSet<Customer>(); createCSVReader(); read(); constructTTRP_Instance(); } private void createCSVReader() { //.... } private void read() { //.... Reades the file and initializes the class attributes } private void readFirstLine(String[] inputLine) …

4
ネストされたクラス:便利なツールまたはカプセル化違反?
だから、私はこれらを使用すべきかどうかについて、まだフェンスの上にいます。 カプセル化の極端な違反を感じますが、コードの柔軟性を高めながら、ある程度のカプセル化を達成できることがわかりました。 以前のJava / Swingプロジェクトでは、ネストされたクラスをある程度使用していましたが、C#で他のプロジェクトに移動したため、使用を避けています。 ネストされたクラスについてどう思いますか?

4
メソッドの名前を変更してもカプセル化を維持できますか?
ゲッター/セッターが正当化される時期についてこのページを読んでいましたが、OPは次のコードサンプルを提供しました。 class Fridge { int cheese; void set_cheese(int _cheese) { cheese = _cheese; } int get_cheese() { return cheese; } } void go_shopping(Fridge fridge) { fridge.set_cheese(fridge.get_cheese() + 5); } 受け入れ答えの状態: ちなみに、あなたの例ではFridge、putCheese()andのtakeCheese()代わりに、クラスに and メソッドを指定get_cheese() しset_cheese()ます。その後、まだカプセル化されています。 カプセル化は、名前をget / setからputCheese()/に変更することによってどのように保持さtakeCheese()れますか? 同じ答えでそれはまた述べています: ゲッターとセッターを使用しても、カプセル化が壊れることはありません。カプセル化を解除するのは、何も考えずに、すべてのデータメンバー(Java lingoのすべてのフィールド)にゲッターとセッターを自動的に追加することです。 この場合、変数は1つだけなのでcheese、チーズを取り出して冷蔵庫に戻したい場合があるため、この場合の取得/設定ペアは正当化されます。

5
関数が外部からアクセスされていることを明確にする方法は?
これはC固有の質問です。私は可能な限りすべてを翻訳単位の境界内に保ち、.hファイルを介していくつかの関数のみを公開することを試みています。つまり、staticファイルレベルのオブジェクトへのリンクを提供しています。 ここで、いくつかの関数を他のモジュールから呼び出す必要がありますが、直接呼び出す必要はありません。私のモジュール/ファイル/翻訳ユニットは他のモジュールにサブスクライブし、関数へのポインターを渡します。次に、特定のイベントが発生すると、いくつかの引数を指定してポインターが呼び出されます。 したがって、これらの関数があいまいな場所から呼び出されていることを非常に明確にする方法を知りたいと思います。 彼らは、あるべきstaticかextern(及び、それらを公開しますか.h)? 関数の名前にいくつかのヒントを含める必要がありますか? それとも、「Xから呼び出されました」というコメントで十分ですか?

7
懸念の分離:分離が「多すぎる」のはいつですか?
私はすっきりしたコードが大好きで、コードを可能な限り最善の方法でコーディングしたいと思っています。しかし、常に1つありましたが、本当に理解できませんでした。 メソッドに関する「懸念の分離」が多すぎるのはいつですか? 次のメソッドがあるとします。 def get_last_appearance_of_keyword(file, keyword): with open(file, 'r') as file: line_number = 0 for line in file: if keyword in line: line_number = line return line_number この方法はそのままでも問題ないと思います。それはシンプルで読みやすく、そしてその名前が言うように、それは明らかにそうです。しかし、それは「ただ1つのこと」を実際に行っているのではありません。実際にファイルを開き、それを見つけます。それは私がそれをさらに分割できることを意味します(「単一の責任の原則」も考慮する): バリエーションB(まあ、これは何となく理にかなっています。このようにして、テキスト内のキーワードの最後の出現を見つけるアルゴリズムを簡単に再利用できますが、「多すぎる」ように見えます。理由は説明できませんが、「感じる」 「それはそのように): def get_last_appearance_of_keyword(file, keyword): with open(file, 'r') as text_from_file: line_number = find_last_appearance_of_keyword(text_from_file, keyword) return line_number def find_last_appearance_of_keyword(text, keyword): line_number = 0 …

2
合成されたオブジェクトへのポインタを返すことはカプセル化に違反しますか
他のオブジェクトを集約するオブジェクトを作成する場合、パススルー関数を使用して内部オブジェクトへのインターフェイスを公開するのではなく、内部オブジェクトへのアクセスを許可したいと思います。 たとえば、2つのオブジェクトがあるとします。 class Engine; using EnginePtr = unique_ptr<Engine>; class Engine { public: Engine( int size ) : mySize( 1 ) { setSize( size ); } int getSize() const { return mySize; } void setSize( const int size ) { mySize = size; } void doStuff() const { /* do stuff …

4
ささいな保護されたゲッターは過剰に露骨ですか?
私が以前に本当に考えたことがないもの(AS3構文): private var m_obj:Object; protected function get obj():Object { return m_obj; } private var m_str:String; protected function get str():String { return m_str; } 少なくともサブクラスはm_objまたはm_strを設定できません(ただし、m_objを変更することはできます)。 私の質問:これは単なる露骨なやりすぎですか? このプログラマーの質問: 単純にパブリックプロパティにするのではなく、クラスプロパティのゲッター/セッターをいつまたはなぜ使用する必要があるのでしょうか。 重複として提案されています。 その質問は、パブリックプロパティとプライベートプロパティのみを扱い、プロパティをゲッターとセッターでラップする必要があるかどうかという点で異なります。私の質問では、保護された変数と、継承するクラスがそれらの変数とどのように相互作用するかに焦点を当てています。 したがって、代替実装は次のようになります。 protected var m_obj:Object; //more accessible than a private variable with a protected getter protected var m_str:String; //more accessible than a …

1
JavaScriptオブジェクトとCrockfordのThe Good Parts
最近、JSでOOPを実行する方法についてかなり考えています。特に、カプセル化と継承に関してはそうです。 Crockfordによれば、classicalはnew()により有害であり、prototypeとclassicの両方が制限されています。これらのコンストラクターの使用は、カプセル化にクロージャーを使用できないことを意味します。 最近、私はカプセル化について次の2つの点を検討しました。 カプセル化するとパフォーマンスが低下します。各オブジェクトのメソッドには異なるクロージャーがあるため(各オブジェクトには異なるプライベートメンバーがあるため)、プロトタイプではなく各メンバーオブジェクトに関数を追加できます。 カプセル化によって、醜い「var that = this」の回避策が強制され、プライベートヘルパー関数が接続されているインスタンスにアクセスできるようになります。それか、毎回privateFunction.apply(this)でそれらを呼び出すようにしてください。 私が言及した2つの問題のいずれかの回避策はありますか?そうでない場合でも、カプセル化はそれだけの価値があると考えていますか? 補足:Crockfordが説明する機能パターンでは、new()とconstructor.prototypeの使用を完全に忘れているため、パブリックメンバーにのみ触れるパブリックメソッドを追加することもできません。古典的な継承とnew()を使用するだけでなく、Super.apply(this、arguments)を呼び出してプライベートメンバーと特権付きメソッドを初期化するハイブリッドアプローチは優れていますか?

6
安全のためにカプセル化はどのように使用されますか?
OOPを学習しています。私はカプセル化について多くのことを学びましたが、読むほど、混乱しました。 私は(プライベートにすることで)データを隠し、プロパティまたはメソッドとしてクラスのユーザー(他の開発者)に公開することを理解しています。また、カプセル化によって詳細を隠すことも理解しています。 記事(http://www.csharp-station.com/Tutorial/CSharp/lesson19)で私は読んだ: 記事の要約 オブジェクトを設計するときは、他の人がそれをどのように使用できるかを考える必要があります。最良のシナリオでは、オブジェクトを使用するすべてのプログラムが適切に設計され、コードが変更されることはありません。ただし、実際にはプログラムは頻繁に変更され、チーム環境では多くの人が一度に同じコードに触れます。したがって、オブジェクトがどのように自然のままの画像だけでなく、間違って行くことができるかを検討することは有益である必要があります使用すること。 BankAccountオブジェクトの場合は、オブジェクト外のコードが10進数のAmountフィールドまたは文字列CustomerNameフィールドにアクセスできる状況を調べます。コードが作成された時点で、すべてがうまく機能します。ただし、開発サイクルの後半では、情報間の関係(または内部状態の定義を変更する他の有効な理由)を複製したくないため、BankAccountオブジェクトは文字列CustomerNameではなくint CustomerIDを追跡する必要があることに気付きます。 。このような変更は、元々設計されたとおりに(CustomerNameが文字列である)BankAccountクラスを使用するように構築されているため、コードに波及効果を引き起こし、アプリケーション全体でその状態にアクセスするコードを変更する必要があります。 カプセル化のオブジェクト指向の原則は、このような問題を回避するのに役立ち、メソッド、プロパティ、インデクサーなどの型メンバーを介して内部状態を非表示にし、アクセスを抽象化できます。カプセル化は、オブジェクト間の結合を減らし、コードの保守性を向上させるのに役立ちます。 質問 カプセル化は、コードに変更を加えるとき、およびその波及効果からどのように役立ちますか。データメンバーの場合、その型をintからfloatに変更すると(プロパティを使用してこれを公開している場合でも)、このコードを既に使用している変数の型を変更する必要があります。 カプセル化がこのような変更にどのように役立つかを教えてください。 このヘルプとガイダンスをありがとう。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.