Index: [Article Count Order] [Thread]

Date:  Sun, 10 Sep 2000 01:01:36 +0900
From:  Kaoru Hosokawa <khosokawa@....com>
Subject:  [XP-jp:00861] Re: Member, MemberList, MemberAuthorization
To:  extremeprogramming-jp@....jp (extremeprogramming-jp ML)
Message-Id:  <B5E089B1.3579%khosokawa@....com>
In-Reply-To:  <50158B900247D411B8120090CC01C0EC1E05A5@....jp>
Posted:  Sun, 10 Sep 2000 00:59:19 +0900
X-Mail-Count: 00861

ホソカワです。

on 2000/09/06 3:07 PM, tetsuya@....jp at tetsuya@....jp wrote:

> 栗原です。
> 
> 太郎君が、MemberAuthorization を作成しようとしてふと考えました。
> (花子さんは今日は有給を取って休んでます(^_^;)
> 
> # 相方が休んでいれば、別の人とペアを組むと思うんですが、細かいと
> # ころは気にしないでください:-)
> 
> 太郎>
> 認証するということは、MemberList クラスが管理している Member
> クラスのメールアドレス値が、ひとつでも一致すればいいってことだか
> ら、、、、
> べたべたに実装すると、MemberList クラスから Member のリス
> ト(もしくは、Iterator)を取得して、ループさせて、、、
> っていう感じにつくれますね。
> なんか、わざわざ MemberAuthorization をつくる必要もあるのかどう
> か疑問だけど、MemberList が認証するのも変だから、良しとしておこ
> うかな。
> 
> それにしても、YAGNI とはいえ、Member が増えてくると気になるし
> 、インデックスでのアクセスもあまり必要なさそうに感じる(し、Java
> っぽくなくて、、)なぁ。
> 
> うーんと、サンプルをつくってみますか、、、カタカタカタ…
> 
> /*
> * @(#)MemberList.java
> */
> package jp.co.esm.wiki.xp;
> 
> import java.util.*;
> 
> public class MemberList {
> public void add(Member aMember) {
> members.put(aMember.getMailAddress(), aMember);
> }
> public Member get(String aMailAddress) {
> return (Member)members.get(aMailAddress);
> }
> public int size() {
> return members.size();
> }
> public Set memberSet() {
> return Collections.unmodifiableSet(members.entrySet());
> }
> public Set mailAddressSet() {
> return Collections.unmodifiableSet(members.keySet());
> }
> 
> private HashMap members = new HashMap();
> }
> 
> こんな感じだとどうだろう?
> MemberList の内部クラスに Iterator をつくるほどのものでもなさそ
> うだしこのぐらいで代用できそうだ。
> Member を取得するためのキーがメールアドレスのほうが何かと便利
> 、、、、あ、YAGNI 違反だ:-P
> それと、重複したメールアドレスははじくようにしないいけないな。
> まぁ、テストだけつくっておいて、実際にこのやり方に変えると決ま
> ってからでいいか。
> 
> 次は、こいつを使う認証クラスのほうだけど、、、、
> 
> /*
> * @(#)MemberAuthorization.java
> */
> package jp.co.esm.wiki.xp;
> 
> import java.util.*;
> 
> public class MemberAuthorization {
> public MemberAuthorization(MemberList aMemberList) {
> memberList = aMemberList;
> }
> public boolean verify(String aMailAddress) {
> return memberList.mailAddressSet().contains(aMailAddress);
> }
> 
> private MemberList memberList;
> }
> 
> こんな感じかな。結構シンプルに実装できそう。
> にしても、MemberList オブジェクトしか使ってないなぁ。
> やっぱり MemberList に移したほうがいいかなぁ。
> 
> さて、このコードを明日花子さんに見せてみるか。
> おっと、もちろんテストケースも作成済みなので、そいつと一緒にね。
> 
> /*
> * @(#)MemberListTest.java
> */
> package jp.co.esm.wiki.xp;
> 
> import junit.framework.*;
> 
> public class MemberListTest extends TestCase {
> public MemberListTest(String name) {
> super(name);
> }
> public static void main(String[] args) {
> junit.textui.TestRunner.run(MemberListTest.class);
> }
> public void testNewMemberList() {
> MemberList memberList = new MemberList();
> assertEquals(memberList.size(), 0);
> }
> public void testOneMemberList() {
> MemberList memberList = new MemberList();
> memberList.add(firstMember);
> assertEquals(memberList.size(), 1);
> }
> public void testDuplicationMember() {
> MemberList memberList = new MemberList();
> memberList.add(firstMember);
> try {
> memberList.add(firstMember);
> fail("Should raise an IllegalArgumentException");
> } catch (IllegalArgumentException e) {
> assert(true);
> }
> }
> public void testGetMember() {
> MemberList memberList = new MemberList();
> memberList.add(firstMember);
> memberList.add(secondMember);
> assertEquals(
> firstMember,
> memberList.get(firstMember.getMailAddress())
> );
> }
> public void testUnmodifiableMemberSet() {
> MemberList memberList = new MemberList();
> memberList.add(firstMember);
> memberList.add(secondMember);
> try {
> memberList.mailAddressSet().add("xxx@....zzz");
> fail("Should raise an UnsupportedOperationException");
> } catch (UnsupportedOperationException e) {
> assert(true);
> }
> }
> public void testUnmodifiableMailAddressSet() {
> MemberList memberList = new MemberList();
> memberList.add(firstMember);
> memberList.add(secondMember);
> try {
> memberList.memberSet().add(new Member("xxx@....zzz"));
> fail("Should raise an UnsupportedOperationException");
> } catch (UnsupportedOperationException e) {
> assert(true);
> }
> }
> protected void setUp() {
> firstMember = new Member("aaa@....ccc");
> secondMember = new Member("ddd@....fff");
> }
> 
> private Member firstMember;
> private Member secondMember;
> }
> 
> /*
> * @(#)MemberAuthorizationTest.java
> */
> package jp.co.esm.wiki.xp;
> 
> import junit.framework.*;
> 
> public class MemberAuthorizationTest extends TestCase {
> public MemberAuthorizationTest(String name) {
> super(name);
> }
> public static void main(String[] args) {
> junit.textui.TestRunner.run(MemberAuthorizationTest.class);
> }
> public void testValidMember() {
> assert(authorization.verify(firstMember.getMailAddress()));
> }
> public void testInvalidMember() {
> assert(!authorization.verify(invalidMember.getMailAddress()));
> }
> protected void setUp() {
> memberList.add(firstMember);
> memberList.add(secondMember);
> authorization = new MemberAuthorization(memberList);
> }
> 
> private MemberAuthorization authorization;
> private MemberList memberList = new MemberList();
> private Member firstMember = new Member("aaa@....ccc");
> private Member secondMember = new Member("ddd@....fff");
> private Member invalidMember = new Member("xxx@....zzz");
> }

Test-First Programming を実践しようと思っていますので、テストからコメントし
ます。

testValidMember() を、書き直して見ました

    private MemberAuthorizer authorizer;

    public void testValidMember() {
        assert(authorizer.isValid(firstMember));
    }

MemberAuthorization は、データを意味する名前ですので、MemberAuthorizer にか
えました。Authorizer という言葉はないと思いますが、許可を出す人と言うイメー
ジです。この人に firstMember は、正会員かどうか訪ねるというコードにしました。
メールアドレスをgetして渡すよりはシンプルだと思います。

MemberAuthorizer の isValid() は、

public boolean isValid(Member member) {
    return memberList.contains(member);
}

// public class MemberList
    
public boolean contains(Member member) {
    return memberList.mailAddressSet().contains(member.getMailAddress());
}

のように考えました。mailAddressSet() などはあまり外に出したくないという意図
があります。

#このコードもコンパイル、実行していません。

-- 
Kaoru Hosokawa
khosokawa@....com