2009-06-12 12 views
1

私のプログラムの一部を設計する際に問題があります。これは小説を書くことなく説明するのは難しいですから、私は試してみましょう。Interface C#のレイアウト方法が正しい

基本的には、ハードウェアからパラメータを読み書きするプログラムがあります。現在、シリアル経由ではそうですが、最終的にFTDIチップ用の.NETラッパーを使用してUSB上で実行したいと考えています。http://www.ftdichip.com/Projects/CodeExamples/CSharp.htm

私の問題は、私はいくつかの抽象化層しかし、私はどこに線を引くべきかわからない。まず、ReadParam()WriteParam()SendCommand()の機能を私のメインフォームクラスに入れないようにします。それはただひっくり返っているようだ。だから明らかに彼らは私がインスタンス化するいくつかの他のクラスに入るはずです。その場合はCommとしましょう。

最初のオプションは、インターフェイスを作ってICommと言うことができ、シリアルとUSBの両方の味を実装することです。これは、ReadReplyData()という特別な機能とGUIに返す前にシリアルデータの前処理を行う機能があるため、コードの大部分が両方のフレーバで複製されるという問題があります。

したがって、次のオプションは、インタフェースであるICommDriverを定義する中間クラスです。 Commは、ReadParam()WriteParam()、およびSendCommand()の各関数と同様に、ReadReplyData()専用の書式化関数を実装します。一方、ICommDriverは、より簡単なReadおよびWrite関数を指定します。

これは2つのねじれを除いてすべて些細なようです。 1つは、私はこれは、明らかに、GUIがハングアップしないので、複数のtheadedしたい。だから私はCommはすべての読み取り/書き込みを行うにはBackgroundWorkerを使用すると考えています。またシリアルフレーバーには、USBフレーバーは表示されませんが、どのCOMポートを(GUIドロップダウンから)開くかを指定する必要があります。それでは、私はその部分をインターフェースの一部にするのかどうか?

あなたのお手伝いをしてくれてありがとう、私はこれを行う正しい方法を理解しようと数日間コードを書いている/削除しています!あなたが必要とするインタフェースの正確な種類に

ジョナサンに関しては

答えて

7

私は 抽象化のいくつかの層をしたい知っているが、私はあなたのどこに問題があるこれがどこにあるライン

を描画する を知っているように見えることはできません。これは開発に根本的に欠陥のあるアプローチであり、まさにこの麻痺の原因となります。いくつかの具体的なのフレーバーの実装を開発します。 kludgy if type1 else type2ロジックを使用してアプリケーションで作業してください。 その後、に戻り、共通の契約、共通の基盤を共有するためにそれらをすべてリファクタリングします。それはblindingly明白どこに行く必要があります。コメント欄でより詳細を

あなたが実装間でコードを共有している場合は、抽象クラスを使用する必要があります。各クラスは、自己完結してください

public interface IComm 
{ 
    void WriteParam(...); 
} 

public abstract class CommStandardBase : IComm 
{ 
    public void WriteParam(...) 
    { 
     DoWriteParam(...); 
    } 

    private void DoWriteParam(...) 
    { 
     CommonWrite1(...); 
     HandleWriteParam(...); 
     CommonWrite2(...); 
    } 

    protected abstract void HandleWriteParam(...); 

    private void CommonWrite1(...) 
    { 
     ... 
    } 

    private void CommonWrite2(...) 
    { 
     ... 
    } 
} 

:私の経験では、最終的なpublicメソッドを維持し、そのような公共の方法から保護された抽象メソッドを呼び出すことをお勧めです。シングルインスタンス、シングルスレッドである必要があり、ワーカーとレポーターの間でやりとりすることができます。

+0

私は既にソフトウェアを機能させていますが、私はリファクタリングとコードのクリーンアップを試みています。私が言及したように、私は私の 'ReadParam()'と 'WriteParam()'関数を私のMainFormクラスに持つことは嫌いです。 2つのフレーバーは、基本的には.NET SerialPortクラスとFTDIのFTD2XX_NETクラスのラッパーです。だから彼らは彼らが呼んでいる基本的な機能を除いて、ほとんど同じです。 –

+1

@Jonathon共有機能を実装する抽象クラスで何が問題になっていますか? –

+0

その共有コードの問題がある場合、その実装に同意します。 –

1

は、それはあなた次第、最終的で、誰が、このアプリケーションは、レベルの低い時にどのように動作するかを知っています。私はあなたの実装をUIで使うことについての部分と、BackgroundWorkerを使ったCommに関するコメントに反応したいと思います。私はそれを反転することをお勧めします。 BackgroundWorkerは実際にはUIレベルのコンポーネントですが、Commはエンタープライズアプリケーションのビジネスオブジェクトのような「中心的な」コンポーネントのほうが多いでしょう。 UIはBackgroundWorkerを作成し、必要な作業を実行するCommインスタンスを作成し、CommからのイベントをオーケストレーションしてUIを更新する必要があります。あなたのUIとBackgroundWorkerが長時間に渡って通信する必要がある場合は、UIが作成したり、キューに入れたり、ManualResetEventやAutoResetEventのスレッドハンドルを使用してUI間で通信できるようなデータ転送オブジェクトを作成することをお勧めしますスレッドとBackgroundWorker。そうすれば、より疎結合した製品が得られるはずです.WindForm、WPF、コマンドライン、さらに多分PowerShellクライアントを持つことができるUIの種類にかかわらず、Commクラスを独立して開発することができます。)

1

私はそうここmomementでVB.NETモードでやや午前行く...

 

Interface IComm 

    Function ReadParam() 
    Function WriteParam() 
    Function SendCommand() 

End Interface 



> 


MustInherit Class CommBase 

.... Load this up with the overideable 

End Class 


 

は、それからちょうどインターフェイスを実装し、必要に応じてベースを継承します。私はRex Mにも同意します。

関連する問題