0

現在、VB6 で開発された非常に大きな銀行ソリューションに取り組んでいます。アプリケーションは大部分がフォーム ベースであり、階層化されたアーキテクチャがありません (データ アクセス、ビジネス ロジック、およびフォーム操作のすべてのコードは単一のフォーム クラスにあります)。私の仕事は、このコードをリファクタリングすることです。私は適切なビジネス ロジック レイヤーとデータ アクセス レイヤーを C# で作成していますが、フォームは VB のままです。

コード スニペットは次のとおりです。

public class DistrictDAO
{
    public string Id{get;set;}
    public string DistrictName { get; set; }
    public string CountryId { get; set; }
    public DateTime SetDate { get; set; }
    public string UserName { get; set; }
    public char StatusFlag { get; set; }
}

District Entity クラス、なぜその拡張子が DAO なのか、よくわかりません。

 public class DistrictGateway
{
    #region private variable
    private DatabaseManager _databaseManager;
    #endregion

    #region Constructor
    public DistrictGateway(DatabaseManager databaseManager) {
        _databaseManager = databaseManager;
    }
    #endregion

    #region private methods
    private void SetDistrictToList(List<DistrictDAO> dataTable, int index, DistrictDAO district){
        // here is some code for inserting 
    }    
    #endregion

    #region public methods
        try
        {
        /*
         query and rest of the codes
         */    

        }
        catch (SqlException sqlException)
        {
            Console.WriteLine(sqlException.Message);
            throw;
        }
        catch (FormatException formateException)
        {
            Console.WriteLine(formateException.Message);
            throw;
        }
        finally {
            _databaseManager.ConnectToDatabase();
        }


    public void InsertDistrict() { 
        // all query to insert object
    }

    public void UpdateDistrict() { 

    }
    #endregion
}

データベース クエリの処理を担当する DistrictGateway クラス ビジネス層になりました。

  public class District
{
    public string Id { get; set; }
    public string DistrictName { get; set; }
    public string CountryId { get; set; }
}


public class DistrictManager
{
    #region private variable
    private DatabaseManager _databaseManager;
    private DistrictGateway _districtGateway;
    #endregion

    #region Constructor
    public DistrictManager() { 
        // Instantiate the private variable using utitlity classes
    }
    #endregion

    #region private method
    private District TransformDistrictBLLToDL(DistrictDAO districtDAO) { 

        // return converted district with lots of coding here
    }

    private DistrictDAO TransformDistrictDLToBLL(District district)
    {

        // return converted DistrictDAO with lots of coding here
    }

    private List<District> TransformDistrictBLLToDL(List<DistrictDAO> districtDAOList)
    {

        // return converted district with lots of coding here
    }

    private List<DistrictDAO> TransformDistrictDLToBLL(List<District> district)
    {

        // return converted DistrictDAO with lots of coding here
    }


    #endregion

    #region public methods
    public List<District> GetDistrict() {
        try
        {
            _databaseManager.ConnectToDatabase();
          return TransformDistrictBLLToDL(  _districtGateway.GetDistrict());

        }
        catch (SqlException sqlException)
        {
            Console.WriteLine(sqlException.Message);
            throw;
        }
        catch (FormatException formateException)
        {
            Console.WriteLine(formateException.Message);
            throw;
        }
        finally {
            _databaseManager.ConnectToDatabase();
        }
    }

    #endregion

これは、ビジネス層のコードです。

私の質問は次のとおりです。

  1. 完璧なデザインですか?
  2. そうでない場合、ここでの欠陥は何ですか?
  3. 私は、try catchブロックが重複しているこのコードだと思います
  4. この実装に適した設計とは
4

4 に答える 4

0

完全?そのようなことはありません。ここで質問する必要がある場合、それはおそらく間違っています。そして、それが今「完璧」であるとしても、それは一度ではなく、エントロピーがそれを手に入れます。

あなたがどれだけうまくやったかという尺度は、それを延長する時が来たときに来るでしょう。変更がすぐに反映されれば、うまくいきました。変更を追加するためにレガシーコードと戦っているように感じる場合は、何が間違っていたかを把握し、それをリファクタリングします。

欠陥?わかりにくいです。今のところ、深く掘り下げるエネルギー、時間、モチベーションがありません。

#3の意味がわかりません。

典型的なレイヤリングは次のようになり、矢印は依存関係を示しています。

view <- controller -> service +-> model <- persistence  (service knows about persistence)

各レイヤーには横断的関心事があります。

  • ビューは、プレゼンテーション、スタイリング、およびローカリゼーションについて知っています。ユーザーエクスペリエンスを向上させるために可能なあらゆる検証を行いますが、ビジネスルールは含まれていません。
  • コントローラはビ​​ューに密接に関連付けられています。ビューからのリクエストのバインドと検証、適切なサービスへのルーティング、エラー処理、次のビューへのルーティングに関心があります。それでおしまい。Web、タブレット、モバイルなどで同じにする必要があるため、ビジネスロジックはサービスに属します。
  • サービスは、ビジネスロジックが存在する場所です。ビジネスルールに従った検証と、モデルおよび永続化レイヤーとのコラボレーションによるユースケースの実現について心配しています。ユースケース、作業単位、およびトランザクションについて知っています。
  • モデルオブジェクトは、より機能的なスタイルを好む場合は値オブジェクトにすることができ、そのような傾向がある場合はより豊富なビジネスロジックを与えることができます。
  • 永続性は、すべてのデータベースの相互作用を分離します。

アスペクト指向プログラミングを含むSpringのようなフレームワークを使用する場合、セキュリティ、トランザクション、監視、ロギングなどの横断的関心事をアスペクトと見なすことができます。

于 2011-09-21T19:41:21.950 に答える
0

ただし、ここで特定の質問をしているわけではありませんが、正しい道を歩むためには一般的なガイダンスが必要なようです。あなたのようにアプリケーション全体の詳細なビューを持っていないため、単一の方法論を提案するのは奇妙です.

n 層アーキテクチャは最近よく聞かれる質問のようですが、それをきっかけに、n 層アーキテクチャに関するブログ シリーズを書きました。これらの SO の質問とブログ投稿を確認してください。彼らはあなたを大いに助けると思います。

N 層アーキテクチャに関するブログ シリーズ (サンプル コード付き)

于 2011-09-21T20:12:57.010 に答える
0

大きなプロジェクトの場合は、MVVM パターンをお勧めします。これにより、コードを完全にテストでき、後でコードを拡張したり、一部を変更したりするのがはるかに簡単になります。他のレイヤーのコードを変更せずに、UI を変更することもできます。

于 2011-09-21T20:28:19.913 に答える
0

あなたの仕事がコードをリファクタリングすることである場合、まず上司に、本当にそれをリファクタリングするべきか、それとも機能を追加するべきかを尋ねてください。どちらの場合も、そのコードに自動化されたテスト ハーネスが必要です。運が良く、機能を追加する必要がある場合は、少なくとも出発点と目標があります。そうしないと、自分で開始点を選択する必要があり、目標がありません。コードを際限なくリファクタリングできます。目標がなければ、それは非常にイライラする可能性があります。

テストせずにコードをリファクタリングすると、災害のレシピになります。コードのリファクタリングとは、動作を変更せずに構造を改善することを意味します。テストを行わないと、何かを壊していないという確信が持てなくなります。定期的に多くのテストを行う必要があるため、これらのテストは自動化する必要があります。そうしないと、手動テストに多くの時間を費やしてしまいます。

レガシ コードを一部のテスト ハーネスに押し込むのは困難です。テスト可能にするには、変更する必要があります。コードの周りにテストをラップしようとすると、暗黙のうちにコードの階層構造が発生します。

ここで、鶏が先か卵が先かという問題があります。コードをテストするにはコードをリファクタリングする必要がありますが、現時点ではテストがありません。答えは、「防御的な」リファクタリング手法から始めて、手動でテストすることです。これらの手法の詳細については、Micheal Feather の著書「Working Effectively with Legacy Code 」を参照してください。多くのレガシー コードをリファクタリングする必要がある場合は、実際に読む必要があります。それは本当の目を見張るものです。

あなたの質問に:

  1. 完璧なデザインはありません。潜在的に優れたものだけがあります。
  2. アプリケーションに単体テストがない場合、これが最大の欠陥です。最初にテストを導入します。一方で、これらのコード スニペットはそれほど悪くはありません。DistrictDAOの技術版のようなものらしいDistrict。ドメインモデルを導入しようとする試みがあったのかもしれません。And: 少なくとも、注入されたコンストラクター パラメーターをDistrictGateway取得します。DatabaseManager私はもっ​​と悪いことを見てきました。
  3. はい、try-catch ブロックはコードの重複と見なすことができますが、それは異常なことではありません。適切な例外クラスを選択することで、catch 句を減らすことができます。または、デリゲートを使用したり、AOP 手法を使用したりすることもできますが、コードが読みにくくなります。詳細については、この他の質問を参照してください。
  4. レガシ コードをテスト ハーネスに適合させます。より良いデザインが暗黙のうちに出現します。

いずれにせよ: まず第一に、上司がコードのリファクタリングで何を意味するのかを明確にします。なんらかの目的を持たずにコードをリファクタリングするだけでは生産的ではなく、上司を喜ばせることもできません。

于 2011-09-21T20:31:46.690 に答える