2012-03-14 17 views
2

私は自分のOO言語を設計していて、例外を打つまでうまくいっていました。例外はカプセル化を破るようです。カプセル化と例外

たとえば、クラスAにクラスBのオブジェクトがあり、BにCがあり、CにXがあり、Aに例外がスローされた場合、AのコードはXだけでなくBとCも処理する必要がありますそれは正しく。これは、CをDに置き換えた場合、例外のハンドラを変更してコールスタックから関連情報を抽出する必要があるためです。

この問題を回避するには、クラスのAPIの一部として例外を設定して、一度に1つの呼び出し元スタックを呼び出すスタックを伝播させるしかありません。そして彼らは、彼ら自身の言葉で例外を再中断すべきです。

例を示します。トレンドは統計的傾向を分析するためのクラスであり、2つのポイントから1つのラインの傾きを計算する方法、傾きを持っています。

method slope 
    given 
     Point 1st 
     Point 2nd 
    returns 
     Number m 
    except 
     when infinite slope 

    m gets 
     (2nd's y - 1st's y)/(2nd's x - 1st's x) 
    except 
     when any divide by zero 
      declare infinite slope 
     when overflow of (2nd's y - 1st's y) 
      declare infinite slope 
     when overflow of (2nd's x - 1st's x) 
      instead do m gets 0 
     when overflow of (2nd's y - 1st's y)/(2nd's x - 1st's x) 
      declare infinite slope 
     when any underflow 
      instead use 0 

end of method slope 

これを行うより良い方法はありますか?あなたはDとCを交換する場合

+0

私の無知を許しますが、これはどの言語ですか? – dwerner

+1

非常に最初の行:私は自分のオブジェクト指向言語を設計しています... – shawnhcorey

答えて

0

は、例外の ハンドラが コールスタックから関連情報を抽出するために変更する必要があります。

通常、例外ハンドラは実装されていません。 Aがコンパイルされるときにクラスと呼ばれる中間体が存在しないこともあるので、Aへの依存関係を構築することは難しいだけでなく、原理的に実行不可能です。

+0

Xが "File not found"を投げた場合、Aはファイルが最初に必要な理由がわからず、 「ファイルが見つかりません」というメッセージが表示されます。それは友人に勝ち、人々に影響を与える良い方法のように私には聞こえません。 – shawnhcorey

+0

@shawnhcorey私が上に書いたものとあなたが今話しているものとの関係は、もしあれば、完全に逃げ出します。これは完全なものではありません。*まだ書かれていない中間の呼び出しコードに対処するコードを生成する必要があります。例えば、C++はこれを行います。それは明らかに不可能ではありません。 – EJP

+0

マシンコードですべてのことを書くことができます。それだけではお勧めできません。問題は可能なことではなく、他人が何をしたかということです。それは最高のものです。 – shawnhcorey

1

実世界の例外は3つのラフのいずれかのカテゴリに分類されます。基本的なランタイムで致命的エラーが発生すると、

  • システム例外がスローされ、メモリ、スタックオーバーフロー、またはおそらくセキュリティ違反のうちのようなもの。これらは一般的に捕らえるべきではなく、多くの場合、を捕まえられません。彼らは基本的に例外システムを使用して(比較的)システムを正常に停止させ、最終的なスタックトレースを開発者に報告します。

  • コードが間違っていると、プログラム例外がスローされます。無効な引数のようなもの、ヌルポインタのメソッドの呼び出し、境界外のエラー。これらは捕らえるべきではありません。代わりに、スローさせるコードを修正する必要があります。彼らは例外システムを使用して、ほとんど同じものを実行するシステムの冗長化を回避します。

  • 実行時例外は、プログラムによって防止できない何か悪いことが発生した場合にスローされます。予期せぬ状況が発生したときにスローされますが、エラーコードなどでメインAPIを乱雑にしたくないほど稀です。これらはファイルIOエラー、ネットワーク問題、解析エラーなどです。これらの例外通常、それを投げているAPIに固有のものです。これらは通常、種類の例外があり、通常はキャッチされます。

上記の内訳に同意すると、カプセル化は第3のカテゴリにのみ影響します。他の2つについては、例外はコードで捕捉されないので、問題ではありません。 3番目の種類の例外については、一般的に、例外をキャッチして、それを再スローするレイヤーに適した別の例外に変換する必要があります。これは、他の言語のほとんどの例外システムが、現在の例外につながった以前の低レベルの例外を添付できる「InnerException」のようなものをサポートしている理由です。

+0

第3のケースがキャッチされるべき唯一のケースであるため、よりクリーンなコードを書くためにのみ使用されます。それは後藤です。別の可能性があると私には思われます。トランザクションが完了できないことを通知するために例外を使用することができ、残りのコードは、アプリケーションが以前の有効な状態に戻るようにトランザクションに対して行った変更をすべてクリーンアップすることです。 – shawnhcorey

0

私は、例外がより多く聞こえることに同意します。そのオブジェクトとクラス指向の構造化。

しかし、エラーを解決することができます。

たとえば、... ...コールスタックから関連情報を抽出する。

class XClass { 
    public: 
    void doSomething() { throw new MyException(); } 
} 

class CClass { 
    public: 
    XClass X; 
} 

class BClass { 
    public: 
    CClass C; 
} 

class AClass { 
    public: 
    BClass B; 
} 

void main() 
{ 
    AClass A = new AClass(); 

    // exception here: 
    A.B.C.X.doSomething(); 
} 

"" オブジェクトは、例外に関する "X"、またはその逆、について知る必要はありません:C++様擬似コード

あなたの一例。すべてのオブジェクトが実行データを追加または削除する例外スタックが必要です。

「純粋なC」には例外はありませんが、エミュレートできます。 "setjmp"ライブラリを検索して、それらの関数がスタックとやりとりできるかどうかを調べることができます。これらの知識は、あなたが例外実装するのに役立つことがあります。

http://www.cplusplus.com/reference/clibrary/csetjmp/

をP.D. Offtopic suggestion:C++ネームスペース、またはパスカルモジュールをプログラムに追加します。あなたはそれを後悔しません。

+0

この 'A.B.C.X.doSomething();'は、AがXについて知っていなければならないものは何でもそれを示しています。 : – shawnhcorey

+0

@shawnhcoreyいいえ、 "A"メソッドはスタックにデータを格納し、 "B"メソッドはスタックにデータを格納し、 "C"メソッドはスタックにデータを格納し、 "X"メソッドはスタックにデータを格納し、例外ハンドラはエラーが発生し、そのデータを使用する代わりに、次の命令に進むために例外がスローされます。 – umlcat

関連する問題