PyPI とは
Python 用の 3rd パーティソフトウェアリポジトリ。
pip
はパッケージマネージャであり、PyPI
を標準の参照リポジトリとする。
仕様と設計の違い
将来どこかで誰かに
「仕様と設計を混同した時はこれ見といてね」と
言えることを念頭において書いた記事
「仕様」 と 「設計」 は別物
私なりの言葉で定義すると
仕様
= 作るものについて、満たされているべきことが定義されたもの
満たされているべきこととは「顧客が期待している結果」と「期待していない結果」のことだ
あなたが SE ならばこの定義について顧客と合意形成を取るべきだ
設計
= 仕様をどう実現するかが具体的に明確化されたもの
設計を基に SE と PG で意思疎通を図る
具体的な手段(モノ)として設計書がある
具体例を挙げるのでおおよその感覚を掴んでいただければ幸い
(突っ込み所は色々あると思うがスルーでお願いしたい)
例 - 顧客からのブログ Web アプリ作成依頼
あなたは SE だ(時には PG だったりする)
ある顧客から実現したいことについて依頼を貰った
依頼内容
弊社内で完結させる、ブログ Web アプリが欲しい 直近で (1) を実現してほしい (1) タイトル・内容 を投稿できる画面を作る 補足しておくと 今考えている画面総数は 3 つ 記事を投稿できる画面 記事の一覧を表示する画面 記事の内容を確認する画面 (資料を添付するので見ておいてください)
添付資料
顧客の依頼内容は「作るものがどうあるべきか」を示した「仕様」だ、「設計」ではない
「設計」はまだだ
あなたは「ご依頼を一度預かります」と伝え、依頼内容を確認する
「この依頼内容でシステムへ落とし込めるが、幾つか顧客が期待する結果を聞かないといけない」
と考えた
そう、入力制限がないことに違和感を覚え始めているはず
依頼内容を精査し、顧客に次の質問を持ちかけた
- タイトルの文字数はいくつまで可能? (これは仕様だ)
- タイトルは未入力を許してよい? (これも仕様だ)
- 内容の文字数はいくつまで可能? (仕様だ)
- 内容は未入力を許してよい? (これも)
その結果こうなった
(1) タイトル・内容 を投稿できる画面を作る (1) - 1 タイトルは 255 文字まで (1) - 2 内容は 1,000 文字まで (1) - 3 タイトルのみ 未入力、空白記号のみの入力で投稿はできないようにする
繰り返しになるが、これは「仕様」であり、実施していたのを仕様を決める行為だ
「設計」は一つもやっていない = 仕様をどう実現するかの具体化は、まだ何もやっていない
仕様を決めていた
ここからようやく「設計」だ
仕様で決まったことをどう実現するかを具体的に明確化しよう、ここから設計だ
あなたが 開発の設計者なら次の設計をするだろう
- ユースケースを書いてユーザー視点の実行パターンを明確化する
- ER 図を書いてテーブル連携の明確化する
- (もう少しコード側に突っ込んで)
文字数バリデーションを実行する手段を明確化する - 他、色々
- (設計書には仕様の説明は書かない。仕様は自明である前提だ)
テストの設計者なら別のことをするかもしれない
仕様を決めた後に設計をする
蛇足
1
「ここからようやく「設計」だ」に関する項目が曖昧だが...
この辺り勉強中なので、色々わかり次第またの機会に
2
仕様を相談するくだりは
説明用ということでその内容を簡素(削った、という方が正確)にしたが
あなたなら顧客へ他に何を質問・相談するだろうか、考えてみてほしい
動機付けになった Web リソース
参考にした Web リソース
Java の interface method に public や abstract を宣言してもよいか
interface MyInterface { public abstract void myMethod(); // public と abstract の宣言 }
Oracle の Docs より
「してもよいが、冗長なので奨められない」
意訳(一部)
interface のメソッドは暗黙のうちに public である interface のメソッドは暗黙のうちに abstract である, なのでブロックは持たずセミコロンで表現されている必要がある public と abstract どちらか/両方 を interface のメソッドで宣言してもよいが、 冗長なので奨められるされるやり方ではない
意訳(一部)元
Every method declaration in the body of an interface is implicitly public. Every method declaration in the body of an interface is implicitly abstract, so its body is always represented by a semicolon, not a block. It is permitted, but discouraged as a matter of style, to redundantly specify the public and/or abstract modifier for a method declared in an interface.
struts.xml の global-exception-mappings とは何か
struts2-core v2.3.28
global-exception-mappings とは
はじめに、Struts2 には Exception mappings
という機能がある
これは Action
内で throw
された例外を自動的に catch
し
あらかじめ用意された result
へマッピングする機能である
この Exception mappings
で
どの result
へマッピングするかを定義する xml 属性が
global-exception-mappings
である
2 点注意が必要
1(X)
ローカルのマッピング(action.exception-mapping
)を定義できるが
これを有効化した時、グローバルのマッピング(global-exception-mappings
)は無効化される
2(Y)
あくまで action#class
の execute
内で発生した例外をマッピングするもので
action#class
のコンストラクタ内で throw
された例外はマッピングされない
具体的に
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <global-results> <result name="myException">/Exception.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="java.lang.Exception" result="myException" /> </global-exception-mappings> <action name="index" class="jp.ymatsukawa.top.Index"> <result name="success">/index.jsp</result> </action> </package> </struts>
/top/index.action
へ GET リクエストされたとする
action#class=jp.ymatsukawa.top.Index
で Exception
が throw
された場合
global-exception-mappings
が Exception
を捕捉する
この時 exception-mapping#result
に対応する result
を実行する
上の場合だと result
は myException
なので
global-results.result#name="myException"
が実行される
(/Exception.jsp
が dispatch
される)
(X)
(動作確認より)
global-exception-mappings.exception-mapping
を定義後
action.exceptoin-mapping
を用いて
個々の action
に exception-mapping
を定義することができる
ただし、その場合は global-exception-mapping
の設定は無効になる
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <global-results> <result name="myException">/Exception.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="java.sql.SQLException" result="myException" /> </global-exception-mappings> <action name="index" class="jp.ymatsukawa.top.Index"> <exception-mapping exception="java.lang.RuntimeException" result="error" /> <result name="success">/index.jsp</result> <result name="error">/myError.jsp></result> </action> </package> </struts>
もし jp.ymatsukawa.top.Index
で
java.sql.SQLException
が throw
されても
/Exception.jsp
は dispatch
されず
/myError.jsp
が dispatch
される
(global-exception-mappings.exception-mapping#exception=java.lang.Exception
でハンドリングをまとめておき、個々の action
で
Exception
以外の例外捕捉を必要に応じて追加するのが良いか...)
(Y)
jp.ymatsukawa.top.Index
のコンストラクタが 例外を throw
し得る場合
global-exception-mappings
はこの例外をマッピングしない
極端な例
package jp.ymatsukawa.top.Index; import com.opensymphony.xwork2.ActionSupport; public class Index extends ActionSupport { public Index() throws Exception { throw new Exception; } @Override public String execute() { return SUCCESS; } }
この場合、Struts2 は例外マッピング、例外ハンドリングすることなく、エラー処理を実行する
[参考元]
struts.xml global-results 要素とは何か
struts2-core v2.3.24.1
struts.xml global-results 要素とは何か
action
間で共有したい result
がある時、これを定義する為の要素
package
ごとにglobal-results
を定義できる- Struts2 は先ず ローカルの
result
(package.action.result
)を走査する- ローカルで
result
が見つからない場合、global-results
を走査する
- ローカルで
(要素の設置順序が決まっているようなので設定ミスしないように)(X)
具体的に
或る package の result#name="error"
を共通化する
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <global-results> <result name="error">/error.jsp</result> </global-results> <action name="index" class="jp.ymatsukawa.top.Index"> <result name="success">/index.jsp</result> </action> </package> </struts>
action
要素の前に global-results
を設定する
global-results
の下に共通化したい result
を設定する
global-results.result を action.result で上書きできるか
できる
上の例より result#name="error"
の時
/error.jsp
ではなく, /myError.jsp
を render させたい場合は
下のように設定する
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="top" extends="struts-default"> <global-results> <result name="error">/error.jsp</result> </global-results> <action name="index" class="jp.ymatsukawa.top.Index"> <result name="error">/myError.jsp</result> <result name="success">/index.jsp</result> </action> </package> </struts>
(X)要素の設定順序に注意
action
の前に global-results
を設定する
要素は上から順に以下の通りである
result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-allowed-methods?, global-exception-mappings?, action*
[参考元]
https://struts.apache.org/docs/result-configuration.html#ResultConfiguration-GlobalResults
http://stackoverflow.com/questions/3742379/struts2-global-results-configuration-error