.netの最近の情報

オブジェクト指向と言いつつ、クラスをインスタンス化させたくない場面は

よくあることです。

 

私の経験上では主に2つ。

 

  1. ユーティリティクラス
    他の色々なクラスから共通で利用されるメソッドを実装する。
    共通関数群のような使い方をするが、そのたびにクラスを
    インスタンス化して利用するのはコードもわかりにくくなるし、
    そもそもオブジェクトとして利用する意味がない。

    この場合、Java等でも同様だと思うが、staticなメソッドを定義し
    インスタンス化せずに手軽に共通メソッドを利用できるようにする。
    その際、インスタンス化自体が無意味なので、コンストラクタを
    private で宣言するのが一般的です。


    public class StringUtil
    {
        private StringUtil
        {
            //インスタンス化不可
        }

        public static Find(string source, string search)
        {
            return ...
        }
    }


  2. シングルトンクラス(シングルトンパターン)
    オブジェクトをシングルトンにしたい場合に使用する。
    シングルトンとはアプリケーション内であるクラスのインスタンスは
    唯一であることを保証するクラスのこと(例:プリンタスプーラなど)

    クラスが内部的にそのクラスのオブジェクトをひとつだけインスタンス化し、
    インスタンスが必要な場合にかならず、唯一のオブジェクトへの参照を
    返すという仕組みである。

    public class Singleton
    {
        private static obj = new Singleton();

        private Singleton
        {
            //インスタンスの取得は、GetInstanceメソッドで
        }

      public static Singleton GetInstance
        {
            return obj;
        }
    }


C#2.0からは、上記のように、無理やりコンストラクタを、privateにして

インスタンス化できないようにするという、よく考えると無理やりな手法

ではなく以下のようにスマートに記述できるようになった。

class定義の前に、staticを付加すると、そのクラスは自動的に静的な

クラスとなり、以下のような特徴を持つようになる。

 

  • 静的メンバのみを含みます。
  • インスタンス化できません。
  • シールされます。
  • インスタンスコンストラクタを含むことができません

コンストラクタを記述しても言語レベルでエラーが検出され、

コンパイルすることができなくなります。

このクラスを利用し、静的フィールド、静的メソッドだけを使用した

ユーティリティクラスやシングルトンの仕組みも簡単に実装できます。

絶対現場主義Visual C#実践講座

 

著者:丸岡 孝司 

発行日:2007年7月25日

発行者:黒田 康夫

発行所:株式会社ラトルズ

411ページ

2,600円+税

 

内容

開発の現場から生まれた実践テクニック&TIPS集。

"Visual C# プログラミング"という大海原をひとりゆくプログラマのために。

  • Chapter1 .NET FrameworkとC#プログラミング
    Visual Studioの使い方、C#コーディング方法、C#のデータ型、制御構造
    などの言語仕様に関するテクニックやTIPSを収録。

  • Chapter2 Windowsアプリケーション
    Windowsフォームやコントロールを使用した、Windowsアプリケーション
    作成のテクニックやTIPSを収録。

  • Chapter3 データベース処理
    .NET Frameworkにおけるデータベース処理に関するテクニックやTIPS
    を収録。

  • Chapter4 Webとネットワーク
    .NET Frameworkにおけるネットワーク処理について簡単に紹介。

 

ポイント

職場で一緒に仕事している人からのお勧めの一冊。借りました。

現在、C#のプロジェクトを一から作り始めて進行中なので、フレームワーク

作りの参考にしました。

 

タイトル "絶対現場主義" にもあるように、実際に現場で開発をする人たち

にとって役立つ内容となっています。

 

特に、C#プロジェクトはまだあまり経験がないけど、こんな感じでいいのかなぁ

とか、Javaのプロジェクトは経験したけど、C#ではどうするべきか・・・(悩)とか、

昔ながらのVBスタイルのプログラムは書けるけど、C#ってオブジェクト指向が

ベースだし、クラスとか、継承とか、カプセル化もいまいち良くわかんないよなぁ

とか・・そんな悩める人たちの手助けになると思います。

 

書き方も、従来の単純な解説書やリファレンス、TIPS集などとは違い、いちいち

現場目線での解説(こういう背景だからこんな疑問が発生し、こう解決すれば

良いのでは?スタイルでの記述)がされており非常に読みやすくなっています。

例示されているシーンも、一度は誰もが悩んできたであろう内容で納得できます。

(その分、普通のTIPS集では1ページで書かれている内容が3~5ページかけて

解説されていたりしますが・・)

 

特に、Windowsアプリケーションでは、開発のフレームワークをどうするべきかや、

コントロールの拡張方法、共通化などについても詳しく書かれていますので、

実際のプロジェクトの参考にできると思います。

 

最後に、Webアプリケーションの事については紹介として少しだけ解説されて

いますが、つい先日、この書籍の、"Webアプリケーション編"が出版されたよう

ですので、紹介だけしておきます。※私は.NETだと、APS.NET MVCの方に

興味があるため、こちらの書籍(MVCについては触れられていなさそう?)

なので購入するかどうかは今のところ未定です。

 

 絶対現場主義Visual C#実践講座(Webアプリケーション編)

 

  

最近仕事でC#をメインで使うようになってきたので。

新しいこともいろいろと習得中です。

 

業務アプリケーションにデータベース処理はつきもので、

さらにデータベース処理には、トランザクションがつきもので、

またまたトランザクション処理にはコミットと、ロールバックが・・・

 

今まではどんな言語を使うにしろ、トランザクション処理では、

トランザクションの開始と、コミット、そして例外時にはロールバックと

明示的に記述していた。

 

C#で、SqlTransactionを利用した従来の書き方

using (SqlTransaction tran = con.Begin.Transaction())

{

    try {

        //SQLによるデータベース更新処理

        :

        //コミット

        tran.Commit();

    }

    catch {

        //ロールバック

        tran.Rollback();

    }

}

 

しかし.NET Framework2.0ではもう少し簡単に書けるようになった、

System.Transaction.TransactionScopeクラスが用意されている。

TransactionScope.Complete()メソッドが呼ばれるとコミットされ、

TransactionScope.Dispose()メソッドが呼ばれるとロールバック

される仕組みとのこと。

なので、usingステートメントと組み合わせて、以下のように書ける。

using (TransactionScope tran = new TransactionScope()) {

    //SQLによるデータベース更新処理

    :

    //コミット

    tran.Complete();

}

※例外が発生したり、Complete()メソッドを呼び出さずに、

usingステートメントを抜けると自動的にロールバックされる。

 

また、TransactionScope クラスには自動的にコネクションや、

SqlCommandクラスを検出する機能があるため、今までのように

明示的にコネクションやSqlCommandのインスタンスとトランザクション

のインスタンスを結びつける必要が無くなっているのもポイント。

 

 

前回は、twitterの最新のつぶやきを表示する、

簡単なアプリケーションを作成してみました。

 

ロジックとしては、twitterで指定されたAPIを呼び出し、

XML形式のデータを取得し、XPathでXMLデータを解析して

表示するといった内容でした。

 

今回は、Webの世界ではXMLより手軽に扱えるとされている、

JSON形式のデータを扱うことにします。twitterのAPIでも標準で

JSON形式のデータに対応されています。

 

今回も、C#.netを使用してアプリケーションを作成してみました。

(プログラムの機能は前回と同じです)

 

ダウンロード

20090914.jpg

※実行にはJson.NETのライブラリも必要です(ダウンロード

 

JSON形式のデータをC#で定義したクラスにマッピングすることで、

マッピング後のデータの操作が簡単・柔軟になります。

 

ソース(TwitterForm.cs)

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Net;
using System.IO;
using Newtonsoft.Json;

namespace TwitterApplication
{
    public partial class TwitterForm : Form
    {
        public TwitterForm()
        {
            InitializeComponent();
            lstItems.Items.Clear();
        }

        private String GetTweet(String URL)
        {
            //Request
            HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(URL);
            Request.Method = "GET";
            WebResponse Response = Request.GetResponse();
           
            //Read
            StreamReader Readar = new StreamReader(Response.GetResponseStream());
            String Results = Readar.ReadToEnd();

            //Return
            Readar.Close();
            Response.Close();
            return Results;
        }

        private void btnTimeLine_Click(object sender, EventArgs e)
        {
            String URL = "http://twitter.com/statuses/user_timeline/" + txtUser.Text + ".json?count=50";
            String JSON = GetTweet(URL);
            List<Status> StatusList = (List<Status>)JsonConvert.DeserializeObject(JSON, typeof(List<Status>));
           
            lstItems.Items.Clear();
            lstItems.HorizontalScrollbar = false;
            foreach (Status StatusObject in StatusList)
            {
                lstItems.Items.Add(StatusObject.Text);
            }
            //ScrollBarSetting
            lstItems.HorizontalScrollbar = true;
        }
    }
}

 

ソース(Twitter.cs)

namespace TwitterApplication
{
    public sealed class Status
    {
        public string In_reply_to_status_id { get; set; }

        public bool Favorited { get; set; }

        public string In_reply_to_user_id { get; set; }

        public string Source { get; set; }

        public string Created_at { get; set; }

        public string In_reply_to_screen_name { get; set; }

        public User User { get; set; }

        public string Id { get; set; }

        public bool Truncated { get; set; }

        public string Text { get; set; }
    }

    public sealed class User
    {
        public string Profile_sidebar_border_color { get; set; }

        public string Description { get; set; }

        public string Url { get; set; }

        public string Screen_name { get; set; }

        public string Following { get; set; }
           
        public bool Verified { get; set; }

        public string Profile_text_color { get; set; }

        public int Followers_count { get; set; }

        public string Profile_background_image_url { get; set; }

        public string Created_at { get; set; }
       
        public string Notifications { get; set; }

        public int Friends_count { get; set; }

        public string Profile_link_color { get; set; }

        public bool Profile_background_tile { get; set; }
       
        public int Favourites_count { get; set; }

        public string Profile_background_color { get; set; }

        public bool Protected { get; set; }

        public string Time_zone { get; set; }
       
        public string Location { get; set; }

        public string Name { get; set; }

        public string Profile_sidebar_fill_color { get; set; }
       
        public string Id { get; set; }

        public int Statuses_count { get; set; }
       
        public int Utc_offset { get; set; }

        public string Profile_image_url { get; set; }
    }
}

 

twitter(ツイッター)とは、"つぶやき"という短いテキストを投稿して公開する

サービス(マイクロブログサービス)である。

 

ま、大抵の人は名前だけは知っていると思いますが、このtwitterには、API

が公開されており、簡単に呼び出して外部アプリ等と連携することができます。

 

今回は、C#.netを使用してアプリケーションを作成してみました。

  • C#.net 2008
  • .net framework2.0

ダウンロード

 

20090913.jpg

 

内容は、テキストボックスに、ユーザ名を入力して表示ボタンを押すと、

リストボックスに最新のつぶやきが50件まで表示されるというシンプルなもの。

 

APIとしては、

http://twitter.com/statuses/user_timeline/ユーザ名.xml?count=50

上記へリクエストした結果のXMLを解析して表示するだけです。

コメント"count"パラメータが取得する最大件数です。

XPathにて"//statuses/status/text"のノードリストを取得します。

 

ソースコード

using System;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Xml;

namespace TwitterApplication
{
    public partial class TwitterForm : Form
    {
        public TwitterForm()
        {
            InitializeComponent();
            lstItems.Items.Clear();
        }

        private String GetTweet(String URL)
        {
            //Request
            HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(URL);
            Request.Method = "GET";
            WebResponse Response = Request.GetResponse();
           
            //Read
            StreamReader Readar = new StreamReader(Response.GetResponseStream());
            String Results = Readar.ReadToEnd();

            //Return
            Readar.Close();
            Response.Close();
            return Results;
        }

        private void btnTimeLine_Click(object sender, EventArgs e)
        {
            String URL = "http://twitter.com/statuses/user_timeline/" + txtUser.Text + ".xml?count=50";
            String XML = GetTweet(URL);
            XmlDocument Doc = new XmlDocument();
            Doc.LoadXml(XML);
            XmlNodeList XMLNodes = Doc.SelectNodes("//statuses/status/text");

            lstItems.Items.Clear();
            lstItems.HorizontalScrollbar = false;
            foreach (XmlNode Node in XMLNodes)
            {
                lstItems.Items.Add(Node.InnerText);
            }
            //ScrollBarSetting
            lstItems.HorizontalScrollbar = true;
        }

        private void TwitterForm_Load(object sender, EventArgs e)
        {

        }
    }
}

 

 

JANコード

JANコードとは、ご存じのとおり、日本で最も普及している、

商品識別コードおよびバーコードの規格のひとつです。

 

商品のパッケージや梱包された箱に印刷されたり、シールが貼付けられ、

商品を識別するための情報として、POSシステムや、販売管理・在庫管理等、

様々なシステムで利用されています。

 

構成

JANのコード体系(構成)は以下のようになっている。

標準の13桁のコードまたは、8桁の短縮のコードが存在する。

13桁

 国コード(2桁) + メーカコード(5桁) + 商品コード(5桁) + チェックデジット(1桁)

 国コード(2桁) + メーカコード(7桁) + 商品コード(3桁) + チェックデジット(1桁)

8桁

 国コード(2桁) + メーカコード(4桁) + 商品コード(1桁) + チェックデジット(1桁)

 

日本の国コードは、"49"または"45"となっている。

 

チェックデジット

チェックデジットは、コードの入力誤りや、バーコードの読み取りミスを防止するために、

12桁のコードから算出した、誤り検出用の付加コードです。

コードを読みとった際に、再度チェックデジットを計算し、読み取ったチェックデジットと

相違がないかで確認をすることができる。

 

JANコードの作成

上記のように、JANコードは決められたルールを基に作成されていることがわかる。

特に、チェックデジットについては、作成した12桁のコードからさらに計算をおこない

13桁目のコードを算出することになる。

※チェックデジットの算出についてはここを参照。

 

そこで、簡単ではあるが、JANコード作成用のプログラムを作成してみた。

国コードは、"49"または"45"より選択し、メーカコード(5桁)、商品コード(5桁)の

タイプで入力し、"作成"ボタンを押すと、チェックデジットを計算し、13桁のJAN

コードを表示するという単純なものです。

※とりあえず最低限の対応をしてみました。

 

20090124.jpg

 

[JANコード作成]

 

(注)

C#でのプログラミングは慣れていないので、とりあえず動作するように、

調べつつ作成しています。より洗練されたプログラム記述あれば、

コメントください。

 

コード

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace JanCodeMaker
{
    public partial class frmJan : Form
    {
        public frmJan()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            cmbCountry.SelectedIndex = 1;
            txtMaker.Text = "";
            txtSyohin.Text = "";
            txtJan13.Text = "";
        }

        private void frmJan_Shown(object sender, EventArgs e)
        {
            txtMaker.Focus();

        }

        private void frmJan_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter) {
                bool forward = e.Modifiers != Keys.Shift;
                this.SelectNextControl(this.ActiveControl, forward, true, true, true);
                e.Handled = true;
            }

        }

        //チェックディジットを計算する
        private void btnMake_Click(object sender, EventArgs e)
        {
            string source = cmbCountry.Text + txtMaker.Text + txtSyohin.Text;
            if (source.Length != 12) {
                MessageBox.Show("12桁で入力してください。");
            }

            int chk1 = 3 * (Int16.Parse(source.Substring( 1, 1)) +
                            Int16.Parse(source.Substring( 3, 1)) +
                            Int16.Parse(source.Substring( 5, 1)) +
                            Int16.Parse(source.Substring( 7, 1)) +
                            Int16.Parse(source.Substring( 9, 1)) +
                            Int16.Parse(source.Substring(11, 1)));
            int chk2 = 1 * (Int16.Parse(source.Substring( 0, 1)) +
                            Int16.Parse(source.Substring( 2, 1)) +
                            Int16.Parse(source.Substring( 4, 1)) +
                            Int16.Parse(source.Substring( 6, 1)) +
                            Int16.Parse(source.Substring( 8, 1)) +
                            Int16.Parse(source.Substring(10, 1)));
            int chk3 = 10 - ((chk1 + chk2) - (((chk1 + chk2) / 10) * 10));
           
            if (chk3 == 10) { chk3 = 0; }
            txtJan13.Text = source + chk3.ToString();
            //MessageBox.Show(chk1.ToString() + "/" + chk2.ToString() + "/" + chk3.ToString());
        }

    }
}

ADO.net

ADO.netでは、従来のADOと違い新しいアーキテクチャでのデータアクセスが採用されている。

データソースとの接続に使用されるデータプロバイダ、非接続時でのデータアクセスを可能にするデータセットが用意されている。

 

データプロバイダにて接続型データアクセスを可能にし、必要に応じ、続されたデータソースからデータセットを作成(Fill - 充填)し、非接続のアクセスを可能にするというイメージとなる。

 

接続型データアクセス

1.Connectionオブジェクトにて、データソースとの接続を確立

2.Commandオブジェクトにてテーブルデータの取得、SQLステートメントの実行、プロシージャの呼び出しをおこなう。

3.DataReaderオブジェクトにて結果セットからデータを取得する(結果セットの取得は順方向のみ可能)※この仕様によりパフォーマンスを上げることが可能になる。

4.必要に応じTransactionオブジェクトにてトランザクション制御をおこなう。

 

非接続型データアクセス

※1~2:接続型データアクセスと同様(データソースから結果セットを取得)

1.Connectionオブジェクトにて、データソースとの接続を確立

2.Commandオブジェクトにてテーブルデータの取得、SQLステートメントの実行、プロシージャの呼び出しをおこなう。

3.非接続アクセスをおこなうため、DataAdapterオブジェクトを作成する。

4.DataAdapterオブジェクトにてデータソースから取得した結果セットを、非接続操作が可能な、Datasetオブジェクトに格納(充填)する。※DataAdapter.Fillメソッドを使用する。

5.非接続にてデータの操作をした後、DataAdapter.Updateメソッドにて更新された情報をデータソースへ反映させることが可能。

 

データアクセス

データアクセスは上記のとおり各オブジェクトを用いておこなうが、データソース(データベース)の種類に応じ各オブジェクトを使い分ける。※プログラミングモデルは共通のため同じコーディング方法にてデータアクセスが可能。

SqlConnection    ... SQLServer用

OleDbConnection  ... OLE DB(Access等)用

OracleConnection  ... Oracle用

OdbcConnection   ... ODBCデータソース用

 

同様に、xxxCommand、xxxDataAdapter、xxxTransactionオブジェクトを使い分ける。