- PR -

設定情報の保存法について

投稿者投稿内容
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-11-14 13:05
引用:

刹那さんの書き込み (2005-11-14 12:39) より:

保守性、人間に分かりやすいのはINIのほうだと思うのですが。
XMLの場合タグを使った入れ子なのでぱっと見では分かりにくいと僕は感じます(人それぞれでしょうが)
っと、この意見がかなりじゃんぬさんの言いたいこととずれている気がします(汗。保守性=メンテナンス性=どれほどメンテナンスが行いやすいか=人間に理解しやすいか?と解釈したのですが…間違いがあればご指摘ください。


渋木さんに先を越されましたが、保守性というのは拡張性も含みます。
たとえば、INI ファイルは複数階層を表現できません。(擬似的には可能)

「エンドユーザーが保守しにくいから INI ファイルなんだ」と言うのであれば、
管理者用の設定ダイアログでも用意してあげてください。
これなら、開発者のメンテナンスも楽でしょう。
同じことを IniFile クラス で書いていたりします。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
笊頭刹那
ベテラン
会議室デビュー日: 2005/10/17
投稿数: 55
お住まい・勤務地: オーストラリア
投稿日時: 2005-11-14 19:16
>渋木宏明さん
たしかにそう考えるとXMLは非常にシンプルですよね。打つのめんどくさいですが(笑。
XMLなどの複雑なものになると最初に書いたものを後で見たときに全部書き換えたくなる性分があって(自サイトのHTMLを何度すべて書き換えたことか…w)めんどくさいと感じていましたが、入れ子ってのは魅力なんですよね(それに加えて速度・推薦されている・次の世代の技術ってのが僕の背中を押したんですが)

>じゃんぬさん
なるほど、拡張性…たしかに拡張性が悪いものはメンテナンスが行いやすいとは言えませんね、実際前回作ったスキン構造で入れ子を表現できなくてどうしようか非常に迷いましたし…やはりXMLです…ね。

--------------------------------------------------------------------------------
管理者用の設定ダイアログでも用意してあげてください。
--------------------------------------------------------------------------------

結局エディタを作る運命からは逃れられない…か、エディタを作る作業というのが非常に退屈なので(コラっ)極力避けたかった(逃げたかった)んです。


今のところ、コードの綺麗さ、拡張性も含めシリアライズを利用したXMLの方法でいってみようと考えています(「ほげたさん」に改良してもらったタイプで)、この方法だとエディタ必要ですね(どんなXML作られるかわからないので、最悪でも僕が使えるエディタが…)がんばります、エディタで飽きるなよ!俺。

たくさんの回答ありがとうございました!
ぼのぼの
ぬし
会議室デビュー日: 2004/09/16
投稿数: 544
投稿日時: 2005-11-14 20:25
Iniファイルで設定可能なほどシンプルな内容なら、IniファイルをXMLに変換するツールを作れば、エディタ不要だったり…

#無責任思いつき発言w
笊頭刹那
ベテラン
会議室デビュー日: 2005/10/17
投稿数: 55
お住まい・勤務地: オーストラリア
投稿日時: 2005-11-14 20:35
あ、前作から改良加えるつもりだったんでXmlで書くと決めたら入れ子状態が続きますんで…そのアイディア考えたんですが、コンバータ作るほうがエディタ作るより大変かな?っと(汗。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-11-14 21:05
 一応、載せておきますね。
SoapFormatter が出す XML 例
コード:
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0"
 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
	<SOAP-ENV:Body>
		<a1:ApplicationEnv id="ref-1"
		 xmlns:a1="http://schemas.microsoft.com/clr/nsassem/所属するアセンブリの厳密名">
			<ClassVersion>4</ClassVersion> XML で規定されている型は、こんな感じ
			<DatabaseSystem href="#ref-3"/> 規定されていない型は、このように分解される
		</a1:ApplicationEnv>
		<a1:DatabaseAccess id="ref-3" href="#ref-3" と対応する
		 xmlns:a1="http://schemas.microsoft.com/clr/nsassem/所属するアセンブリの厳密名">
			<pSelectedDatabase>ORACLE9i</pSelectedDatabase>
			<pDBSetting href="#ref-10"/>
		</a1:DatabaseAccess>
以下略


用途については、リファレンスに書かれていますので、参照してください。

 これ、使いようによっては、Windows の「サスペンド」みたいな使い方が出来ます。もっとも、BinaryFormatter を使いましょう、ですけど。BiralyFormatter も、SoapFormatter も、同じメソッドを使うので、意図したとおりにシリアライズ出来ているかの確認をするために、一時的に SoapFormatter を使う、という手もあります。


 本題に戻って、
エンドユーザがメンテナンスする為にファイル名を書く、ようにすると、そのファイル名が妥当でないとき、ファイルを削除やリネームされたときの処理が必要になります。この辺は、どうお考えでしょうか?
 この対策がきちんと出来るのであれば、ファイル名を書くでいいと思います。
 また、エディタも、Office2003 なら、XML の編集に利用することも出来ますから、特に問題にはならないでしょう。

ん???これ、使えませんか?Word2003 で、ビットマップを貼り付ければ、XML に埋め込まれません?ちょっと今、2003 の環境がないので、確かめられませんが。スキーマもいるのかな?
# 書いている今、書き込めないのがもどかしい。。。
___________________________________________________________________
□ written by Jitta on 2005/11/14
□ Microsoft MVP for Visual Developer ASP/ASP.NET Oct.2005-Sept.2006
_________________
笊頭刹那
ベテラン
会議室デビュー日: 2005/10/17
投稿数: 55
お住まい・勤務地: オーストラリア
投稿日時: 2005-11-14 21:18
>Jitta
-----------------------------------------------------------------------------------
BiralyFormatter も、SoapFormatter も、同じメソッドを使うので、意図したとおりにシリアライズ出来ているかの確認をするために、一時的に SoapFormatter を使う、という手もあります。
-----------------------------------------------------------------------------------
すごい、それは知らなかった!使える…バイナリだと確認が…なので(笑。まぁ今回には関係ないですが。

ファイル名についてですが
skin[directory]
 適当な名前[directory]
  skin.xml
  images[directory]

って感じです、わざわざ開いて画像ファイルだけを削除したら自己責任で再インストール(再解凍)してもらうしかないですね。

ユーザさんが改造することは考えてません、壊したら自己責任ということで。

スキン開発者さんがちょこちょこいじった場合にファイルなどは相対で指定してます(うえず)、一応目標としてスキンフォルダを圧縮して配る(firefoxみたいな?)感じにするつもりなのでユーザーが消すことは無いとして考えています、それでもファイルが見つからない場合はエラーダイアログにスキン製作者の問合せ先を書いてそっちに責任を押し付けるという(なんとも自分勝手な)つくりになっています。

Word持ってないんです…orz OpenOffice使っているので…せっかくですが使えません、すいません。
笊頭刹那
ベテラン
会議室デビュー日: 2005/10/17
投稿数: 55
お住まい・勤務地: オーストラリア
投稿日時: 2005-11-14 21:19
>Jitta
となっていますがさんつけるの忘れただけです(汗っっ
失礼お許しください(_ _(--;(_ _(--; ペコペコ
笊頭刹那
ベテラン
会議室デビュー日: 2005/10/17
投稿数: 55
お住まい・勤務地: オーストラリア
投稿日時: 2005-11-15 15:10
後々の拡張性や変更した場合の安全性も考慮しリフレクションなどを使って自作シリアライズ作りました。

コード:
// Field
FieldInfo[] fs = type.GetFields(BindingFlags.Public 
	| BindingFlags.Instance | BindingFlags.Static);

for(int i=0;i<fs.Length;i++)
{
	FieldInfo f = fs[i];

	// Write
	WriteContentsElement(f.Name,f.GetValue(o),w);
}

		private void WriteContentsElement(string name,object o,XmlTextWriter w)
		{
			// Prepare
			w.WriteStartElement(name);

			// Contents
			#region Contents

			switch(o.GetType().Name)
			{
				case "ImageFile":
				{
					ImageFile ifile = (ImageFile)o;
					w.WriteElementString("FileName",ifile.FileName);
					break;
				}
				case "Font":
				{
					Font font = (Font)o;
					w.WriteElementString("FontFamily",font.FontFamily.ToString());
					w.WriteElementString("Size",font.Size.ToString());
					w.WriteElementString("Style",font.Style.ToString());
					break;
				}
…以下略

// Field
FieldInfo[] fs = type.GetFields(BindingFlags.Public 
	| BindingFlags.Instance | BindingFlags.Static);

for(int i=0;i<fs.Length;i++)
{
	FieldInfo f = fs[i];

	// Read
	object o = ReadContentsElement(f.Name,f.FieldType,r);
	f.SetValue(obj,o);
}

			switch(t.Name)
			{
				case "ImageFile":
				{
					string filename=r.ReadElementString("FileName");
					result = new ImageFile(filename);
					break;
				}
				case "Font":
				{
					string fontfamily,size,style;
					fontfamily=r.ReadElementString("FontFamily");
					size = r.ReadElementString("Size");
					style = r.ReadElementString("Style");
					FontStyle fs = FontStyle.Regular;
					if(style.IndexOf("Bold")>=0)
						fs|=FontStyle.Bold;
					if(style.IndexOf("Italic")>=0)
						fs|=FontStyle.Italic;
					if(style.IndexOf("Underline")>=0)
						fs|=FontStyle.Underline;
					if(style.IndexOf("Strikeout")>=0)
						fs|=FontStyle.Strikeout;
					result = new Font(fontfamily,float.Parse(size),fs);
					break;
				}
...
				case "SByte":
					result = sbyte.Parse(r.ReadString());
					break;
				case "Byte":
					result = byte.Parse(r.ReadString());
					break;
				case "UInt16":
					result = ushort.Parse(r.ReadString());
					break;
				case "Int16":
					result = short.Parse(r.ReadString());
					break;
...
				case "String":
					result = r.ReadString();
					break;
				default:
				{
					if(t.BaseType == typeof(Enum))
						result = Enum.Parse(t,r.ReadString(),false);
					else
						result = null;
					break;
				}

【ところどころ略をしました。】



動作も快適でこの方法で満足しているのですがdouble値だけうまくいきません。

流れのイメージとしては
object o = double.MaxValue;
w.WriteString(o.ToString());
と保存し
string v = r.ReadString();
object o = double.Parse(v);
return o;
として返して、Activator.CreateInstanceで作ったSamileInfo形のフィールド変数のDouble型に追加しているのですが(上記コード参照してください)。

double.Parse(v)のところで
「値がでかすぎかちいさすぎです」
って言われます。これってバグでしょうか?double.MaxValue使って取得した値なのでそんなはずはないと思ったのですが…(※ 確認してみましたが書き込み前・書き込み後・読み込み後で値の変化はありませんでした)

特にdouble使うわけではないので問題ないのですが気になったので。



くわえ、このような方法を取っていますが、なにか問題あるでしょうか?保守性も高く速度も上々だと思うのですが、まぁ小さなクラスでしか確認をしていませんが。

何かこの方法に対する問題点などをご存知の方がいらっしゃいましたらご教授お願いいたします。

スキルアップ/キャリアアップ(JOB@IT)