当前位置: 技术问答>java相关
some thoughts about immutable programming
来源: 互联网 发布时间:2015-05-31
本文导语: Today, when I was reading C++ View, I saw an interesting example. Description: we have a list in memory that holds all the friends we have. We'll also need to add it to database. Suppose we have a method void addFriend(Person p) { frien...
Today, when I was reading C++ View, I saw an interesting example.
Description:
we have a list in memory that holds all the friends we have. We'll also need to add it to database.
Suppose we have a method
void addFriend(Person p)
{
friends.add(p);
addToDb(p);//if exception's thrown out, we need to undo in friends!
}
The problem exists when either friends.add() or addToDb() throws exception. then we have to undo the changes we've made to db and to the list.
According to the author, "try-catch" can work, but it'll become very tedious and hard to maintain when the number of statements requiring "try-catch" scales up. So a transaction object should be used here.
Here, although transaction object can work, but it still requires us to write an undo operation for each one, and sometimes it's not trivial to write an undo method.
So what do I suggest?
Although db operation cannot be immutable, in-memory operation certainly can! If we do immutable programming, we don't need to undo at all!
don't believe?
Suppose the friends list is an immutable structure, i.e.
List
List cons(Person);
where list.cons(p) only returns a new list instance without touching the old instance. (curious how this can be implemented by constant-time and linear storage? I'll give it later)
ok, if that's true, what can we do to the addFriend method?
void addFriend(Person p)
{
List tmp = friends.cons(p);
addToDb(p);
friends = tmp;
}
Ha ha, does that solve the undo easily?
Here is an immutable list impl
public interface List
{
public List cons(Object obj);
public Object getFirst()throws java.util.NoSuchElementException;
public List getTail();
public boolean isEmpty();
private static final EmptyList singleton = new EmptyList();
public static List instance(){return singleton;}
}
class ConsList
{
public List cons(Object obj){return new ConsList(obj, this);}
public Object getFirst(){return hd;}
public List getTail(){return tl;}
public boolean isEmpty(){return false;}
private final Object hd;
private final List tl;
ConsList(Object hd, List tl){this.hd = hd; this.tl = tl;}
}
class EmptyList
{
public List cons(Object obj){return new ConsList(obj, this);}
public Object getFirst(){throw new java.util.NoSuchElementException();}
public List getTail(){throw new java.util.NoSuchElementException();}
public boolean isEmpty(){return true;}
EmptyList(){}
}
Description:
we have a list in memory that holds all the friends we have. We'll also need to add it to database.
Suppose we have a method
void addFriend(Person p)
{
friends.add(p);
addToDb(p);//if exception's thrown out, we need to undo in friends!
}
The problem exists when either friends.add() or addToDb() throws exception. then we have to undo the changes we've made to db and to the list.
According to the author, "try-catch" can work, but it'll become very tedious and hard to maintain when the number of statements requiring "try-catch" scales up. So a transaction object should be used here.
Here, although transaction object can work, but it still requires us to write an undo operation for each one, and sometimes it's not trivial to write an undo method.
So what do I suggest?
Although db operation cannot be immutable, in-memory operation certainly can! If we do immutable programming, we don't need to undo at all!
don't believe?
Suppose the friends list is an immutable structure, i.e.
List
List cons(Person);
where list.cons(p) only returns a new list instance without touching the old instance. (curious how this can be implemented by constant-time and linear storage? I'll give it later)
ok, if that's true, what can we do to the addFriend method?
void addFriend(Person p)
{
List tmp = friends.cons(p);
addToDb(p);
friends = tmp;
}
Ha ha, does that solve the undo easily?
Here is an immutable list impl
public interface List
{
public List cons(Object obj);
public Object getFirst()throws java.util.NoSuchElementException;
public List getTail();
public boolean isEmpty();
private static final EmptyList singleton = new EmptyList();
public static List instance(){return singleton;}
}
class ConsList
{
public List cons(Object obj){return new ConsList(obj, this);}
public Object getFirst(){return hd;}
public List getTail(){return tl;}
public boolean isEmpty(){return false;}
private final Object hd;
private final List tl;
ConsList(Object hd, List tl){this.hd = hd; this.tl = tl;}
}
class EmptyList
{
public List cons(Object obj){return new ConsList(obj, this);}
public Object getFirst(){throw new java.util.NoSuchElementException();}
public List getTail(){throw new java.util.NoSuchElementException();}
public boolean isEmpty(){return true;}
EmptyList(){}
}
|
If your list is not based on a linked list, but based on, say an array. Won't the cost of copying be very expensive?
|
It's a good idea.
|
佩服,你的问题这总让我获益非浅:)
|
今晚要走了,明天细细品味:)
|
很好的解决方法,Immutable只在Patterns In Java中见过,且未消化吸收,所以,我想,能给你的,只有赞誉之辞:)谢谢你给我上了一课!
|
好东西:)资源共享无限!
据我所知jakarta.apache.org的Commons现在也有一个未发布的子项目是做Collection的,也实现了Bag、Heap等,具体实现我还没仔细看,源码可以通过Cvs取到,ajoo(jet pig)兄不妨去看看。
另外,我对你的实现也很感兴趣,相信也有人和我一样感兴趣,所以不建议你一份一份的发邮件,最好到http://sourceforge.net/去开一个开源项目,那样会好些:)
据我所知jakarta.apache.org的Commons现在也有一个未发布的子项目是做Collection的,也实现了Bag、Heap等,具体实现我还没仔细看,源码可以通过Cvs取到,ajoo(jet pig)兄不妨去看看。
另外,我对你的实现也很感兴趣,相信也有人和我一样感兴趣,所以不建议你一份一份的发邮件,最好到http://sourceforge.net/去开一个开源项目,那样会好些:)
|
唉,倒霉:(
呵呵,不行就来这
http://cosoft.org.cn/html/
活脱一个它的翻版:)
再不行就到IBM DW的开源站点吧
http://www-124.ibm.com/developerworks/oss/
麻烦:)
呵呵,不行就来这
http://cosoft.org.cn/html/
活脱一个它的翻版:)
再不行就到IBM DW的开源站点吧
http://www-124.ibm.com/developerworks/oss/
麻烦:)
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。