asatoの技術的な日常日記

「成長に最大の責任をもつ者は、本人であって組織ではない。自らと組織を成長させるためには何に集中すべきかを、自らに問わなければならない」  非営利組織の経営 - ピーター・ドラッカー

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

The Nature of Order

The Nature of Order」読み再開。

「全体性(wholeness)」の概念とか、「中心(center)」の概念とかなんとなくしかわからないけど、まあ、まあ、まあ、徐々に理解していこうじゃないか。

とりあえず、「中心は、中心のみからなる」とからしい。あるいは、中心は、中心のみから理解できるとか、定義されるとかっぽい。


もちろん、疑問は、ソフトウェアの観点から、アレクザンダーの話がどうかかわってくるのか、という点。

ソフトウェアにおける全体性とは? 中心とは? アーキテクチャにおける全体性とは? 中心とは? モジュラリティと全体性の関係は? 中心との関係は?

もしこれらの質問に答えることができるとするなら、ソフトウェア開発は、設計プロセスは、どう変わる?

スポンサーサイト

コード進化パターン:クラス階層の追加

うーん、一つ追加。

 Java におけるコード進化パターン

今回のは、なんかクラス追加するときに、そのクラスだけでなく、同時に interface も導入したくなる場合があるよね、という内容。

ある意味では、将来の機能追加を予測しているわけだから、余分なモジュールを追加しているとも考えられる。もし、予測通りになるのなら、まあ、interface を実装してクラス階層を成長させればいい。

でも、実際に機能追加があったときに、interface を導入するということも考えられる。そのときでもいいんじゃないか、ともいえる。

わかった、問題は、クラス階層にあるんじゃないのか。

そのクラスを使う側との依存を早いうちに緩和しようとしているのか。

interface を導入するのは、クラスを使う側と使われる側の抽象度の依存性を緩和すること にある気がした。再確認した。

実例は:

public interface GraphicObject {
public void draw(Graphics g);
}
public class DamageGraphic implements GraphicObject {

private Point loc;

public DamageGraphic(Point loc) {
this.loc = loc;
}

public void draw(Graphics g) {
g.drawString("100", loc.x, loc.y);
}
}

みたいな感じ。

GraphicObject を導入しない場合には、DamageGraphic を使うクラスは、この クラスの抽象度 で依存する。でも、GraphicObject を導入することで、この interface が 提供する抽象度 で依存するだけでいいことになる。

まあ、当たり前といえばあたりまえだけど、再確認。


つまり、クラス階層を一度に導入する理由は、二つの観点からの理由だといえる

  • 将来の起こるであろう予測している変更に備える
  • 物理的な依存関係は変わらないが、モジュール(クラス)間の抽象度の概念的な依存関係を削減する。

要求が変化する理由、デザインが変化する理由

成功する要求仕様 失敗する要求仕様」によれば、要求が変化する理由はこんな感じらしい。
-ステークホルダが要求文書をレビューする。何か新しいものへの欲求が引き出される。
-ステークホルダがシステムの使い方を覚える。何か新しいものへの欲求が引き出される。
-ステークホルダがプロトタイプを触ってみる。何か新しいものへの欲求が引き出される。
-システムが使われる状況が変わる。たとえば、ユーザ数が増えるなど。
-現在のシステムのバージョンを使っていると、顧客はシステムにさせたいことをさらに思いつく。

では、要求を実現するデザインのほうはどんな理由で変わる? Tokuda さんの博士論文である「Evolving Object-Oriented Designs with Refactorings」によれば、次のような理由から。
-機能性:新しい機能のサポート。既存の機能の変更。
-再利用性:他のアプリケーションで再利用できるようにする。
-拡張性:将来の拡張追加に備える
-保守性:再構成により保守のコストを削減する

また、デザインは、人間的側面の影響で変化する。
-経験:経験ある従業員は、彼らのドメイン知識をベースにより良い設計を作る可能性がある。
-新しい展望:新しいプロジェクトメンバーは、ある設計がどうやって構成されるのかついて異なるアイデアを持っていることがよくある。
-実験:適切な設計に達するには、異なる設計パスを探索することが要求されるかもしれない。


疑問は「要求の変化とデザインの変化の間の関係は?」

コンサーン進化

少しずつゲーム作成中。

今回の機能追加は、プレイヤーが攻撃したときの効果音。

ゲームを比較的まともに開発するのは初めてなので、あってるかどうかしらないけど、フレーム毎にゲームが更新されるように設計してる。

登録されたタスクが順番に処理されていく感じ。伝統的なタスクシステムとはちょっと(いい意味でも悪い意味でも)違うかもしれない。

とりあえず、なにはともあれ DSM (Design Structure Matrix) で分析してみる。
concern_evo


上の DSM が、効果音機能を付ける前で、下が付けたあと。

今回の DSM の拡張は、単に依存関係を「・」であらわす代わりに、継承関係を「E」で、コンサーンを実装する関係を「C」で書いてみた、ということ。

うーん、どう解釈すれば。。。


一つ思うのは、コンサーンにも種類があるのではないか、ということ。たとえば、「タスク管理」としているコンサーンは、もちろん、ユーザには関係のない項目。ユーザからすれば、ゲームがどのように設計されているかはどうでもいい。ということは「タスク管理」は、実装のコンサーン、あるいは、アーキテクチャレベルのコンサーンと呼ぶのが適切かもしれない。

もう一つは、移動・攻撃のアニメーション、あと、攻撃音のコンサーン間の関係。まずは、「攻撃アニメーション」と「攻撃音」の関係から考えてみたい。この二つの間に、なんらかの依存関係はあるだろうか。

concern_dep


「攻撃アニメーション」なしで、「攻撃音」はありえるだろうか。あるいは、「攻撃音」なしで「攻撃アニメーション」はありえるだろうか。前者はありえないとしても、後者はありえるかもしれない。たとえば、「移動アニメーション」には、「移動効果音」がなくてもいいとしている。フィーチャダイアグラムっぽく書けばこんな感じ。
feature_diagram



これを決めているのは、何か。仕様 だと思う。逆に言えば、仕様が変われば、コンサーン間の依存関係も変わるといえる。ということは、この仕様を、DSM の要素の一つとして考えることができるかもしれない。

spec_dsm

プログラミングの進歩


詰まるところ,ソフトウェア開発における本当の進歩は,プログラミングの進歩,すなわちプログラミング・テクニックにおける進歩に依存しているのです。

Jack W. Reeves - ソフトウェア設計とは何か?

では、取り組むべき課題は「どうやってその進歩を助長するか」だと思う。

どうやって、プログラミング言語は、あるいはそれに伴うプログラミング・テクニックは、進歩してきたのか?

何があれば進歩を助長できるのか?

一つのアプローチは、ベンチマーキング だと思う。ベンチマーキングは、ツールや手法を評価するためのエンピリカルな手法の一つ。詳しくは Sim のベンチマーキングの理論 を参照。

アスペクト指向デザイン: DI Aspect

ちゃんと分析できてないけど、書かないと忘れそうなので書く。

Dependency Injection (DI) とアスペクトの関係は?

学術的には、東工大の石川さんと千葉さんが論文を書いている。

 アスペクト指向プログラミングと Dependency Injection の融合

 Aspect-Oriented Programming beyond Dependency Injection

すでに彼らが分析しているのかもしれないけど、勉強のため考えてみる。


DI についての一般的な記事は、マーチンファウラさんの記事がある。

 Inversion of Control コンテナと Dependency Injection パターン


DI は基本的には、コンポーネント間の関係をどうやって管理するかに関するものだと思う。

Spring などのコンテナのやってることだけからいえば、コンポーネント間の関係を設定ファイルであらかじめて設定しておく。そして、そのファイルを基に、構成済み(依存性注入済み)のオブジェクトを取り出す。

Spring などの設定ファイルベースの DI は、一つのアプローチだと思う。もう一つのアプローチは、アスペクトを使うことだと思う。僕の後者の経験が少ないから、落とし穴にはまるかもしれないけど、考えてみる。

簡略化した実例から入ってみようと思う。Java でゲームを作っているとして、次のようなクラスがあるとする。


public class GameManager {
// ... ゲームの管理を行う。
// 現在のゲームの状態(タイトル画面、ゲーム中、ゲームオーバー)など。
}

public class AttackKeyHandler {

private Player player;
private GameManager gameManager;
private FPSManager fpsManager;
private KeyManager keyManager;

public AttackKeyHandler(Player player, FPSManager fpsManager, KeyManager keyManager) {
this.player = player;
this.gameManager = gameManager;
this.fpsManager = fpsManager;
this.keyManager = keyManager;
}

public void handle(KeyEvent e) {
// ... 攻撃のキーが押されたときの処理を行う
}
}



一つは、ゲームの管理を行うクラス。設計的には、このクラスは、ゲーム中に一つだけあると仮定して問題ない。

もう一つは、ユーザが攻撃のときのキーを押したときの処理を行う。この処理を行うためには、色々な管理クラスへのアクセスが必要だとする。

ここでの問題点は、コンストラクタの引数が比較的多いということ。もちろん、うまく設計されてないからこうなっているとも考えられる。たとえば、管理クラスを管理するもっと多きな管理クラスを作れば、引数の数は減る。

あるいは、GameManager や FPSManager のオブジェクトがゲーム中に一つだけ存在しているとするなら、これらのクラスに Singleton パターンを適用して handle メソッド内で、これらのクラスにアクセスするようにすればいいかもしれない。

とはいえ、テスト容易性の観点と経験から言うと、あまり容易に Singleton を適用するのは避けたい。

したがって、Spring などの DI のアプローチが思い浮かぶ。しかし、設定ファイルのアプローチは、ちょっと避けたい。理由の一つは、Spring の ApplicationContext を使って、設定済みのオブジェクト(この例では、AttackKeyHandler)を得るのがよさように思えない。


そこで、アスペクトを使えばどうかな、と考えてみる。たとえば次のようにする



@Injectable
public class AttackKeyHandler {

private Player player;
private @Injected GameManager gameManager;
private FPSManager fpsManager;
private KeyManager keyManager;

public AttackKeyHandler(Player player, FPSManager fpsManager, KeyManager keyManager) {
this.player = player;
this.fpsManager = fpsManager;
this.keyManager = keyManager;
}

public void handle(KeyEvent e) {
// ...
}
}



@Injectable と @Injected アノテーションを使って、どのフィールドが自動的に設定されるのかを指定している。

アスペクトのコードはこんな感じ。



public aspect DependencyInjection {

declare parents : (@Injectable *) implements InjectableType;
}

public aspect GameManagerDependencyInjection {

private GameManager gamaeManager; // 注入されるオブジェクト

// 注入を要求するオブジェクトが生成されたとき
after() returning(InjectableType o) : call( (@Injectable *).new(..) ) {
inject(o);
}

public void setGameManager(GameManager gamaeManager) {
this.gamaeManager = gamaeManager;
}

private void inject(InjectableType o) {

for(Field f : o.getClass().getDeclaredFields()) {

if ( f.isAnnotationPresent(Injected.class) ) {

if ( f.getType().isAssignableFrom(GameManager.class)) {

boolean access = f.isAccessible();
try {
f.setAccessible(true);
f.set(o, gamaeManager);

} catch(IllegalAccessException e) {

throw new DependencyInjectionException(e);
} finally {
f.setAccessible(access);
}
}
}
}
}
}
public class ....
private void initGame() {
// ... その他の初期化
GameManagerDependencyInjection.aspectOf().setGameManager(gameManager);
}
}



GameManagerDependencyInjection アスペクトは、最低限の動く実装しかしていないけど、ライブラリ化するならもっと一般化はできると思う。


利点は:
-設定ファイルのアプローチと比べて、比較的軽量。

欠点は:
-テストが容易でなくなるかもしれない。アスペクトとテスト容易性の関係は、まだまだ研究が必要な分野。

-コードの理解容易性の低下。AJDT などの アドバイスがどこに適用されているのかが分かる開発環境がないと、オブジェクト振る舞いが分かりにくいかもしれない。Spring などの場合は、ApplicationContext とかを使って設定済みのオブジェクトを得るので、DI しているってことが明示的だと思う。


欠点が多いように思えるけど、なぜかアスペクトのアプローチを今のところ採用してしまう現状。

コード進化パターン


 成長する全体は基本的で本質的な特徴をもっています。

 第一に、全体は、少しずつ成長していきます。

 第二に、全体は予測できません。成長が始まった時点では、それがどのように展開していくのか、どこで終わりをむかえるのかは、まだはっきりしないのです。なぜなら、全体それ自身の法則にしたがう成長の相互作用のみが、その継続と終わりを決めることができるからです。

 第三に、全体ははっきりとしたまとまりをもっています。真の全体は断片の集まりではなく、部分もまた全体を持っているのです。それは、夢の各部分のようにお互いに驚くべき複雑さでつながっています。

 第四に、全体は常に情熱に満ちています。というのも全体性それ自体が、私たちに働きかけ、心の底に届き、私たちの気持ちをゆり動かし、涙を誘ったり、幸せにしたりする力を持っているからです。

  「まちづくりの新しい理論」C. アレグザンダー

「コードの変化・進化には何らかのパターンがあるのか?」

このに回答すべく、二年前ぐらいから、少しずつパターンだと思われるものを抽出し、カタログ化しています。

 「Java におけるコード進化パターン

ここでの「パターン」の定義は、繰り返し発生するということです。進化のパターンとは、あるコードの状態に対して、何らかの要求変化に対応して、あるコードの状態に変化するということが繰り返し起こるということです。

ファウラーさんの「リファクタリングカタログ」は、そのような進化のパターンの例であると思います。

pattern.jpg


コードの進化のパターンの動機は、一つは、こうやってコードの変化を明示的に考えることがデザインについて学ぶことにつながると思うからです。

あるコードからあるコードへの変化は、何らかの変化によって引き起こされます。上の例では、コードの重複、つまり、getName/setName メソッドの重複をなくすことを動機に行わました。

リファクタリングの例からは、パターンがあることが分かると思います。

一方で、ありえないパターンを経験から推測することも可能であると思います。たとえば、java.util.Collections など static なメソッドのみを持ち、インスタンス化されることが意図されていないユーティリティクラスです。これらのクラスに対しては、interface を実装することになるような、変化のパターンは起こりません。したがって、(ちゃんと設計されているなら)Strategy パターンでいうところの Strategy の 役割を持つことはないのです

また、ユーティリティクラスに、static なメソッドが新たに追加される変化のパターンはあったとしても、通常のメソッドが追加されるような変化のパターンもありません。

このように考えると、あるコードに対して、起こりうる変化・起こりえない変化があることが分かると思います。現実世界における都市の成長の観点からいえば、まるで、ローソンのすぐ右隣にファミリーマートが建つことがないように、ソフトウェアにおいてもそのような変化・進化・成長のパターンがあるように思えます。リファクタリングは、この観点から言えば、全貌の一部しか捉えていないのではないしょうか。

したがって、コード進化のパターンのカタログ化の目的は、全貌をできるかぎり捉えようとすることです。

なぜか。

一つは、前述のように、学ぶためです。ソースコードを読むことで学ぶこともできます。しかし、棋士が棋譜から学ぶように、我々プログラマもある局面からある局面への変化から学ぶことがあるはずです。

もう一つは、単に学ぶだけでなく、考える材料になるためです。アスペクト指向などのモジュール化の考えは、従来のコードの進化のパターンを変化させます。再び将棋の例で言えば、もし、新しい駒が追加されたとしたら、あるいはルールが変わったとしたら、今までの定石や考えなどは、少なからず影響を受けます。ルールが変わったことにより、全貌は、デザインの指向・戦略は、どのように影響を受けたのか。そのような影響を調査するためには、従来の戦略がどうだったのかが知られれていると便利です。

アスペクト指向デザイン:BGMコンサーン

アスペクト指向プログラミングは、横断的なコンサーンをモジュール化することを目的としています。ここまでは一般的な話なので、情報元を示せ!とかやめて。


Java というか AspectJ でゲーム作ってるわけだけど、BGM って横断的コンサーンな気がした。さらに、フィーチャでもある気がする。

BGM なので、「タイトル画面」での曲とか、「ゲーム中」の曲とか、「
ゲームオーバー」の時の曲とか、そういうゲームの状態に依存して、鳴る曲が決まる。

フィーチャであるとは、たとえば、BGM がないゲームをリリースすることもあるかもしれない。まあ、オン・オフに切り替えるのが妥当だと思うけど。


以下は実例。オブジェクト指向の場合の実装を考えてないので、比較はまだできてない。


public class GameManager {

...

private GameMode gameMode = GameMode.OPENING;

public enum GameMode { OPENING, NORMAL, PLAYER_DOWN, GAME_OVER, ENDING };

public GameMode getGameMode() {
return gameMode;
}

public void setGameMode(GameMode gameMode) {
this.gameMode = gameMode;
}

....
}
public aspect MusicManagement {

...

// ゲームモードが変わったら、BGM変更
after(GameMode mode) :
args(mode) && set(GameMode GameManager.gameMode)
{

if (mode == GameMode.OPENING) {
// ... BGM 変更
}
else if (mode == GameMode.NORMAL) {
// ... BGM 変更
}
else {
// ...
}

}
...
}




ちゃんと分析はできてない(以下のコードはコンパイルすら検討してない)けど、通常のオブジェクト指向の考えだと、たとえば、
public void setGameMode(GameMode gameMode) {
this.gameMode = gameMode;
// ここでBGM変更
}
みたいになるんじゃないかと思う。

もっと GameManager と BGM のコンサーンを分離したいなら、リスナーor Observer を導入することになると思う。

  public void setGameMode(GameMode gameMode) {
   this.gameMode = gameMode;

   fireGameModeChanged(...); // リスナーに通知
  }

public class BGMManager implements GameModeListener {
 public void gameModeChanged() {
  // BGM 変更
 }
}

あるいは、XPI (Crosscutting Programming Interface) のアプローチ(PDF)っぽくすると

public aspect XGameModeChange {
 public pointcut change(mode) : args(mode) && set(GameMode GameManager.gameMode);
}
public aspect MusicManagement {
 after(GameMode mode) : XGameModeChange.change(mode) {
  // ...
 }
}
みたいになるきがする。

めんどくさいけど、いつものごとく DSM で一応確認してみる。
bgm


なかなか興味深い。

アスペクト指向デザイン

あるオブジェクトは、デフォルトの状態を持つとします。でも、できるなら、状態の初期値は、アプリケーションに依存せずに設定したい。アスペクトは、役立つかな?

実際の例:


public class Enemy extends AbstractMapCharacter implements FrameListener {

....

private EnemyProperty property = new EnemyProperty();

public Enemy() { }

...
}

public class EnemyProperty {

private List<Class<? extends MapObject>> movableMapObjects = new ArrayList<Class<? extends MapObject>>();
private List<Class<? extends MapObject>> unmovableMapObjects = new ArrayList<Class<? extends MapObject>>();

public EnemyProperty() {

movableMapObjects.add(Floor.class);

unmovableMapObjects.add(Player.class);
unmovableMapObjects.add(Enemy.class);
}
...
}


この EnemyProperty クラスのコンストラクタでは、Enemy オブジェクトが移動できる対象を決めている。でも、できるなら、こういうコードは外で設定したい。でも、外で設定するとなると、オブジェクトを作るたびに初期化コードを呼ばないといけない。

典型的な解決策は、たぶん、Factory クラスを作って、デフォルトの設定をされたオブジェクトを作って返すことだと思う。


public class EnemyPropertyFactory {

public EnemyProperty createDefaultProperty() {

EnemyProperty property = new EnemyProperty();

property.addMovableMapObject(Floor.class);

property.addUnmovableMapObject(Player.class);
property.addUnmovableMapObject(Enemy.class);

return property;
}
}

public class Enemy extends AbstractMapCharacter implements FrameListener {

....

private EnemyProperty property = EnemyPropertyFactory.createDefaultProperty();

public Enemy() { }

...
}


以下は、アスペクト的解決策:


public class EnemyProperty {

...

public EnemyProperty() { }

...
}

public aspect EnemyPropertyDefaultInitialization {

after(EnemyProperty property) : this(property) && execution( EnemyProperty.new(..)) {

property.addMovableMapObject(Floor.class);

property.addUnmovableMapObject(Player.class);
property.addUnmovableMapObject(Enemy.class);
}
}



このアスペクトでは after アドバイスでコンストラクタをインターセプトして、初期状態を設定している。

以下は、上記の3つのアプローチの DSM。
enemy_before_dsm

enemy_before2_dsm

enemy_after_dsm


依存の粒度、DSM、XPI などなど

アノテーションつかって、アドバイスが適用される側のコードとアスペクト側のコードの依存を軽減できる?

たとえば、実際の例:

before:
public aspect RoomBoundsChecking {

before(Room room, int x, int y) :
args(*, x, y) && this(room) && execution(void setMapCharactor(..))
{
if (x >= room.getWidth() || y >= room.getHeight() ) {
throw new IllegalArgumentException("x >= getWidth() || y >= getHeight()");
}
}
}
public class Room {
....
public void setMapCharactor(MapCharactor chara, int x, int y) {

chara.setLocation( toAbsoluteLocation(x, y) );

charactors.put(new Point(x, y), chara);
}
...
}
after:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface BoundsCheck { }


public aspect RoomBoundsChecking {

before(Room room, int x, int y) :
args(*, x, y) && this(room) &&
execution(@BoundsCheck * Room.*(..))
{
if (x >= room.getWidth() || y >= room.getHeight() ) {
throw new IllegalArgumentException("x >= getWidth() || y >= getHeight()");
}
}
}
public class Room {
....
@BoundsCheck
public void setMapCharactor(MapCharactor chara, int x, int y) {

chara.setLocation( toAbsoluteLocation(x, y) );

charactors.put(new Point(x, y), chara);
}
...
}


あと、数分で適当に考えた DSM (Design Structure Matrix):

dsm1

dsm2




色々疑問とか思ったこと:

  • アノテーションってデザインルール or XPI になってる?
  • 依存の粒度って重要かも。メソッドのシグニチャとかメソッド内部の実装とか
  • DSM のツールってどこかにないの? 手書きでやるのめんどくさい


関連しそうな文献:
Gregor Kiczales and Mira Mezini
Separation of Concerns with Procedures, Annotations, Advice and Pointcuts
European Conference on Object-Oriented Programming (ECOOP), Springer LNCS, 2005
http://www.st.informatik.tu-darmstadt.de/public/Publications.jsp


William Griswold, Kevin Sullivan, Yuanyuan Song, Macneil Shonle, Nishit Tewari, Yuanfang Cai, Hridesh Rajan,
"Modular Software Design with Crosscutting Interfaces",
IEEE Software, Special Issue on Aspect-Oriented Programming, Jan/Feb 2006.
http://www.cs.iastate.edu/~hridesh/research.shtml

フィーチャと実装

ユーザに見える機能をサービス、あるいは、フィーチャと呼ぶとして、実装してるときに、どのフィーチャに関する実装を取り扱っているのか、ってのを意識するだろうか?

feature


少なくとも、僕は、あんまり意識していないことが分かった。

そもそも、フィーチャのもっと厳密な定義は? R.E. Lopez-Herrejon さんの博士論文の「Understanding Feature Modularity [PDF]」にいくつかフィーチャの定義が列挙されてる:

  • End-user visible characteristics of a system [85].
  • A distinguishable characteristic of a concept that is relevant to some stake-holder
    [85].
  • Qualitative properties of concepts [51].
  • A functional requirement; a reusable product line requirement or characteristic. A requirement or characteristic that is provided by one or more members of a software product line [68].
  • Increment in program functionality [162].


僕は、一番最初の定義を意識していた。

本日のレッドライン: 部分最適化 vs. 全体最適化

重要だと思ったところに、赤線を付ける習慣が身についてきた。


日経ビジネス10.30号の記事「物流軽んじる企業は滅ぶ」より。
-----
「物流というものは、常に部分最適を排し、全体最適を考えない限り決してうまくいきません。」

 by 水嶋 康雅 氏(多摩大学ロジスティクス 経営・戦略研究所 所長兼教授、元ソニー上席常務)
-----

同じようなこともドラッカーが言っている。
-----
 ミサイルの官制システムのように機械的なものであれ、樹木といった生命システムであれ、企業のような社会システムであれ、あらゆるシステムに共通するものこそ「相互依存性」なのである。

とはいえ、システムの特定の機能やある部分が改善されたり、効率化されたりしても、必ずしもシステム全体がよくなるわけではない。

実際、部分の改善によって、そのシステムそのものに欠陥が生じたり、あるいは破壊されたりする場合すらある。逆に、全体を強化するための最善手が、ある特定の部分の機能低下を招く場合がある。

 システムにおいて重要なのは、全体の動きである。それは、システム全体の成長、バランス、調整、統合の結果であって、部分の効率をテクニカルに向上させた結果ではないのである、

 P.F. ドラッカー経営論「経営科学の罠」
-----


ドラッカーのは、経営科学に対する批判だけど、じゃあ、ソフトウェア工学ではどうだろう。

部分最適化を目指してないだろうか。進化・成長を妨げるような部分的なデザインの最適化を目指していないだろうか。

Code Reading

Code Reading」を前のほうだけ読んだ。ちなみに、原書しかもってないので原書。翻訳書も安ければ買いたい。

ちょっと思ってたより「コード」だけの話じゃない感じ。デザインの話とか、アーキテクチャの話とかも触れてないわけじゃないので。

そもそも、出発地点が大切だと思った。いきなりだけど、「Design Reading」の名前付けは間違ったかも。僕の興味あるのは、デザインを学ぶには、ソースコードからだけで十分なのか。他の補助的な方法もあるんじゃないか。そもそもデザインを学ぶとは何か、だと再認識。

Design Reading, Part 1: 前準備

Code Reading」という本があるけど(まだちゃんと読んでない)、じゃあ、Design Reading とかはどう?

そもそも、デザインとコードの違いは? Code Reading は、Design Reading と同じか? 違うとしたらその違いは何?
code_vs_design


ここでは「Design ReadingとCode Readingは、似ているが違う点もある」という仮説の基で議論していきたいと思う。図でいえば、(a)、(b)、(c) のどれかに対応する。

まず、プロセスとプロダクトでコードをデザインを区別したい。
process_product


次に、Code Reading と Design Reading のモデルを考えてみた。
model


途中でモデルが変わることがあるかもしれないけど、このモデルを基に考えていきたいと思う。

モデルの説明などの詳細はまた今度。

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。