3

しばらくの間、うまく機能している c# コードがいくつかあります。オブジェクト指向の原則の基本は理解していますが、猫の皮を剥ぐ方法は明らかに複数あると言わざるを得ません (ただし、そのフレーズは嫌いです!)。 .

したがって、次のように基本的なデータ サービス クラスとして機能する基本抽象クラスがあります (読みやすくするために大幅に簡略化しています)。

public abstract class dataservice
{
    public enum OutputType : int { XmlTOJson = 0, Xml = 1, Json=2 }

    protected object SomeDBcall(string StoredProcedure)
    {
        // Just assume we are using SQLclient/DB access..
        object SomeReturnObjValue = db.ExecuteScalar(cmd);
        return SomeReturnObjValue;
    {
}

..基本的に、抽象クラスにいくつかの基本的なDBの取得/更新/削除呼び出しがあるかもしれません..主に、アプリにあるDB操作の基礎があるためです。

これで、基本クラスを実装するクラスができました。たとえば、私の場合は顧客クラスです。

public class Customer : dataservice
{
    Public String CustomerDoSomething(string SomeDataEtc)
    {
        // Ok, so again for simplicity sake, we are going to use the base class to 
        // call a DB retrieve 
        object ReturningObj = SomeDBcall("my stored procedure");
        return ReturningObj.ToString();
    }
}

だから私の質問はこれだと思います:上記の方法は「大丈夫」ですか?必要に応じて仮想メソッドをオーバーライドできると考えていますが、この場合、DB操作を呼び出す手段として保護されているメソッドを基本クラスで使用するだけです。

明確さ/ガイダンスは非常に高く評価されています!

4

5 に答える 5

1

おそらく、抽象クラスを具体的にして、必要なデータベース関連のものを処理するある種のヘルパークラスとして使用することができます。サンプルコードが示す限り、クラスにアクセスする複数のデータベースを持つ必要はなく、パラメータが異なるだけです。

于 2012-06-07T17:55:12.420 に答える
1

テンプレートパターンを調べて、具体的なサブクラスでオーバーライドできる定義済みの保護された仮想フックを使用して、基本(抽象または非抽象)クラスのインターフェイスを定義することをお勧めします。別の投稿者が述べたように、各ドメイン領域にDBサービスを追加するだけの場合は、データベースサービスから派生するのではなく、基本的なデータベースサービスメソッドをヘルパークラスにカプセル化することを検討してください。

LSP違反ステートメントについて質問してくれた@jgauffinに感謝します。正しくなく、削除されました。基本クラスのパブリックインターフェイスをサブクラスで拡張する必要がある場合が多くあります。もちろん、これを行うには、YとZの両方がXから派生し、Yが新しいパブリックメソッドA()とZはそうではありません。

OPのコンテキストでのテンプレートパターンの例では、パブリックインターフェイスを拡張せずに、サブクラス内のカスタム機能をより適切にカプセル化できます。ただし、これは、OPのSomeDataEtcパラメータなど、サブクラスインスタンスに外部からの影響が及ばない場合にのみ機能します。これは、インスタンスが不変である場合に最適に機能します。

public abstract class DataService
{
    protected object myWidget = new Widget();
    public object SomeDataBaseCall(string storedProcedure)
    {

        DoSomeCustomThing();

        //do db stuff
        object SomeReturnObjValue = db.ExecuteScalar(storedProcedure);
        return SomeReturnObjValue;
    }

    protected void DoSomeCustomThing() {}
}


public class Customer : DataService
{
    override protected void DoSomeCustomThing()
    {
        // do your custom thing here
    }
}

さらに、OPの例では、派生クラスの新しいパブリックメソッド内で委任を使用して、基本クラスのSomeDBCallメソッドを呼び出してストアドプロシージャを実行するのが賢明なようです。dbアクセスメソッドを冗長にコーディングしている場合、提案された継承には何のメリットもありません。

他の場所でも述べたように、データサービス機能の継承ではなく、構成を使用する方がよい場合があります。

于 2012-06-07T18:17:55.000 に答える
1

概要

多くの場合、あなたの「開発自体があなたを導きます」。

実用的な答え。

(1)基本クラス「dataservice」を定義すると、そのクラスから、他のいくつかのクラスがベースになります。あなたは「抽象的」とマークしました、それは良いことです。それ自体が変数を持つという意味ではありません。

一部の開発者は、そのクラスを「抽象」としてマークしません。これは必須ではありませんが、悪い考えではありませんが、「抽象」とマークするための「グッドプラクティス」です。

また、サブクラスで使用される他のメソッドが追加され、オーバーライドされる場合とされない場合があります。

知っておくと、これらのメソッドは保護されており、オブジェクトの外部で使用されることを意味するのではなく、他のメソッドによって使用されることを意味します。それで大丈夫です。

後で、メソッドをクラス外で使用する必要があり、パブリックに変更する必要があるかもしれません。

(2)「DataService」の子孫であるサブクラス「Customer」を追加します。クラスの外部で使用する必要があり、「public」とマークされているメソッドを追加します。

これは、親クラスではなく、このクラスによってのみ使用されることを意図しています。したがって、「仮想」または「オーバーライド」は必要ありません。良い。

(3)あなたの例はとても単純です。あなたがしたほとんどのことは、私には問題ないようです。

最終的に、コードを追加すると、状況が変わる可能性があります。たとえば、プライベートであった基本クラスのメソッドがパブリックになるか、「dosomething」などのメソッドを「名前変更」または「リファクタリング」して、より優れていることがわかります。基本クラスに含まれるかどうか。

概要

他にも、その言及、規則、または概念に関する回答があります。彼らは大丈夫だと私には思えますが、あなたがOOPをよりよく使うことを学んでいるという事実をスキップしてください。「一口でケーキを食べよう」という人もいますが、それは良い考えではありません。

PD「うさぎの肌を傷つけることができます」、私にはよく聞こえます。

乾杯。

于 2012-06-07T18:36:21.277 に答える
1

確かに、それは「大丈夫」ですが、基本クラスがabstract. abstractクラスは、いくつかの一般的なロジックを実装し、残りの実装を派生クラスに任せるのに最適です。ただし、抽象/仮想メソッドがないため、ここでのポイントはわかりません。

于 2012-06-07T16:03:21.203 に答える
0

次のデータ アクセス オブジェクト パターン (DAO) を推測してください。いずれにしてCustomerも、あなたのデータ アクセス クラスではありません。クラスを使用してデータにアクセスします。つまり、DAO は継承よりも構成を優先する必要があるということです。

何かのようなもの:

public class Customer : IDataAccessObject
{
    public Customer()
    {
        _dataAccess = new DataAccess();
    }

    public string CustomerDoSomething(string SomeDataEtc)
    {
        object ReturningObj = _dataAccess.SomeDBcall("my stored procedure");
        return ReturningObj.ToString();
    }
}

なんで?オブジェクトは単一の責任を負います。つまり、オブジェクトの拡張とリファクタリングが容易になります。

いくつかの基本的なプログラミング原則であるSOLIDについて読むことができます。

あなたは .NET 開発者なので、命名ガイドラインに従うこともお勧めします。

于 2012-06-07T18:17:14.083 に答える