ニューラルネットワーク型コンピューティングに向けたプログラムデザインについて
たまたまIBMが脱ノイマン型CPUを作ったというニュースを見て、いよいよ始まったかという気持ちになった。
でもPICのハーバード・アーキテクチャだとかPLCのサイクルコンピュータなど色々あり、これらも含めて
考え方のスケールを1つ上げて見ると、ニューラルネットワーク型CPUもノイマン型の派生品となるだろう。
さらに2015年6月1日にインテルはアルテラ社を買収したという事から、今後どういうコンピュータが生まれるかが想像できる。
インテルはCPU(ノイマン型)、アルテラはFPGA(ステートマシン型)、合わせるとサイプレス社のPSoC(ノイマン型+GALロジック)と似たものができる。
IBMはCPU設計のデザインを新しいニューロン型(ステートマシン型)にしたのに対して、インテルはハイブリッド路線に舵を切ったといえる。
インテルの場合は既存の資源が流用できる構図で進化するが、IBMは今までと違う進化なので下位互換は無いと思える。
そこでIBMのCPUが登場した時、プログラムはどういうアプローチになるのかを考えてみた。
ニューラルネットワークとは
https://ja.wikipedia.org/wiki/%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%A9%E3%83%AB%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF
簡単に言えば、人間のニューロンが数億個繋がったものを差す。
ニューロンは、1個の外部入力がありN個の値が異なる外部出力を行うもの。
当然ノイマン型でもコンピュータ5大要素で説明ができる。(それくらい影響力が強い)
プログラムデザインはどうなるのか
今回みた記事によると100万ニューロンがCPUになったというだけで、プログラミングはどういった手法で行うのかは書かれていない。
ここからは推測だが、PLCみたくラダーでステートマシンで表現する方法になるんじゃないだろうか。
ニューラルネットワークの解釈
ニューロンが1入力N出力であることから、それらを繋がったニューラルネットワーク自体も巨大な1入力N出力の塊であるといえるので、ニューラルネットワークは1つのニューロンと同等といえる。
内部構造は木構造で互いに接続しあう感じになり、ある入力からある出力までを1本道にして見た時、それはラダー図で表される。
ラダー図だとリレーのON/OFFしか情報がないから、カメラ画像を入力した時、出力結果は?って思う人もいるだろう。
そこはオブジェクト思考を取りいれて考えてみて欲しい。
リレーのON/OFFを1つのオブジェクトだとすると、カメラ画像も1つのオブジェクト。つまりラダー図で描かれているが流れてくるデータはオブジェクトである。
つまりプログラマが実装する場合は、ステートマシンで実装で完結する。
もし機械学習(パターンマッチング)を視野に入れた場合、すべての組み合わせの中から最適解を見つける事になるので、
すべての事象を含めた入力値を与えて、パラメータの最適値を見つけさせて、結果を出力させる、ということになる。
ここで1つポイントになるのが、しきい値。入力値に対して、条件式があってしきい値で分岐する。
これが階層Nを持ち、最終段で結果を得るとされるのだが、プログラム的に見て適正値であるかなんて判断が付かない。
どうすればいいか、インテルが買収したアルテラ社を思い出して欲しい。
フリップフロップ回路を構成する、AND、OR、NOT、NOR、NAND回路を登場させてみよう。
ロジック回路の最適解を求める方法は既存技術で利用されているものである。
入力値とパラメータのテーブルがあって、出力側に正解となる教師データを設定できる。
入力値は操作できないにしても、教師データ入力して、出力結果を人手で設定して正解を導いてあげることで、パラメータが確立され、ロジックを形成することができる。
インテルのアプローチを考えると、入力値には外部入出力の結果をすべてプロパティで表現できるモデル構造を構築しておくことで
教師データで得られたニューラルネットワークのロジック回路をCPUに内蔵したFPGA書いて、条件判断をさせ結果を書き込む。こういった事が考えられる。
インテル:CPU+FPGA方式
既存のプログラミング+FPGAで条件判断を専用ロジック化(数千クロックかかった処理を1クロックで結果出力に導くので超高速化が得られる)
void FPGA(Model);
FPGA内部には入力値パラメータと教師データで得られたロジック回路が入っている条件判断部
Modelにはプロパティには外部入出力と条件判断で使用するパラメータ。
IBM方式:PLC的なステートマシンで構築。
すべてのプログラムがケースツールで表現できるようになって、CPU自身が仮想の専用回路となるため、すべての動作が快適になる。
まとめると、 既存のノイマン式はあらゆる事が自在にできる構造だったが、
言語の進化と共にハードウェアを抽象化してプログラマが直接操作できないようになってオーバーヘッドが生じていくらCPUが早くなっても速度が変わらない問題が発生している。
そこでGPCPUのように単純な演算は専用回路でやった方が早い、そんなアプローチが出始めてきた現在、その延長線上に今回のIBMやインテルの技術の進化がある。
どのように進化するかといえば、原点回帰ともいえるハードウェアに近いレイヤーでプログラミングするという手法になっていくと考えられる。
実現方法はまだ模索している段階で、ビジネスとして成功する鍵は速度はもちろん既存技術が流用できるかである。
インテルは既存技術の組み合わせで、汎用CPUと専用ロジックのハイブリッドで高速化。
順当な進化ともいえる。
IBMはCPUの構造に手を加えて、条件命令と外部入出力をまとめたモデルオブジェクト用の宣言命令だけになって、ノイマンの無限のチューリングマシンから
CPUサイズによってできる事が決まる有限のチューリングマシンになって、今のCPUでいうスレッド数だとかメニーコアの概念から外れてGPUみたく処理ユニット数(ニューロン数)で数えられるようになるんじゃなかろうか。
既存技術からはだいぶ離れた位置に存在していて、x86からx64へ以降した以上の摩擦が生じることだろう。
ただし、こういった考えはCPUに役目を与えていくプラグイン方式なので、汎用OSの役目はモデルのタスクマネージャーとコンパネでモデルオブジェクトの管理とGUI環境、つまり今と見た目は変わらないけどCPUアーキテクチャは進化を遂げてることができる。
どちらも共通することは外部入出力の扱い方で、すべての事象をまとめたモデルを宣言し、入力値とすることで、教師データによって入力・出力値のテーブルが構築でき、機械的にロジックの最適解を求めていく、またはロジックを書いていく構造になるんだろう。
インターネット上にある断片化された情報を切り取って、リブログする。 主にソフトウェア、Ubuntu関連、CPUなど気になったニュース、また、日々の面白い出来事やニュースもリブログします。
2015年6月21日日曜日
2015年6月15日月曜日
[C#]Mixinの表現方法
色んなやり方があるけど、privateメソッドまですべてを自由に使えるというのでこういう方法はありなのかと思って書いたメモ。
イメージは、1つのモデルオブジェクトに対して、Aさん、Bさん、Cさん不特定多数の使い方(インターフェイス)を用意する。
つまり、ダイソー商品をDIY目的で本来の使い方をしない人向けの別インターフェイスを設ける、というような感じ。
using test1;
public class Hello{
public static void Main(){
// Here your code !
var test = new test();
var t1 = (ITest1)test;
var t2 = (ITest2)test;
var t3 = (ITest3)test;
t1.Hello();
t2.World();
t3.Hello();
t3.World();
}
}
namespace test1
{
using System;
interface ITest1
{
void Hello();
}
interface ITest2
{
void World();
}
interface ITest3
{
void Hello();
void World();
}
public partial class test
{
private void Print(string message)
{
Console.WriteLine(message);
}
}
public partial class test : ITest1
{
#region ITest1 メンバー
public void Hello()
{
this.Print("Hello");
}
#endregion
}
public partial class test : ITest2
{
#region ITest2 メンバー
public void World()
{
this.Print("World");
}
#endregion
}
public partial class test : ITest3
{
#region ITest3 メンバー
void ITest3.Hello()
{
this.Print("Hello2"); //ITest1とは別のHelloとなる
}
void ITest3.World()
{
this.World(); //ITest2のWorldが呼ばれる
}
#endregion
}
}
イメージは、1つのモデルオブジェクトに対して、Aさん、Bさん、Cさん不特定多数の使い方(インターフェイス)を用意する。
つまり、ダイソー商品をDIY目的で本来の使い方をしない人向けの別インターフェイスを設ける、というような感じ。
using test1;
public class Hello{
public static void Main(){
// Here your code !
var test = new test();
var t1 = (ITest1)test;
var t2 = (ITest2)test;
var t3 = (ITest3)test;
t1.Hello();
t2.World();
t3.Hello();
t3.World();
}
}
namespace test1
{
using System;
interface ITest1
{
void Hello();
}
interface ITest2
{
void World();
}
interface ITest3
{
void Hello();
void World();
}
public partial class test
{
private void Print(string message)
{
Console.WriteLine(message);
}
}
public partial class test : ITest1
{
#region ITest1 メンバー
public void Hello()
{
this.Print("Hello");
}
#endregion
}
public partial class test : ITest2
{
#region ITest2 メンバー
public void World()
{
this.Print("World");
}
#endregion
}
public partial class test : ITest3
{
#region ITest3 メンバー
void ITest3.Hello()
{
this.Print("Hello2"); //ITest1とは別のHelloとなる
}
void ITest3.World()
{
this.World(); //ITest2のWorldが呼ばれる
}
#endregion
}
}
2015年6月14日日曜日
オブジェクト指向からコンポーネント思考へ
「オブジェクト指向」と検索してざざっとでてくる用語。
「カプセル化」「多態性」「再利用」「リファクタリング」「プロトタイプベースオブジェクト指向」「クラスベースオブジェクト指向」「振る舞い」「UML」「抽象化」「デザインパターン」
上記のようないろんな用語以外にも良くわからない技術で表現していたりして不明瞭さたっぷりです。
つまりオブジェクト指向とは万人が同じ答えにならない、「不明瞭」な物を扱っている覚悟をしておく必要があります。
工業製品としてソフトウェアを作るなら誰もがある一定上の同じモノができるようにモノサシやテンプレートが必要になると思います。
そこで古くからあるコンポーネント思考の導入の始まりです。
ソフトウェアの「職人技、一品物」から「工業製品、量産品」のように扱える、そんなやり方を説明していきます。
~~~~~~~~~~~~~~~~~~
まずはおさらい、オブジェクト指向について
要点だけをまとめると、
・オブジェクト指向とは、オブジェクトを表現するものがクラスであること。
クラスがオブジェクトを表現するんじゃなく、本質は逆なのです。
例えば、目の前にある人物像のデッサンする場合、
目の前にあるのがオブジェクトであって、キャンバスに描くのがクラスです。
クラスを作ってから目の前のオブジェクトは作れないんです。
「鳥取は島根の隣」と同じ次元では無いことがわかったでしょうか。
補足するとデザインパターンにFactoryパターンというがあるのですが、命名した人は根本的な間違えに気づいてないと思います。
・インスタンスとは、元は図形をコピーするという意味。
現在の言語仕様にあてはめるとクラス(設計図)のコピーにあたる。生成物ではない。
オブジェクトは生成じゃなく、複製だからです。
目の前にあったオブジェクト(人物像)をキャンバス(クラス)に描いて出来たものがオブジェクトなので、生成じゃなく複製が正しい表現となります。
・オブジェクト指向には多態性と振る舞いは不要。
オブジェクト思考のメリットで騒がれてる事はすべて投げ捨ててしまいましょう。
これらは後付の理由なので本質を知る上では不要です。
そうすることでオブジェクトそのものをクラスに表現できるようになります。
オブジェクトをクラスに表したものをModelクラスと呼んでいます。
例
----
class PenModel
{
//ペンに関する関心のあるプロパティを記述。
public int Length { get; set; }
public Color Color { get; set; }
//最初はメソッドは用意しない
//メソッド追加する場合は、オブジェクトの変化を与えるメソッドであって振る舞いでは無い。
//振る舞い=イベントなので動的、状態変化は静的、同じ用に見えて異なるからです。
//これはOK
public void ChangeColor(Color newColor)
{
this.Color = newColor;
}
//これはNG、後で説明するが、直感的な動詞はController向けの名称
public void Write(int count)
{
this.Length -= count;
}
//これはOK
public void DecLength(int count)
{
this.Length -= count;
}
}
----
class Main
{
public static void Main()
{
//求めているペンを生成する
var blackPen = new Pen { Length = 10, Color = Color.Black };
var redPen = new Pen { Length = 10, Color = Color.Red };
}
}
----
私はMVCフレームワークの影響を受けてしまっているのでModel部分のメソッド定義はController側に分離してしまっているのでそうなっています。
そうすることで、オブジェクトの本来の性質が表に出て分かりやすいと思うし、値の検証もしやすさと多態性の表現をControllerで表せれる点など思うことは沢山あります。
まあ独自の書き方ですが、
class Model
{
...(関心のあるプロパティと変化メソッド)
}
//多態性はコントローラクラスで分けて表現
//同じ動作する関数が増えていくのがキライって方はModelクラスをpartialしてインターフェイスで分けて
//内部情報の書き換えはPrivateにする事で解決します。
//(オブジェクト単体で見るとすべて丸見えだけど、インターフェイス経由なら制限できるので)
//ちなみにControllerクラスには操作するModel以外の内部変数は極力作らない事です。
class Controller1
{
Model model;
public Controller1(Model model)
{
this.model = model;
}
public void Write(string message)
{
Console.WriteLine(message);
model.DecLength(message.Length);
}
}
class Controller2
{
Model model;
public Controller2(Model model)
{
this.model = model;
}
public void ChangeColor(Color newColor)
{
this.model.ChangeColor(newColor);
}
}
雰囲気だけは伝わったかと思います。
あとは何回か書くと理解が進むんじゃないかな。
再利用についてはコンポーネント指向の回で説明します。
○オブジェクト指向の設計手法
オブジェクトの表現について理解できたならば、
次はオブジェクト設計ですが、
間違えやすいポイントを最初に持ってくると、基本的な考え方は
対象となるオブジェクト同士の関係が
1:1, 1:N, N:1, N:N
であるかがポイントになります。
例えて男女関係と見立てると複雑度が分かりやすいです。
1:1の関係はごく普通。
1:N、N:1の関係はおや?ってなりますね。ここは何とかしなくてはなりません。
プログラム的にいえばModelクラスを複数束ねるCollectionクラスを用意するなどです。
N:Nはもはや分かりません。
つまりオブジェクト設計とは
1:1の関係に持っていく作業です。
設計の仕方は仕様の元となるクライアントとヒアリングして
ざっくりと全体図を書きます。
プログラムとは自動化するのが本来の目的なので
現状、人手でやることをすべて表すことと関係する役者をすべて並べること作業の事です。
これらをユースケース図を使って書きます。
全部書き表したらよく言われる「汎化」作業に入るのですが、ここで注意ポイント
勝手に減らしたりくっつけたりしない事、です。
オブジェクト指向の説明でデッサンの例のように
聞いた内容=オブジェクト
なので、それをユースケース図で書き表すのが作業です。
勝手にアレンジを加えるのはNG、提案はOKですが仕様の構造を変えるような提案はNGです。
現状をそのまま書き表して確認する、これが重要であるからです。
なぜそこまでして現状そのままに書き表すのかというと
現実と1:1で合わせておくことで「実はこうだった」など後出しの変更に強いからです。
ユースケース図を描いてN:Nの箇所があれば、ヒアリングして別の担当者になる人を探したりする作業も
オブジェクト設計のうちの1つになります。
この時点でなるべく1:1になるようにするのが設計の最適化。
もしNのオブジェクトで違う作業があるなら再度ヒアリングして分割できるかチェック、
だめならばプログラム上、多態性で表現することになります(←これが後々の問題の種になる事を承知の上でね。)
もちろんユースケース図に間違いがあった場合、仕様バグなので論外です。
-------------
ここまでで
オブジェクト指向とは、オブジェクト設計と実装方法について説明しました。
ここからコンポーネント指向についてを述べていきます。
おなじみとなったVB、C#の開発環境でデザイナー画面にアイテムを設置していくだけでプログラムが出来てしまう
あれがコンポーネント指向です。アイテムはコンポーネントと呼ばれているので気づいた方はいるんじゃないでしょうか。
あの機能はDelphiが元になっていて、MSが開発者を引き抜いたりお金の力で出来たのが今のVisualStudioとC#言語仕様になります。
http://ja.wikipedia.org/wiki/Visual_Component_Library
VLCの基本構造は最下層になるTObjectクラスがあって派生でトップに立ったものがコンポーネント、いわゆるソフトウェア部品・モジュールとなります。
底のオブジェクトがあって最上位になっていくほど高機能になっていく構造です。
車輪の再開発ですが、これをプログラムで表現しようという試みです。
全体ブロック図
+--------------------+----
| 業務画面 |
+--------------------+ ビジネス領域(フォーム画面に部品ペタペタ、イベント広げて処理書いたり、、)
| ビジネスロジック |
+---------+----------+----
| Library | | コンポーネント部品(.NETから派生するのでこの位置をキープ)
+---------+ |
| .NET |
+--------------------+----
今回着目する箇所はLibraryと書かれている部分です。
Libraryのブロック図
+--------------------+---
|Controller | 共通操作
| | Modelクラスには、Driverモデルと共通パラメータ、共通操作
+--------------------+---
|Driver(Model) | プロトコルレイヤー(外部と通信プロトコル(コマンド)で操作を行う)
| | Modelクラスには、通信仕様上で必要になるパラメータ(IDなど)、コマンドメソッド
+--------------------+---
|外部IO(Model) | 外部入出力レイヤー(シリアルポート、ファイル、TCP/IP 通信を行う)
| | Modelクラスには、ポート初期化パラメータ、Open/Close/Read/Write
+--------------------+---
こんな具合でしょうか。
大体は外部と通信するのでオブジェクトの体は通信インターフェイスにします。
その上に相手とのコミュニケーションする電文の作成・解析が必要になってきて
さらに上になると判断してコミュニケーションする頭脳という具合ですかね。
IOが足回り、Driverが手足、Controllerが頭脳、こうなります。
例でいうとTCP/IPで相手と通信する場合、通信仕様が必要になるので、先ほどのブロック図に当てはめていけばコンポーネントの完成。
つまり再利用を重視した構造であるということになります。
使うユーザーは最初に書いたとおり、VisualStudioを操作して画面に部品を設置するだけでプロパティウィンドウに書かれたプロパティを設定していくと
通信仕様とは一切知らなくても通信プログラムが完成します。
こういった部品を沢山作って行くことで
画面と状態遷移とビジネスロジックをプログラムにする作業に集中できるようになります。
大規模になってもオブジェクト指向で設計をがんばってもらって
足りないコンポーネントは作って、
ビジネスロジックと1:1で向き合える大きさまで派生させて、
画面単位にコンポーネントをくっつけて、
イベント広げて処理を書いてビジネスロジックを動かす、
画面遷移するなら遷移する、終了するなら終了で。
そんな作業の流れができてくればコーディング量も減って品質の向上につながるのではないでしょうか。
色々書いてきましたが、
オブジェクト指向は設計用で実装用ではないです。
設計と実装を1:1にするのもありですが、上記作業なら無理して合わせる必要もないですね。
ここでの注意ポイントはビジネスロジックにパラメータは持たない事です。
以上、思考の整理とともに長々と書いてみました。
「カプセル化」「多態性」「再利用」「リファクタリング」「プロトタイプベースオブジェクト指向」「クラスベースオブジェクト指向」「振る舞い」「UML」「抽象化」「デザインパターン」
上記のようないろんな用語以外にも良くわからない技術で表現していたりして不明瞭さたっぷりです。
つまりオブジェクト指向とは万人が同じ答えにならない、「不明瞭」な物を扱っている覚悟をしておく必要があります。
工業製品としてソフトウェアを作るなら誰もがある一定上の同じモノができるようにモノサシやテンプレートが必要になると思います。
そこで古くからあるコンポーネント思考の導入の始まりです。
ソフトウェアの「職人技、一品物」から「工業製品、量産品」のように扱える、そんなやり方を説明していきます。
~~~~~~~~~~~~~~~~~~
まずはおさらい、オブジェクト指向について
要点だけをまとめると、
・オブジェクト指向とは、オブジェクトを表現するものがクラスであること。
クラスがオブジェクトを表現するんじゃなく、本質は逆なのです。
例えば、目の前にある人物像のデッサンする場合、
目の前にあるのがオブジェクトであって、キャンバスに描くのがクラスです。
クラスを作ってから目の前のオブジェクトは作れないんです。
「鳥取は島根の隣」と同じ次元では無いことがわかったでしょうか。
補足するとデザインパターンにFactoryパターンというがあるのですが、命名した人は根本的な間違えに気づいてないと思います。
・インスタンスとは、元は図形をコピーするという意味。
現在の言語仕様にあてはめるとクラス(設計図)のコピーにあたる。生成物ではない。
オブジェクトは生成じゃなく、複製だからです。
目の前にあったオブジェクト(人物像)をキャンバス(クラス)に描いて出来たものがオブジェクトなので、生成じゃなく複製が正しい表現となります。
・オブジェクト指向には多態性と振る舞いは不要。
オブジェクト思考のメリットで騒がれてる事はすべて投げ捨ててしまいましょう。
これらは後付の理由なので本質を知る上では不要です。
そうすることでオブジェクトそのものをクラスに表現できるようになります。
オブジェクトをクラスに表したものをModelクラスと呼んでいます。
例
----
class PenModel
{
//ペンに関する関心のあるプロパティを記述。
public int Length { get; set; }
public Color Color { get; set; }
//最初はメソッドは用意しない
//メソッド追加する場合は、オブジェクトの変化を与えるメソッドであって振る舞いでは無い。
//振る舞い=イベントなので動的、状態変化は静的、同じ用に見えて異なるからです。
//これはOK
public void ChangeColor(Color newColor)
{
this.Color = newColor;
}
//これはNG、後で説明するが、直感的な動詞はController向けの名称
public void Write(int count)
{
this.Length -= count;
}
//これはOK
public void DecLength(int count)
{
this.Length -= count;
}
}
----
class Main
{
public static void Main()
{
//求めているペンを生成する
var blackPen = new Pen { Length = 10, Color = Color.Black };
var redPen = new Pen { Length = 10, Color = Color.Red };
}
}
----
私はMVCフレームワークの影響を受けてしまっているのでModel部分のメソッド定義はController側に分離してしまっているのでそうなっています。
そうすることで、オブジェクトの本来の性質が表に出て分かりやすいと思うし、値の検証もしやすさと多態性の表現をControllerで表せれる点など思うことは沢山あります。
まあ独自の書き方ですが、
class Model
{
...(関心のあるプロパティと変化メソッド)
}
//多態性はコントローラクラスで分けて表現
//同じ動作する関数が増えていくのがキライって方はModelクラスをpartialしてインターフェイスで分けて
//内部情報の書き換えはPrivateにする事で解決します。
//(オブジェクト単体で見るとすべて丸見えだけど、インターフェイス経由なら制限できるので)
//ちなみにControllerクラスには操作するModel以外の内部変数は極力作らない事です。
class Controller1
{
Model model;
public Controller1(Model model)
{
this.model = model;
}
public void Write(string message)
{
Console.WriteLine(message);
model.DecLength(message.Length);
}
}
class Controller2
{
Model model;
public Controller2(Model model)
{
this.model = model;
}
public void ChangeColor(Color newColor)
{
this.model.ChangeColor(newColor);
}
}
雰囲気だけは伝わったかと思います。
あとは何回か書くと理解が進むんじゃないかな。
再利用についてはコンポーネント指向の回で説明します。
○オブジェクト指向の設計手法
オブジェクトの表現について理解できたならば、
次はオブジェクト設計ですが、
間違えやすいポイントを最初に持ってくると、基本的な考え方は
対象となるオブジェクト同士の関係が
1:1, 1:N, N:1, N:N
であるかがポイントになります。
例えて男女関係と見立てると複雑度が分かりやすいです。
1:1の関係はごく普通。
1:N、N:1の関係はおや?ってなりますね。ここは何とかしなくてはなりません。
プログラム的にいえばModelクラスを複数束ねるCollectionクラスを用意するなどです。
N:Nはもはや分かりません。
つまりオブジェクト設計とは
1:1の関係に持っていく作業です。
設計の仕方は仕様の元となるクライアントとヒアリングして
ざっくりと全体図を書きます。
プログラムとは自動化するのが本来の目的なので
現状、人手でやることをすべて表すことと関係する役者をすべて並べること作業の事です。
これらをユースケース図を使って書きます。
全部書き表したらよく言われる「汎化」作業に入るのですが、ここで注意ポイント
勝手に減らしたりくっつけたりしない事、です。
オブジェクト指向の説明でデッサンの例のように
聞いた内容=オブジェクト
なので、それをユースケース図で書き表すのが作業です。
勝手にアレンジを加えるのはNG、提案はOKですが仕様の構造を変えるような提案はNGです。
現状をそのまま書き表して確認する、これが重要であるからです。
なぜそこまでして現状そのままに書き表すのかというと
現実と1:1で合わせておくことで「実はこうだった」など後出しの変更に強いからです。
ユースケース図を描いてN:Nの箇所があれば、ヒアリングして別の担当者になる人を探したりする作業も
オブジェクト設計のうちの1つになります。
この時点でなるべく1:1になるようにするのが設計の最適化。
もしNのオブジェクトで違う作業があるなら再度ヒアリングして分割できるかチェック、
だめならばプログラム上、多態性で表現することになります(←これが後々の問題の種になる事を承知の上でね。)
もちろんユースケース図に間違いがあった場合、仕様バグなので論外です。
-------------
ここまでで
オブジェクト指向とは、オブジェクト設計と実装方法について説明しました。
ここからコンポーネント指向についてを述べていきます。
おなじみとなったVB、C#の開発環境でデザイナー画面にアイテムを設置していくだけでプログラムが出来てしまう
あれがコンポーネント指向です。アイテムはコンポーネントと呼ばれているので気づいた方はいるんじゃないでしょうか。
あの機能はDelphiが元になっていて、MSが開発者を引き抜いたりお金の力で出来たのが今のVisualStudioとC#言語仕様になります。
http://ja.wikipedia.org/wiki/Visual_Component_Library
VLCの基本構造は最下層になるTObjectクラスがあって派生でトップに立ったものがコンポーネント、いわゆるソフトウェア部品・モジュールとなります。
底のオブジェクトがあって最上位になっていくほど高機能になっていく構造です。
車輪の再開発ですが、これをプログラムで表現しようという試みです。
全体ブロック図
+--------------------+----
| 業務画面 |
+--------------------+ ビジネス領域(フォーム画面に部品ペタペタ、イベント広げて処理書いたり、、)
| ビジネスロジック |
+---------+----------+----
| Library | | コンポーネント部品(.NETから派生するのでこの位置をキープ)
+---------+ |
| .NET |
+--------------------+----
今回着目する箇所はLibraryと書かれている部分です。
Libraryのブロック図
+--------------------+---
|Controller | 共通操作
| | Modelクラスには、Driverモデルと共通パラメータ、共通操作
+--------------------+---
|Driver(Model) | プロトコルレイヤー(外部と通信プロトコル(コマンド)で操作を行う)
| | Modelクラスには、通信仕様上で必要になるパラメータ(IDなど)、コマンドメソッド
+--------------------+---
|外部IO(Model) | 外部入出力レイヤー(シリアルポート、ファイル、TCP/IP 通信を行う)
| | Modelクラスには、ポート初期化パラメータ、Open/Close/Read/Write
+--------------------+---
こんな具合でしょうか。
大体は外部と通信するのでオブジェクトの体は通信インターフェイスにします。
その上に相手とのコミュニケーションする電文の作成・解析が必要になってきて
さらに上になると判断してコミュニケーションする頭脳という具合ですかね。
IOが足回り、Driverが手足、Controllerが頭脳、こうなります。
例でいうとTCP/IPで相手と通信する場合、通信仕様が必要になるので、先ほどのブロック図に当てはめていけばコンポーネントの完成。
つまり再利用を重視した構造であるということになります。
使うユーザーは最初に書いたとおり、VisualStudioを操作して画面に部品を設置するだけでプロパティウィンドウに書かれたプロパティを設定していくと
通信仕様とは一切知らなくても通信プログラムが完成します。
こういった部品を沢山作って行くことで
画面と状態遷移とビジネスロジックをプログラムにする作業に集中できるようになります。
大規模になってもオブジェクト指向で設計をがんばってもらって
足りないコンポーネントは作って、
ビジネスロジックと1:1で向き合える大きさまで派生させて、
画面単位にコンポーネントをくっつけて、
イベント広げて処理を書いてビジネスロジックを動かす、
画面遷移するなら遷移する、終了するなら終了で。
そんな作業の流れができてくればコーディング量も減って品質の向上につながるのではないでしょうか。
色々書いてきましたが、
オブジェクト指向は設計用で実装用ではないです。
設計と実装を1:1にするのもありですが、上記作業なら無理して合わせる必要もないですね。
ここでの注意ポイントはビジネスロジックにパラメータは持たない事です。
以上、思考の整理とともに長々と書いてみました。
ラベル:
ソフトIC
登録:
投稿 (Atom)