『コードクリーンの道』ノート04——データ構造


データの抽象化
変数内部構造を隠し、抽象的に値を取ったり設定したりすることで、ユーザーがデータの実現に関心を持たずにデータ本体を操作できるようにします.
たとえば:
class Point {
    getX:function(){};
    getY:function(){};
 	setX:function(){};
    setY:function(){};
}
もちろん、ただ露出して値を取るのではなく、分配器が完成するのです.
たとえば:
class Vehicle {
    getFuelTankCapacityInGallons:function(){}
	getGallonsOfGasoline:function(){}
}
class Vehicle {
    getPercentFuelRemaining:function(){}
}
前者は明らかに具象手段で自動車の燃料曽階と通信しています.後者は抽象的な手段で割合をとって燃料のデータを得る.
前者は明らかに変数のアクセサです.後者は・・内部のデータ形態が分かりません.
ここでは明らかに後者がいいです.データの詳細を暴露したくないので、抽象的な形でデータを表現したいです.
あるオブジェクトに含まれるデータを最良の方法で提示するには、ひたすらの取得器と分配器ではなく、完成させます.
データ、対象の反対称性
上記の2つの例は、オブジェクトとデータ構造の違いを示しています.
  • オブジェクトは、データを抽象化した後に、操作データの関数を露出する.
  • データ構造はデータ構造を暴露し、有意な関数
  • を提供していない.
    この2つの差は小さいが、深い意味がある.
  • プロシージャコード
    class Square {
        point:{x:9,y:0}
    	side:20
    }
    class Rectangle {
        point:{x:9,y:0}
    	height:10;
    	width:10;
    }
    class Geometry {
        Pi: 3.14
    	area(shape){
            if(shape instanceof Square) {
                let s = shape
                return s.side  * s.side
            }
            if(shape instanceof Rectangle) {
                let s = shape
                return s.height  * s.width / 2
            }
            throw new Error('      ')
        }
    }
    
    は、形状クラスがデータのみを有し、Geometryは特定の関数を有する.
  • 長所:
  • Geometry内部にどんな方法を追加しても、外部の形状クラスのデータ構造には影響しません.
  • 欠点:
  • しかし、新しい形状を追加すると、Geometryに新しいコードを追加する必要があります.
  • 対象に向けた方法
    class Square {
        point:{x:9,y:0}
    	side:20
    	area:function(){}
    }
    class Rectangle {
        point:{x:9,y:0}
    	height:10;
    	width:10;
    	area:function(){}
    }
    
    は、各形状クラスに自分の関数があるので、このような関数的利点は前者とは明らかに反対であり、他のクラスの関数は、形状クラスを新たに追加する際には影響を受けない.
  • これは、データ構造とオブジェクトの二分原理を表している. ( ) ; 。逆を見ても通じます. , 。 , 。デメテルの法則
    オブジェクトがデータを隠し、露出操作を行います.これは、オブジェクトがアクセスによって操作を暴露するべきではないことを意味し、そのデータ構造も暴露されるからである.
    デメテル氏は、クラスCの方法fは以下のオブジェクトだけを呼び出すべきだと考えています.
  • C
  • fにより作成されたオブジェクト
  • は、パラメータとしてfのオブジェクト
  • に伝達される.
  • Cのエンティティ変数が持つオブジェクト
  • 言い換えると、方法は、どの関数で返されたオブジェクトを呼び出すべきではない.友達とだけ話して、知らない人とは話さない.
    いくつかの反例を通してこの法則を理解した.
  • 列車事故
    let opts = ctx.getOptions()
    let scratchDir = opts.getScratchDits()
    let outputDir = scratchDir.getAbsolutePath()
    
    これは列車と似ています.どのようにしてこの法則を違反したかを見てみましょう.
    モジュール オブジェクトは、多くのオプションを含み、各オプションには多くのディレクトリがあり、各ディレクトリは一つのパスに対応しています.
    一つの関数には豊かすぎます.
    上がデータ構造だけであるなら、当然この法則は適用されない.対象であれば、対象のデータ構造が暴露され、対象の隠しデータ構造に合わず、操作データの関数が暴露されます.
  • この混雑は、不幸にも混成構造を引き起こし、半分は対象で、半分はデータ構造である.このような構造は、新しいデータ構造を追加することの難しさを高めると同時に出現するかもしれないし、新しいクラスを追加することの難しさを高めることもあります.
  • 隠し構造は列車事故の例を説明します.もし私たちがデータ構造を隠す必要があるならば、また臨時ディレクトリの絶対パスを手に入れます.どうやって実現しますか?まず、絶対パスを取得するための必要性を見てみます.絶対パスを得ることは、指定された名前を作成するための一時ファイルを得るためであり、ctxを直接に
    let file = ctx.createScratchFileStream(classFileName)
    
    を操作させてもいいです.つまり、データ構造を隠しています.
  • データ転送先
    DTMは最も洗練されたデータ構造であり、共通変数のみで関数のないクラスである.このような構造は、データ転送オブジェクトと呼ばれることがあります.
    主に、データベース通信やソケット転送のメッセージなどのシーンを解析するために使用されます.
    結び目
  • オブジェクト暴露挙動は、データを隠すために、既存の挙動を修正する必要なく、新しいオブジェクトタイプを追加するのに便利であるとともに、既存のオブジェクトに新しい挙動を追加することも困難である.
  • データ構造暴露データは、明らかな挙動がなく、また既存のデータ構造に新しい挙動を追加するのに便利であると同時に、新しい既存の関数に新しいデータ構造を追加するのも難しい.