.NET Standard とは何か?

.NET Core が 1.0 になってリリースされて、ASP.NET Core MVC が Linux 上で動くようになったと思ったら、今度は .NET Standard ってのが出てきて、え?いきなり、.NET Standard 2.0 ってのは何ですか?ってな感じな人は多いと思いますが(私もそうでして)、ひとまず、.NET Standard とは何なのかを探っていきます。

Introducing .NET Standard | .NET Blog
https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/

もともと、.NET Core って、Windows に依存する API を切り離してしまって、Linux やら Mac やら動く環境を作るのが目的じゃなかったんですか?と思っていたわけですが、図を見るとちょっと違うようです。

dotnet-today

たぶん、Xamarinを買収した影響(Mono自体を取り込んでしまった影響)が大きいと思うのですが、Linux 上で、何らかの .NET なプログラムを動かそうと思うと、.NET Core なプログラムと mono なプログラムは競合します。上の図では、Xamarin が、iOS/Android に「のみ」依存しているような書き方ですが、実際は Linux 上で動かしているものもあるわけで、Raspberry Pi 上で C# を動かしてツールを作ったり、F# を動かせたりするのはそれです。実運用的に apache と .NET の組み合わせが妥当かどかは別として(LAMPで組むとか、Javaのほうが楽だろうし)、mono を使えば、結構な .net なツールを Linux 上で動かせます。クラスライブラリ自体も大体のところは本家(?)の .NET Framework を網羅しています。まあ、そのあたりが Unity + Mono という組み合わせなわけですが、それとは別なスタイルで .NET Core な環境を Microsoft は独自に始めたわけです。

で、結果的に Xamarin 社と業務提携から買収に至ったわけで、そうなると、上の「Mono Class Library」なところが「Core Library」に置き換わるのかな?と想像するわけじゃないですか。Microsoft 社内としては、Mono と .NET Core のメンテナンスを分散して注力するよりも、.NET Core に統一してしまったほうがよい(Mono の差分な資産はどうするのか?は別として)と思っていたわけです。

が、

dotnet-tomorrow

蓋を開けてみれば、base library の場所が、ごっそり「.NET Standard」に切り替わるって話なんですよね。ええ。.NET Core は 2.0 になることなく、vNext(でいいのか?)という統一された形で、.NET Standard になるわけですね。

すっきりするのはすっきりするんでいいですが、いわゆる OS 依存な低レイヤな部分は、.NET Standard としてどう扱うのか?特にSystem.IO系のセキュリティ絡みは .NET Standard としてどう扱うのか(あるいは扱わないのか)が不明なのですが、ひとまず、ひとつにまとめたい模様です。

PCL Hell が解決するのか?

PCL(Portable Class Library)を作るときに、動作するプラットフォームを選ぶわけですが「そんな未来なことはわかりません」。要は、誰が考えたか知らないのですが、.NET Framework で「Client Profile」っていう Web 系抜きのパッケージを考えたのが間違っていたわけです。

image

and

image

肥大化するアセンブリと、OneClick なインストール環境(だったかな)を利用できるようにするために、Web 系のアセンブリをケチったわけですが、その系譜が、Xamarin.iOS/Android を含める PCL 作りのところまで引き擦られていきます。あのプロファイルの番号は、順列組み合わせになっていて、Silverlight とか、Windows 8.0 とか Windows Phone とか過去の遺物を引きずり回します。まあ、最終的に Proifle7 か Proile78 か Profile259 なマジックナンバーに落ち着くわけですが(苦笑)。

ちなみに、ここの Hell な原因は、アセンブリ名やクラスの厳密性を優先させているのが問題であって、Linux の *.so のように(というか C言語呼び出しのごとく)「名前はどうでもいいから、スタックさえ合っていれば、呼び出せるよ」でもいいわけで、実際 Linux 内で *.so を呼ぶのは非常に簡単ですし、シンボリックも使えて便利です。まあ、その分、競合は発生しそうなんですが、Windows の各種ライブラリみたいに頻繁に更新しない、というのがミソですね。

あと、F# のタイププロバイダーで、ビルドするときの DLL と、出力する DLLと、Xamarin 内で動作する DLL が競合してしまって、Xamarin.Android/iOS 内ではタイププロバイダーを使えないとか、F# のライブラリを参照している C# のライブラリを参照する F# のプロジェクトを作るときにはコツがいるとか、変なことになっているのは、ぜんぶ PCL 絡みの変なことになっているせいです。ええ、F# のライブラリな変な番号も体系も PCL のせいです。F# が流行らないのも PCL のせいだし、ポストが赤いのも PCL のせい。

そんなわけで .NET Standard 1.x が過渡期である

ことが判明して、.NET Core そのものをあれこれと攻めていっても、これも過渡期(2.0がなくて吸収合併するんだったら、まあ VSCode でビルドの仕方ぐらいを覚えるのでよいのでは?)なので、構造的には .NET クラスライブラリの焼き直しの時期なんでしょう。Microsoft 内部の人にはそうなんだけど、外部からすれば、そこで停滞しているわけにはいかない( .NET 以外の分野が主だったりするわけなので)となれば、そこは「最新情報」の獲得にあくせくするのではなくて、

  • 従来型の WPF アプリを極める(内部的に UWP は .NET Standard で統一されるので、UWP でできることが限りなく WPF に近くなる)。
  • スマートフォンは、Xamarin.Forms を拡張してしまうか、Xamarin.iOS/Android で独自に進化させる(特に、Xamarin.Andrid のほう)。
  • Linux で ASP.NET するときは .NET Core を使う

という感じですかね。個人的には。

他にも VR とか Unity とか機械学習で Python とか Alljoyn とか ROS とか、諸々な要因があるわけで、 .NET Standard がそのあたりと「どのくらい組み合わられるか?」が肝になってきます。

もうちょっと真面目な解説はこちらへ

.NET Standard Library
https://docs.com/iwanaga-nobuyuk/3514/net-standard-library

.NET Core とマルチプラットフォーム
http://www.slideshare.net/shozon/net-core-66620714

マイクロソフト、.NETの分裂を未然に防ぐための標準仕様「.NET Standard」を策定 - Publickey
http://www.publickey1.jp/blog/16/netnet_standard.html

カテゴリー: 開発 | 1件のコメント

[ソフトウェア開発者の道具箱] 同情プログラミングをやめる

道具箱シリーズの第2弾は「同情プログラミング」の話です。

プロジェクト運営(プロジェクト「管理」ではなく)の視点から言えば、プロジェクトやチームがうまく動く方法は「うまくいかない部分」を切り去っていくことです。「切り去っていく」ということは、冷徹な感じがするような気がしますが、人を切り去るのではありません(チーム崩壊を招く「マイナス生産者」に対しては、切り捨ての手法をとりますが)、その人が何かをやるときに、うまくいかなくてマイナスになってしまう部分を切り落として捨て去ります。人なのだから、何かの間違いもするし、勘違いもするし、運が悪いときもあるし、体調が悪かったときもあるし、状況によりうまくいかない場合もあるでしょう。だから、トータルで考えるわけですが、チームとして(それは人として「成長」なのかもしれません)今よりもうまくいくためには、今、ダメである部分を少しずつ切り取っていくのが着実な方法なのです。なので、何らか状況でうまくいかなかったとき(能力が低かったというのも含めて)は、再び同じ状況に陥ったときには回避できるようにしておきます。完全に同じ状況というのはないのですが、今後も似たようなことはおきますよね。ISO9000の「是正処置」という考え方ですが、これを流用します。勿論、なんでも是正処置が必要なわけでなく、レアな場合(今後は1度も起こらないようなこと)は是正する必要はありません。苦くて忘れたい経験は、忘れ去ってしまうのがベターです。

さて、プログラミングにおいて、プログラムコードを書くということは、それなりの時間をかけて、それなりのかの人の努力の結果が示されているわけです。なにがしかに時間は、会社の給与のうちかもしれないし、自主的に家に帰って考えた結果かもしれないし、どこかの講習でお金を払って覚えた技かもしれません。1,2日のコードであれば、捨て去る勇気もあるのですが、1週間も掛かって苦労して作りあげたコードを、人情的に捨てるに忍びないですよね。ちょっとぐらいまずくても、何らかのいいところを拾うとか、かの人の心情を害さないような手段を取りたいものですよね。

ですが、残念。それらは捨て去ってしまうほうがベターなのです。

プログラムコードが、アジャイル開発的に動くものを達成するのであれば(場合によっては、「動かない飾りのコード」というものもありますから)、動かないまずいコードは、そのままゴミでしかありませんし。何の価値もありません。そこに「同情」をしてしまうと、先行き負債を抱えてしまうのは明らかなことです。いや、コード自体の負債以前に、かの人の成長機会を失ってしまうのです。

ベストな方法、かの人に書き直して貰う事です。仕事として。

うまくいかない原因は、まずい設計かもしれないし、時間がなかったのかもしれないし、予想よりも時間が掛かったかもしれない、能力が足りなかったのかもしれない、いろいろな原因があります。でも、2度めにコードを書くときは、設計の見直しや、時間をしっかりとったり、計画を立て直したり、かの人の能力だけでなく他の人の助けを求めたりすることが可能であり、それは「経験」として生きてきます。それを、本人に伝えずにこっそり直してしまったり、直すべきところを指摘して勝手にピンポイントで直してしまったりというような、かの人の「成長機会」を奪うような方法は、結果的にチームやプロジェクトにとって損失でしかありません。そう、いわゆるかの人の生産性が変わらないままになってしまうのですから。

この「同情プログラミング」をやめるのは、かの人にシビアすぎるような感じがするでしょうし、無意味につらくあたるような気がしますよね。いいえ。「同情プログラミング」をやめるためには、

  • 失敗を前提として、コーディング期間の計画を立てる
  • やり直しの時間を確保する
  • 失敗しても問題が少ないところを新人に配置する

というプロジェクト運営/計画が必要です。それがなければ、単なる無法地帯で、プロジェクトの成否は偶然によって左右されているだけですよね。

カテゴリー: ソフトウェア開発者の道具箱 | [ソフトウェア開発者の道具箱] 同情プログラミングをやめる はコメントを受け付けていません

PLEN2 で始めるロボット制御の基本…の補足

Plen2で始めるロボット制御の基本(スライド)

[slideshare id=66364049&doc=plen2-160924053144]

NETラボ勉強会 20160924 – YouTube

二足歩行ロボットのチート…じゃなくて、参考用に購入した PLEN2 を題材にした発表です。あれこれ、模索した結果を話しているので、本格的なところは ROBO-ONE などを参照して貰うとして、ソフトウェア開発のサイドから見ると、ハードウェアな二足歩行ロボットはこう見える&こうアプローチできるという感じで話をしています。

PLEN2 を購入して、あれこれ弄って分かったことなのですが、

  • サーボモーターの初期化が結構大変
    → 結構、誤差がでるので、誤差は誤差で許容しないといけない。
  • 歩くといっても、モーション作りと、自律制御と、人によるコントロールが混在している
    → どれを目指すかによって、制御プログラムにいろいろ違いがでる
  • ソフト屋さんのアプローチできるところは多い。
    → クラウドでセンサーデータを集めるだけじゃなくて、モーションを作るアプリとか、通信制御の部分とか、協調動作を映像化するとか、今後ソフト屋さんのできることは多い。

VR など仮想空間ということで、ソフトウェアだけで完結できるものが流行りだったりするのですが、自分としてはハードウェアにアプローチできる部分でソフトウェア開発の手法を使う方向でやっています。なので、重力の話だとか物理誤差だとかモーメントとか必須になりますよね。

7月からずっと、ASP.NET MVCの本を書いていたのですが、やっとこさ一区切りついてきています。10月以降は、再びハードウェアなもの(Windows IoT Core も含めて)に戻る予定。真面目に Raspberry Pi/Rasbian に戻って、Python も。

コントローラー制御の参考に

有線 USB の XBOX コントローラは、Windows IoT Core でも繋がるので、お手軽です。無線のほうは、まだ試していない。

カテゴリー: PLEN2 | PLEN2 で始めるロボット制御の基本…の補足 はコメントを受け付けていません

アリスは無限にプラダから猫を取り出す(F#編)

アリスは無限にプラダから猫を取り出す | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/8179

これをF#版に直してみる。
実は、GetCatsメソッドを末尾呼び出しにして、F#のほうは無限に猫を取り出せる…という風にやろうと思ったのだが、この方式だと lst に詰め込むときにスタックオーバーフローになってしまう。
最初は head::tail 方式で書いていたのだが、なんか面倒になって(ツリー構造だから)、外部で list を持っているのが問題かも。

type IObject() = do ()
type Cat(name) = 
    inherit IObject()
    member val Name:string = name with get, set

type Bag() =
    inherit IObject()
    member val Items:IObject list = [] with get, set
    member x.Add(items) =
        for it in items do
            x.Items <- it :: x.Items
        x
    // 猫だけ取り出す
    member x.GetCats() =
        let rec cats (bag:Bag) =
            let mutable lst = []
            for it in bag.Items do
                if it.GetType() = typeof<Cat> then
                    lst <- it :: lst
                else
                    let bag = it :?> Bag
                    lst <- lst @ cats bag
            lst
        cats x 

// main
// 入れ子のバッグ
let prada = 
    Bag().Add(
        [Cat("mike");
         Bag().Add( 
            [Cat("hop");
             Cat("stop");
             Cat("jump")]);
         Cat("kuro");
         Cat("shiro")] )
// 猫のみ取り出す
for it in prada.GetCats() do
    let cat = it :?> Cat
    printfn "cat: %s " cat.Name 

// 無限バッグを作る
let mutable infbag = Bag().Add([Cat("Cheshire")])
infbag.Add([infbag]) |> ignore
// 無限に取り出す...ことはできない
for it in infbag.GetCats() do
    let cat = it :?> Cat
    printfn "cat: %s " cat.Name 
カテゴリー: F# | アリスは無限にプラダから猫を取り出す(F#編) はコメントを受け付けていません

アリスは無限にプラダから猫を取り出す

アリスはプラダがお好き | Moonmile Solutions Blog
http://www.moonmile.net/blog/article/alice-plada

アリプラシリーズの第24弾めは、イテレーターの話…というか、とある林檎な国では for がなくなって for in だけになってしまったものだから、いやいや、配列とコレクションがごっちゃになってないか?と思って作ろうと思ったのだけど、横道に逸れてイテレーターになってしまったという訳。

最近のプログラム言語ではコレクションの全ての要素に対して何かやるときは、foreach を使う訳ですが(林檎の国では for in ですね)、これはコレクションの中身のすべてのアクセスするというだけで、特に順序は決まっていません。まあ、実装上は最初の要素からアクセスするんだけど、Javascript のように実はとびとびだったり、そもそもコレクションと配列の違いってそういう「順序性」のところにあります。順序が保証されていないってことですね。順序が保証されないってことは、逆順ってのもないわけで、すべての要素に1回ずつアクセスするってだけです。実際のところは、各プログラム言語のスペックによるのだろうけど、配列とコレクションの違いってのはそういうところにある。
なので、コレクションを foreach で探索したときに、ひとつ前の要素とあわせて何かする(たとえばフィボナッチ関数)というような他の要素をアクセスして順序が問題になる場合は、再帰関数を使ったりするのだが、まあ、それの例っぽいものを示しておこう。

こんな感じに、Bag クラスと Cat クラスを作ってみる。鞄の中には猫か鞄を入れられる。鞄の中には鞄が入るので、実は無限に鞄が入るとい不思議な Bag クラスになっている。いや、これは DOM と一緒で XNode がそれの仕組みなっているので、一般的なツリー構造のアプローチになっている。

class IObject { }
class Cat : IObject
{
    public string Name { get; set; }
    public Cat( string name ) {
        Name = name;
    }
}
class Bag : IObject
{
    public List<IObject> Items { get; set; }
    public Bag () {
        this.Items = new List<IObject>();
    }
    public Bag Add( params IObject[] items )
    {
        foreach ( var it in items ) { this.Items.Add(it); }
        return this;
    }
    // 猫だけ取り出す
    public IEnumerable<Cat> GetCats()
    {
        foreach (var it in this.Items)
        {
            if (it is Cat)
            {
                yield return it as Cat;
            }
            if (it is Bag)
            {
                foreach (var ii in (it as Bag).GetCats())
                {
                    yield return ii;
                }
            }
        }
    }
}

Bag クラスには、猫だけを取りだすための GetCats メソッドがあって、イテレーターを返すようにしてある。yield return を使って、入れ子になった Bag の中も探索できるようにしている。
Add メソッドは、子要素(Bag か Cat)を追加できるようにしてあって、これは XElement と同じ仕組みになっている。

猫のみ取り出す

Bag prada = new Bag().Add(
    new Cat("mike"),
    new Bag().Add( 
        new Cat("hop"),
        new Cat("step"),
        new Cat("jump")),
    new Cat("kuro"),
    new Cat("shiro")
    );
// 猫のみ取り出す
foreach ( var it in prada.GetCats() )
{
    Console.WriteLine("cat: " + it.Name);
}

prada の鞄に、猫と鞄を入れるんだけど、これを実行すると GetCats メソッドで綺麗に猫だけを取り出せる。

これでアリスは満足ですよね。

結果を見るとわかるんですが、鞄の中身を取り出す順番は実装依存なので、どういう順番で猫が出てくるのかは分かりません。けれども、ひとつの要素を1回ずつアクセスして取り出しています。

無限に猫を取り出す

さて、Bag クラスを見ると、Bag クラス自身を入れ子にしているので、実は自分自身を要素に加えることができる。そう、循環参照というやつだ。

// 無限バックを作る
Bag infbag = new Bag().Add(new Cat("Cheshire"));
infbag.Add(infbag);
// 無限に猫を取り出せる
foreach (var it in infbag.GetCats())
{
    Console.WriteLine("cat: " + it.Name);
}

バッグ infbag を作って、自分の鞄に追加するという無限バッグを完成させる。でもって、これも GetCats メソッドで取り出すとどうなるか?アリスは、無限にチェシャ猫を取り出すことができるのだろうか?

20160921_02

一見、無限に取り出せるように見えるけど、GetCats メソッド内で入れ子になっているからスタックオーバーフローになっちゃんですよね~、ちゃんちゃん。

サンプルコード

サンプルコードはこちら
https://1drv.ms/u/s!AmXmBbuizQkXgf0CI2eEOEnAdsI-_w

カテゴリー: 開発, C# | アリスは無限にプラダから猫を取り出す はコメントを受け付けていません

[ソフトウェア開発者の道具箱] イチゴジャムの法則

6月末に出版した 現場ですぐに使える! Visual Basic 2015 逆引き大全 520の極意 なのですが、この第19章には不思議な Tips が入っています。章自体は「トラブルシューティングの極意」ということで、運用保守や設計段階の落とし穴について書いた章なのですが、最後の10個の tips が「対人関係」になっています。端的に言えば、トラブルシューティングなんて、その場その場の経験の積み重ねと、根本的な対処の方法を知っていればよいだけなので、あまり表面的な対症療法なものは、これ以上追加したくなかったんですよね。というのと、試しに「技術書に技術的なじゃないものを紛れ込ませてみたかった」というのがあります。真面目に書くと、えらい時間が掛かるのだけど、Tips 風に1頁にまとまるぐらい(1000字ぐらい)を目標に書き下してみました、という具合です。

でもって、ものがVBだったからなのか、やっぱり読者対象がずれていたのか分かりませんが、まったく反響がないので、ここにブログの記事としていくつかついかしておきます。中身的には、見積もり本舗とか消えてしまった別のブログに書いてきたものでもあるのですが、なんらかの形で検索に引っ掛かるようにするもひとつかと。あと技術顧問的なことをやるので「ここ読んで」という具合にできるようにしておきます。

タイトルはワインバーグ著「コンサルタントの道具箱」から持ってきてるので、いわゆる「ソフトウェア開発者の道具箱」です。コンサルタントだと、どこかのシャチョーさんとかマネージャーを相手にするのですが、ソフトウェア開発者の場合は同僚やプロジェクトリーダー、新人、顧客の担当者が相手になります。書籍のほうは、改変が効かないのである程度オブラートに包んで話をしていますが、バックグラウンドには行動経済学とか心理学とか孫子とかそんなものも入っています。参考文献としては「コンサルタントの道具箱」しか出てきませんが、そのあたりは「読み取って」頂くというのが主旨でもあったり、そもそも「イチゴジャムの法則」ってのがそんなものなのです。

中心に何か伝達したいものがある、というのをイチゴジャムの法則では「粒」と表しています。その粒は、広げようと薄めようと逆に濃くしようとも同じなわけで、過不足なく書けば「粒」そのもになるけど、人によって受け取り方が違ったり詳しい説明が必要だったりするときには、粒の外側に解説を付け加えます。まあ、それが書籍の売りだったりするし、「コミュニケーション」とか「会話」とか呼ばれるものですよね。ツーカーの関係であれば、メール一本で済むようなところも、顧客との関係であれば電話をするなり相手先まで行くなりの「礼儀」的なコミュニケーションを必要とします。それをしないと「コミュ障」と呼ばれたり、相手からコミュニケーションの取れない人と排斥されてりします。書籍にちらっと書きましたが、このコミュニケーションを過剰に付ける技というものあります。いわゆる「広告」的なものだったり、上滑りな議論だったり、暇つぶしのお昼のワイドショーだったりします。「粒」がないのですから、どこまでも薄く薄く引き伸ばせるし、そもそも「粒」がないのだから、議論にも反論にもなりません。ただ、ぴーちくとさえずっているだけになります。そう、暇つぶしだったらそれでいいんですけどね。残念ながら、人によっては「粒」のありかが何処なのか見えなくなってしまって、疑似的な「粒」に引っ張られて議論がどこかに飛んで行ったりします。いや、もともと「粒」がないのだから、議論自体にもならないんですけどね。

そういうわけで、とあるコミュニケーション(顧客との間柄だったり、チーム内の間柄だったり)の中には「粒」があったりなかったりするわけで、若い頃には「粒」がない会話にイライラすることもあるでしょうが、いやいや歳をとると「粒」ない会話はそれはそれとして、頭の中で別な「設計」を考えたりできるようになるので大丈夫です。そのあたりの話は、けらえいこ著「たたかうお嫁さま」や「セキララ結婚生活」に詳しく書いてあります。

ちなみに、「粒」とはいっても、クオリアみたいにこれと示せるものではありません(つーか、クオリア自体がアレなので、そういう意味では「粒」ない会話を「クオリア的な」と言ってもよいかしれません)。そこは双方の合意のものとに通じるものでもあり、共通の個人的体験の重なりや、重ならないけどツーカーに考えられる、というようなひとつの単語や文では表せないものかもしれません。明示的なものであれば、UMLのようにあらわせるのですが、概念的なものは伝えにくいので暗喩(メタファ)を使います。メタファーを重ねることにより色濃くなる中央を明らかにするんですね。これは質問の応酬という形でも表せる(ディスカッションとは違います)ので、双方、それなりの技能が必要です。そういう意味では、文体が読者を選ぶというものもあり、かつこの文章自体もそういうメタファーに含まれているという意味で、やっぱり「粒」的なものを強化するために「イチゴジャムの法則」をもう一度持ち出してみるわけです。

河合隼雄著「中空構造日本の深層」のように、中空であるからこそ中央にあるものを双方が了解できるという場合も多いのです。私はこの方法を好みますが、最近の世の中はそうではなくなりつつありますよね。実際に中央にあるものを右に寄せたり左に寄せたりすれば、当然ならが双方の主張が異なるのだから議論が一致するはずはありません。一致することもなく、妥協もせずなのだから、そこは社会は広く階層化されている(ねじれの位置にあるという意味で)交差位置で満足すればよいのです。

さて、話を元に戻すと、ある程度価値観が一緒だったり、共通の体験があれば粒を使ったコミュニケーションが楽≒効率よくなります。まあ、そこがアジャイル開発的なチームビルディングなんですけどね。スクラムの本にもそう書いてあります。ある意味で、チームで残業をしたりチームで経営的な視点を持ったりチームで趣味を共有できたり、というのは、濃厚なコミュニケーションを欲しているのではなく(そういう場合もあるけど)、仕事上の煩雑なコミュニケーションを省略するために「あらかじめ」価値観を共有するという目的があります。なので、チームビルディングにおいて、スタート時点の「価値共有」と同時に「仕事上の価値の共有をお互いに認めることができるか?」というハードルも必要となり、組織だからこ組織に成り得るという分岐がそこにはあります。

そうそう、もうひとつのチームビルディングの仕方として「オーケストレーション」もあるので、こっちのは別の機会に。いわゆる LLC(合同会社) です。

カテゴリー: ソフトウェア開発者の道具箱 | [ソフトウェア開発者の道具箱] イチゴジャムの法則 はコメントを受け付けていません

Bitbucket にプライベートな git を作る方法

月7$ 払って github にプライベートレポジトリを作ればいいんだけど、その前にお試し的に Bitbucket で作って運用してみるテスト。大抵の場合は、面倒なので public で github で作ってしまえばいいのだが、ちょっと内部的なのだと非公開で作りたいときもあるので、メモとして。

既存のものからアップロードしようとしたり、あれこれやったんだけど、なんかうまくいかない。したかがない(?)ので、Bitbucket の手順に従ってちまちまやるのが一番手っ取り早いです。

image

リポジトリの作成から、新規リポジトリの作成

image

新しいリポジトリが作成できたら、コマンドラインの「私はゼロからスタートします」をコピペしながら実行する。「SourceTreeにクローン」のほうは、Firefox で動かなかったので

image

 

mkdir /path/to/your/project
cd /path/to/your/project
git init
git remote add origin https://moonmile@bitbucket.org/moonmile/sample.git

 

git init と git remote を使って、新規作成したレポジトリをローカルの PC に作れば ok.

あとは、ローカル PC で、Visual Studio でプロジェクトを作るとか、他に保存してあるプロジェクトをコピーするとかして、commit, push すればよい。

他の PC や Mac では git clone すればよいので、これでコードの同期が簡単にできる。

カテゴリー: 開発 | Bitbucket にプライベートな git を作る方法 はコメントを受け付けていません

MVVM+MVCパターンを大規模システムにスケールする

大規模プロジェクトで MVVM を導入するときの注意 | Moonmile Solutions Blog をもう少し突っ込ん考えてみます。大規模といっても、みずほみたいにできあがらなくて破綻したパターンもあれば、特許庁の場合のように設計時で破綻した場合もあれば、豊洲のように作ってからそもそも破綻しているのもあるわけで、常々プロジェクトの成功率は30%程度なので、大抵は破綻します。まあ、途中でプロジェクトとしてうまく失敗させる(一気に解散する)か、うまくプロジェクトを軟着陸できずにだらだとお金をつぎ込んで「失敗」させることがことができず終わる二百三高地になるやもしれません。

さて、それなりの資源(人と金)をつぎ込んでペイができるかどうかのバランスを保つ場合(公共事業の場合は、バランスを保たなくてもよい場合もあるので別)、「失敗が許されない」パターンがあります。しかし、失敗が許されないの対偶を人は「必ず成功する/させる」と受け取りますが、実は「全面的に失敗という状態にならければよい」わけで、部分的に成功であればつぎ込んだモノへの回収ができます。端的に言えば、工事進行基準になるのですが、実際ソフトウェアの開発工程に工事進行基準を持ち込んで、プロジェクトが半分で頓挫したときにそのプロジェクトには半分の価値があるのか?というと怪しいところがあります。と言いますか、大抵の場合、無いです。例えば、脱サラでよくやる飲食店のパターンは、初期投資でキッチンを購入したりするのですが、途中で潰れるとキッチンを下取りできるので、そこそこペイができます。が、ソフトウェア開発の場合、注力するもののほとんどが「人件費」なので、途中で頓挫したからといって、それを中古として出すことはできません。まあ、頓挫したサイトを売り買いするパターンもあるけど(会員データ込みとか?)大抵の場合は、工事進行基準とかEVのように価値が右上がりになるのではなく、プロジェクトの終了直前(完了直前)に一気に価値があがるのが普通です。ですが、長期のプロジェクトは人数が多い大規模なプロジェクトになると、最後の一気にあがる価値の時期に達しない場合は、まるごと価値がなくなるということなり、EV的(アーンドヴァリュー的)になだらかな価値が生み出されているという訳ではありません。

image

発注側としては、まるで既製品の車を買うように完成した品を即使いたいわけですから、納品直前に支払いをするほうが得なので、↑の図は望ましい形になります。支払を遅らせるという点で、資金活用もできますからね。ですが、請負側としては、支払いは納品により一括だし、途中の破綻のリスクを負わなければならず、たまったものではないので、プロジェクト工程を分けて分割支払いにします。

image

こんな風に段階的にリリースして、価値を発注側に提供して支払いを得ます。プロジェクト工程でいれば、要件定義とか設計工程とか製造工程とかいうやつですね。実際、それぞれの工程に確かな「価値」があるかどうかはわかりませんが、価値があるかのように振る舞うわけです。それぞれの工程が別の人物/会社にて行われているときには、いわゆる「作り逃げ」の手が使えるわけで、豊洲とか特許庁のあれはそのパターンです。その工程の本来の「価値」とは何かを忘れ去っています。

さて、段階的なリリースをプロジェクトの各工程にあてはめましたが、アジャイル開発のイテレーション開発の方法では、この段階的なリリースは「完成品」をしてひとつのプロジェクトとしています。スクラムで言えば、2週間ごとにリリースするとか、コアな部分だけ先に作って後から顧客の要望を取り入れる(あるいは削っていく)という方法がありますね。そのような、短期的なリリース(分割リリース)をもって、全体のプロジェクトを長期に引き延ばせば、マイグレーション開発というスタイルになるだろうし、そこは保守/運用を絡めて継続的に開発していくというスタイルを取ります。勿論、この継続したスタイルや段階リリースがすべてのプロジェクトに当てはまるわけではありません。近いところでは、Apple の Map の惨事は、ひょっとして「段階リリースの一部」といえば許せるかもしれませんが、製品とみたときはダメですよね。紙の書籍であっても、買ったときは表紙だけあって、あとから中身をちょっとずつ届けますと言われても、表紙が紙の状態では買いません(当たり前)。段階的なリリースあっても、顧客の視点からみて「何らかの形で価値が完成されて」いないと、価値とはみなされませんし、対価を支払う気にはなりません。そうそう、「月刊○○」のように毎月500円ずつ買わせるというパターンは、実は段階的な価値提供の成功例かもしれません。

発注視点で分割する

車のように完成したものしか価値がない場合と違って、実はソフトウェア開発において「分割リリース」は、発注側にとってもメリットがあるものです。必ず、そのプロジェクトが完成すると保障されているとしても(プロジェクトが失敗するリスクを0としたとしても)、発注側にとって5年後に5億円を支払って価値を得るよりも、1年目に1億円を支払って活用したしたときの価値を得たほうが投資率はいいですよね。また、4年後のオリンピックを目標にするならば、4年後に4億円を支払って価値を得るというスタイルよりも、1年目に2億円の支払いをして半分の価値を得たほうが、先行者利益を得られる可能性が高まります。

そんな訳で、長期かつ大規模なプロジェクトの場合、発注側の視点での「分割リリース」が意外と重要になってきます。大抵の場合は、ウォーターフォール開発やイテレーション開発の視点でプロジェクト工程として分けたり、アジャイル開発にして顧客の要望に沿わせたりするのですが、それとは違う視点での「分割」の仕方が必要なことがわかります(そういう視点で、アジャイル開発をしているならば別ですが)。

大規模プロジェクトを発注視点で分割する

5から10名程度がアジャイル開発の基本ならば、人海戦術的にウォーターフォールやPMBOKを活用するのが規模の大きい開発の基本とはなるのでしょうが、もう少し平易に、前段階の時点での分割を考えます。

先に話したように、顧客/発注側の都合を加味してプロジェクトを分割してみると、

  • 投資効果の大きい部分を先行リリースする。
  • 先行リリースされたものを使う場合は、完成品よりも人手がかかる。
  • 先行リリースされたものは不備/不足が多いため、人手で回避する。

ということになります。どこかの Xamarin.Forms のプロジェクトを想像させますが、まあ、あれと似たような感じです。OSS ならば、ひとまず公開してしまって(Xamarin.Forms はクローズドからスタートだけど)、それ自身に価値があるのかどうかを市場評価したうえで、継続的に開発をすすめるか/あるいは撤退するかの判断ができますよね。開発者は無限に時間を使えるわけではないのですから。

これは、多少ポンコツではあっても駅まで荷物を運べる車が便利とか、多少メンテナンス料金がかかったって時間が1/10で済むのであればロボットで自動化させたお菓子の生産ライン、みたいな感じですよね。人は、最初の材料を入れるところと梱包のところを任されていたり、ロボットが動かなくなったときのために張り付くわけです。

そうそう、iPhone のような完成したスタイルを求める場合は、分割リリースのほうが嫌われるわけで、そのあたりは Apple Map の叩かれ具合と Bing Map の叩かれ具合から察することができます。

分割リリースによる多少の不具合/不備を、発注側が受け入れるかわりに、先行投資としての価値を発注側が最終リリースのときよりも多く受け取れる、という価値を発注者側が熟知している、という前提が重要になります。

image

それらを前提にして、発注側視点で分割をしたとき、たとえば MVVM パターンの場合、大規模開発に参画している会社/チームは、View や ViewModel などに特化している訳ではなく、それぞれの業務知識の範囲≒ドメイン内で分割します。

請負視点を加味する

さて、発注視点であれば、投資効果の高い部分からの開発&リリースをすればよいということになります。ということは、設計段階において、いくつかの制限がでてきます。

  • とあるモジュール/ライブラリ/コンポーネントが、先行リリースで独立して動けること
  • とあるモジュール/ライブラリ/コンポーネントが、継続的に改修可能であること
  • とあるモジュール/ライブラリ/コンポーネントが、他システムと連携して動作可能であること

一見、当たり前のように見えますが、最終リリース型のウォーターフォール開発を行ったとき(最終リリース型のアジャイル開発でも同じ)、各コンポーネントは独立して動く必要なく他コンポーネントと密接な連携をしていても構いません。また、最終系までリリースが延期されるので、リリース後の改修を考慮に入れなくてもよいパターンが存在します。それにより、拡張性を無視することによる開発の効率化やコストカットが可能です。また、リリースまで動作が保証されないので、他システム/コンポーネントとの連携動作は最終リリース時まで保留になっていてもよいのです。たとえば、テスト環境できっちり動作することがプロジェクト運行時に保証されていれば、それが途中途中で他コンポーネントと連携させて無理に動作させる必要はありません。いわゆる、糊やにかわ的な部分を作る必要がなくなり、これもコストカットに貢献しています。

このため、多分にしてコスト高になりがちな分割リリースですが、そのコスト高をうわまる先行投資のペイを発注側が求めているならば(あるいは、発注側に認めさせることができれば)、このような分割リリースのための設計は意味があります。

ひとつの方法は「デザイン・ルール」のモジュール化により、各依存関係(設計時の変更工数も含め)を求めて、できるだけ関係の少ない状態にします。この本自体は、アイデアに過ぎず実体は伴わないのですが、私は「アイデア」として利用しています。

MVVM+MVC と TDD を活用する

肝としては、「設計段階で分割を考慮した設計をする」だけなのですが、そのあたりをアーキテクトと呼んだり呼ばなかったりしますが、まあ、少なくとも分割を考慮しない設計をした場合は、分割リリースはできません。継続リリースも困難ですよね。

image

一例を出すと、

  • ブラウザ
  • クライアントアプリ C#
  • サーバーシステム PHP

というシステムの分割の仕方があります。クライアントサイドでは MVVM パターンを使い、サーバーサイドでは MVC パターンを使う。Model はシリアライズ機能を用意しておき、ネットワーク系でデータのやり取りを行う。データベースは、サーバーサイドにあるパターンですね。クライアントは、Windowsデスクトップクライアントと、ブラウザでアクセスするクライアントを用意します。ブラウザからは、jQuery で Web API を調節呼び出してもよいし、別途 CakePHP 側にブラウザ用の View を作ることもできます。

当然のことながら、それぞれのコンポーネントは業務に直結しているわけではないので、各システム(在庫システムとか顧客管理システムとか)に応用が可能だし、実際応用ができます。コンポーネント自体は、独立で動作できるように TDD を用意しておきます。

難点としては、何かの機能を付け加えようとしたときに、クライアントサイドからサーバーサイドの一貫を見直さなければいけません。機能を追加したときに(特に削減したときに)、他のシステムに提供している機能が変化していないかを随時チェックする必要があります。それらを、手作業/人海戦術でやっていては、お金がいくらあっても足りません。何らかの形で自動化を行います。逆に言えば、自動化できないのであれば、そこの機能は常に切り捨てられるものであり、一品ものでしかないということです。

上記のシステム例で言えば、それぞれのコンポーネントのインターフェースが揃った状態で、ひとまず分割リリースの用意ができています。インターフェースしかないので、中身がからっぽだから何も動作はしないけど、でも、分割リリースができる程度の動作はするわけです。つまり、動くものの価値を発生さることが可能です。ほら、さきの EV 的な価値創出に近づいたでしょう。

image

そりゃ、要件定義も大切だけど(機能を絞るとか)設計がボロボロだったら、何もできあがりませんよね…ってな具合です。

横断型の TDD は、コンポーネントごとに TDD を作る方法とは違うので、これはまた別途書きます。あと、連携するコンポーネントが多くなると、先に書いた通り機能を追加する旅にあちこち手を入れる(MVC パターンだったら必ず3箇所に手を入れるとか)になるので、ここも別途手法を変えます。じゃないと手数ばかりかかって余計大変になるので失敗する率があがります。

カテゴリー: 設計 | MVVM+MVCパターンを大規模システムにスケールする はコメントを受け付けていません

アリスは System.Json に出会う

ということで、さっそくダウンロードして、無理矢理 .NET Framework のほうでビルドします。ええ、.NET Core じゃなくて、普通の .NET Framework に持って来るわけですね。

corefx/src/System.Json at master ・ dotnet/corefx
https://github.com/dotnet/corefx/tree/master/src/System.Json

から System.Json の src 以下をごっそり持ってきます。

Visual Studio 2015 でクラスライブラリを作成

実は、そのまま corefx のプロジェクトを持って来て少し変えるだけでいけるかなと思ったのですが、無理でした。

エラー時に System.SR という内部的なリソースにクラスにアクセスしているので、ビルドができません。仕方がないので、以下のようなダミークラスを作ります。

internal sealed class SR
{
    public static string ArgumentException_ArrayMustEndWithBracket { get; internal set; }
    public static object ArgumentException_ExpectedXButGotY { get; internal set; }
    public static object ArgumentException_ExpectedXDiferedAtY { get; internal set; }
    public static string ArgumentException_ExtraCharacters { get; internal set; }
    public static string ArgumentException_ExtraDot { get; internal set; }
    public static string ArgumentException_IncompleteEscapeLiteral { get; internal set; }
    public static string ArgumentException_IncompleteEscapeSequence { get; internal set; }
    public static string ArgumentException_IncompleteExponent { get; internal set; }
    public static string ArgumentException_IncompleteInput { get; internal set; }
    public static string ArgumentException_InvalidLiteralFormat { get; internal set; }
    public static string ArgumentException_LeadingZeros { get; internal set; }
    public static object ArgumentException_MessageAt { get; internal set; }
    public static string ArgumentException_NoDigitFound { get; internal set; }
    public static string ArgumentException_StringNotClosed { get; internal set; }
    public static object ArgumentException_UnexpectedCharacter { get; internal set; }
    public static string ArgumentException_UnexpectedEscapeCharacter { get; internal set; }
    public static object[] NotSupported_UnexpectedParserType { get; internal set; }

    internal static string Format( params object[]  para)
    {
        throw new NotImplementedException();
    }
}

これで、ビルドは通るようになりました。

呼び出し側は、

class Program
{
    static void Main(string[] args)
    {
        var json = @"{ ""name"": ""JSON"", ""number"": 13 }";
        var jr = new JavaScriptReader(new StringReader(json), false);
        var o = jr.Read();
        var pairs = o as KeyValuePair&lt;string, object&gt;[];

        Console.WriteLine("hello " + pairs[0].Value);
        Console.WriteLine("number is " + pairs[1].Value);
    }
}

な感じで、JavaScriptReader クラスを new して、Read メソッドを使います。元の System.Json のテストプロジェクトには JsonValue のテストコードしかないのですが、まあ、これでいけます。ただし、JavaScriptReader は internal なクラスになっているので、「public class JavaScriptReader」に書き替えてしまいます。

Read メソッドの戻り値は object 型なので、適当な型に直します。これ、最終的にどうするつもりかわからないのですが、ひとまず、KeyValuePairの配列で来ているので「KeyValuePair<string, object>[]」でキャストします。

実行すると、こんな感じで、アリスが JSON に出会えます。

どうも、プロパティ名はダブルクォートで囲まないと駄目なので、RFCに沿い過ぎているというか…「{ name: “JSON” }」な JavaScript の連想配列な JSON も通してほしいですね。そういうときは、NuGet で Newtonsoft.Json をインストールせよ、という話なんですが :)  コード的にはReadNumericLiteral でプロパティ名をクォートで拾っているので、それ修正すれば ok.

サンプルコード

AliceJson-v0.1-src.zip
https://1drv.ms/u/s!AmXmBbuizQkXgfxWteUSWlBU7zrT1g

カテゴリー: C# | アリスは System.Json に出会う はコメントを受け付けていません

アリスはプラダに猫がいることを知らない

な感じで、内部データを遅延して持って来る例を作ってみる。

class Program
{
    public static List<Cat> cats = new List<Cat>();
    static void Main(string[] args)
    {
        cats.Add(new Cat("tora"));
        cats.Add(new Cat("mike"));

        var pradaRed = new Prada();
        var pradaBlue = new Prada();
        var pradaYellow = new Prada();

        Console.WriteLine("1: {0}", pradaRed.Cat?.Say());
        Console.WriteLine("2: {0}", pradaRed.Cat?.Say());
        Console.WriteLine("3: {0}", pradaBlue.Cat?.Say());
        Console.WriteLine("4: {0}", pradaYellow.Cat?.Say());

        return;
    }
}

class Cat
{
    string _name = "";
    public Cat(string name)
    {
        _name = name;
    }
    public string Say()
    {
        return $"{_name}: nya-";
    }
}
class Prada
{
    Cat _cat = null;
    public Cat Cat
    {
        get
        {
            if (_cat == null)
            {
                _cat = Program.cats.FirstOrDefault();
                if (_cat != null)
                {
                    Program.cats.Remove(_cat);
                }
            }
            return _cat;
        }
    }
}

実行するとこんな感じ

意味合いとしては、アリスはプラダのバックを3つ持っている(pradaRed、pradaBlue、pradaYellow)んだが、中に猫がはいってるかどうかは分からない。どの順番で開ける猫がいるかわからないし、猫がいるかどうかも知らない。でも、開けると猫が入っているか、また猫が入ってないかわかる。というシュレディンガーなプラダな猫の話。

cats は最初から用意されているので、外部データとして存在します。メインプログラムのアリスから見れば、最初は、Prada のオブジェクトを作るだけなので、内部の _cat が存在するかどうかは知らない。というか、知らなくてもいい状態。Cat プロパティを呼んだときにはじめて、中の cat を取り出すことができる。鞄クラスの Prada から見える Cat プロパティは、外部からみれば単純にデータを返しているように見えるが、実際は別に用意されている cats から取り出している。
つまり、MVVM パターンでいえば、View が VM に対してプロパティアクセスでデータを取り出しているときに、VM は Model からデータを引っこ抜くわけだが、そこは View が VM に問い合わせたときまで遅延される方式になっている。MVVM の大抵の例は、Model が省略されていて、View から VM のアクセスしかないのだが、ここで VM と Model との違いが明確になるよという話だ。

こんな感じで MVVM パターンを使える。Model は常に VM から参照される「制限」を付けることで、MVVM パターンの役割が担えるということだ。

じゃあ、Model(データベースや計測器など)からデータが上がってくるようなときはどうするのか?ってのは別パターンを使うことになる。この話は別の記事に書くことにしよう。

カテゴリー: 設計 | アリスはプラダに猫がいることを知らない はコメントを受け付けていません