0

「ボックス モデル」という用語は、一般的に、「長方形のコンテナー」(別名「ボックス」) のグラフィカルなレイアウトを表すように設計されたデータ モデルを指し、関連する計算を実行するために使用します (たとえば、囲みボックスのサイズ変更)。(これは、そのようなモデル一例です。)

私の質問の本質はこれです:

次のプロパティを持つ「ボックス モデル」の実装を探しています。大まかに重要度の順に並べています。

  1. レイアウト情報のモデリング(寸法、マージン、パディング、包含関係など) と、特定のデバイス (Web ブラウザー、PostScript、X11 など) でのこの情報のレンダリングとの間の明確な分離を維持する必要があります。
  2. いくつかの「標準」ボックス モデル (たとえば、w3 の) を忠実に実装する必要があります。または、それがなければ、少なくとも「デファクト スタンダード」の称号の信頼できる候補になるのに十分な実質的な採用ベースが必要です。
  3. できれば、Python で作成する必要があります (2 番目の選択肢: JavaScript、3 番目の選択肢: それ以外!)。

これらの基準を満たすものが存在する場合、それが孤立する可能性は非常に低いことを認識しています. ほとんどの場合、それはより大きなシステムのコンポーネントになります。これで結構です。

注意: IMO、この投稿の残りの部分には、上記の質問に答えるために必要な情報は含まれていません。 この追加コンテンツは、回答する前に、この質問の出所を知りたい人のためにのみ含めています。ただし、議論の材料にすることを意図したもので はありません。それに対する返信はコメント セクションに限定してください。いずれにせよ、私の推定に反して、この補足コンテンツが SO にとって不適切であると判断された場合は、お知らせください。喜んで削除させていただきます。


この質問の背後にある動機を簡潔に (おそらく少しあいまいですが) 述べると、次のようになります。

私が現在実装しているライブラリによって追加された「認知的不協和」の量を最小限に抑えるためです。

もう少し詳しく言うと、私が言及している「認知的不協和」とは、確立された問題領域をモデル化する新しいソフトウェアのすべてによって導入されるもので、他の既存のものと「基本的に同等だが同一ではない」方法で行われます。同じ問題領域で動作するソフトウェア。このような「認知的不協和」には、確立された概念の新しい用語、または確立された用語の新しい意味、新しい慣習などが含まれます。

このような認知的不協和を最小限に抑える明白な方法は、既存の標準データ モデルの用語と規則を採用するという原則に固執することです。もちろん、この戦略は、そのような標準データ モデルが存在する場合にのみ成功、その普及率に比例する場合にのみ成功します。(少なくとも私の経験では、広く採用されているデータ モデルは比較的まれです。そのため、作成中のライブラリによって引き起こされる認知的不協和を完全に「回避」するのではなく、単に「最小化」することを目的としています。)

より具体的には、レイアウト情報を抽象的にエンコードして計算するという問題を容易にするために、小さな社内ライブラリに取り組んでいます。

このライブラリは依然として非常にシンプルですが、命名法、慣習、および全体的な構造に関して、ほとんど恣意的な選択をしなければならないことにすでに気付きました。たとえば、Python では次のようになります。

# EXAMPLE 1

from __future__ import division

class Box(object):
    def __init__(self, width, height):
        self.width = width
        self.height = height

def make_box(width, height, aspect_ratio=None):
    if aspect_ratio is not None:
        w = height * aspect_ratio
        if w < width:
            width = w
        else:
            height = width / aspect_ratio
    return Box(width, height)

この関数は、指定された幅と高さを持つ周囲のボックス内に収まるBox最大のオブジェクトを作成し、指定されている場合はアスペクト比を持ちます。aspect_ratio

(注: この投稿のすべてのコードは、実稼働レベルのコードの例としてではなく、説明のみを目的としています。したがって、エラー チェック、パフォーマンスの最適化、丸めエラーの処理などはありません。)

注意すべきことの 1 つは、この小さなおもちゃの例でも、「標準的な慣行」に準拠している場合と準拠していない場合があるいくつかの用語と規則を既に導入していることです。

  1. 「ボックス」、「幅」、「高さ」、および「アスペクト比」(「フレーム」、「デルタ_x」、「デルタ_y」、および「プロポーション」とは対照的に) という用語の選択。
  2. 比率としての「アスペクト比」の定義width/height(比率ではなくheight/width)。
  3. のような式における「幅」と「高さ」の「デフォルトの順序」Box(50, 100)
  4. aspect_ratioと の指定された組み合わせと指定された組み合わせがwidth一致しない場合を処理するためのポリシー(つまり、 andを、許可されている最小値ではなく、最大値としてheight解釈する)。widthheight

おそらく、問題は用語や、引数のデフォルトの順序などの単純な規則に限定されるものではありませんが、より広い範囲であっても、同様に規則の問題である設計上の決定にも及ぶでしょう。

この点を説明するために、Paddingクラスを使用してモデルを拡張し、関数を変更して、および引数で指定されたサイズよりも小さい可能性がmake_boxあるオブジェクトを返す代わりに、常に正確にそれらの次元を持ち、さらに を含む を返すことを想像してください。指定されたと指定された と の間の不一致をエンコードする属性。さらに、このような不一致がある場合は、残りのスペースをボックスの両側に均等に分割します (つまり、結果のパディングを対称にします)。(この説明のコード表現については、以下を参照してください。)BoxwidthheightBoxpaddingaspect_ratiowidthheightEXAMPLE 2

この小さな機能強化は、それ自体でさらに多くの用語と慣例を導入していますが、この小さな機能強化は、モデルの精緻化をすでに示しているという事実に焦点を当てたいと思います。それに加えて、この新しいタイプのオブジェクトと既存のもの (特に「ボックス」) との間の特定の (大部分は恣意的な) 関係があります。言い換えれば、この小さな機能強化は、ライブラリの残りの部分にグローバルに影響を与えるモデルの拡張を実際に意味します。私のライブラリが、デフォルトの順序付けなどのより狭い範囲のものだけでなく、そのような「グローバルな」構造規則にも準拠することを望みます。

確かに、これらの設計上の決定のいくつかは、「標準」と見なされる可能性のあるものと完全に一致するか、十分に一致する場合があります。さらに、この基準から逸脱したものはそれぞれ、将来のユーザーにわずかな認知的負担をもたらすだけです. 結局のところ、標準用語が「ボックス」の代わりに「フレーム」である場合、私のライブラリの (最終的な) ドキュメントを読んでいる人にとって、「ボックス」のすべての言及を精神的に「フレーム」に置き換えることは、それほど負担にならないでしょう。それでも総合的には、そして特に、他の多くの同様のライブラリが既に含まれている (そして典型的なプログラマーが使用しなければならない) "認知宇宙" では、それぞれが慣習からの独自の小さな逸脱を追加すると、その効果は負担になります。これらの変化する慣習は、新しいソフトウェアについて学ぶことを妨げます。これの特に具体的な兆候の 1 つはバグの形であり、そのうちのいくつかは見つけるのが非常に難しい場合があります。

すでに述べたように、このような認知的不協和をすべて解消できると期待するのは現実的ではありません。一つには、基準がありません。期待できる最善の方法は、混乱させるユーザーの数を最小限にすることですが、それでもこの数はかなりの数になります。さらに、非標準的な慣習や用語を意識的に採用することによる長期的な利益 (プログラマーの短期的な利便性とは対照的に) が、追加の認知的不協和を正当化する状況もあります。ケースは非常にまれです。


# EXAMPLE 2

from __future__ import division

class Padding(object):
    def __init__(self, top=0, right=0, bottom=0, left=0):
        self.top = top
        self.right = right
        self.bottom = bottom
        self.left = left

class Box(object):
    def __init__(self, width, height, padding=Padding()):
        self.width = width
        self.height = height
        self.padding = padding

def make_box(width, height, aspect_ratio=None):
    if aspect_ratio is None:
        return Box(width, height)
    else:
        w = height * aspect_ratio
        if w < width:
            p = (width - w)/2
            padding = Padding(left=p, right=p)
        else:
            h = width / aspect_ratio
            p = (height - h)/2
            padding = Padding(top=p, bottom=p)
        return Box(width, height, padding)
4

1 に答える 1