関係行動設計へのオブジェクト
24989 ワード
本篇
这些パターン主要是处理数据从对象以及关系型数据库之间的传递问题.
只有データソース層的问题
労働単位
ワークパターンの単位は、どのドメインオブジェクトが変更されたかを追跡する方法を記述します(変更されたオブジェクトだけがデータベースで更新される必要がある).
记录那些对象改变了,然后更新数据库中对应的记录.
有一个労働単位对象,包含了4个
list
一个 commit()
方法.new list
新增的对象,需要插入到数据库中 dirty list
修改过的对象 clean list
未修改过的对象(实际情况下, clean list
无需创建) delete list
删除的对象,需要在数据库中删除相应记录 呼び出し元の登録在代码附近增加把对象放进リスト里的操作,比例新しい出一个对象后立即把它放进
new list
中; オブジェクト登録:让对象自己把自己放进相应的リスト中,比如在セッター方法里和构造方法里添加相应的代码.
public class Song extends DomainObject {
private String name;
private String artist;
...
public Song(String name, String artist, ...) {
this.name = name;
...
UnitOfWork.registerNew(this);
}
public void setName(String name) {
this.name = name;
...
UnitOfWork.registerDirty(this);
}
}
public class UnitOfWork {
private static ThreadLocal current = new ThreadLocal();
private List<DomainObject> newObjects = new ArrayList<DomainObject>();
private List<DomainObject> dirtyObjects = new ArrayList<DomainObject>();
private List<DomainObject> deletedObjects = new ArrayList<DomainObject>();
// put obj into the New list
public void registerNew(DomainObject obj) {
Assert.notNull(obj.getId(), "id is null", );
Assert.isTrue(!dirtyObjects.contains(obj), "object is dirty");
Assert.isTrue(!deletedObjects.contains(obj), "object is deleted");
Assert.isTrue(!newObjects.contains(obj), "object is new");
newObjects.add(obj);
}
public void registerDirty(DomainObject obj) {...}
public void registerDelete(DomainObject obj) {...}
// Let the data-source layer to do the db-things
public void commit() {
for (DomainObject obj : newObjects) {
DataMapper.getMapper(obj.getClass()).insert(obj);
}
for (DomainObject obj : dirtyObjects) {
DataMapper.getMapper(obj.getClass()).update(obj);
}
for (DomainObject obj : deletedObjects) {
DataMapper.getMapper(obj.getClass()).delete(obj);
}
}
}
労働単位的优缺点
長所
短所
アイデンティティマップ
各オブジェクトがマップ内のすべてのロードされたオブジェクトを維持することによって一度だけロードされることを保証します.それらを参照するときにマップを使用してオブジェクトを検索します.
只要用来防止同一个数据被多次从数据库中读出来.
实现的方法是对数据库的每一个表构造一个マップ即代码中的
Map<Class, IdentityMap> singleton
利用数据库中的キー来判断那些记录已经被读出来了.public class IdentityMap<E> {
private Map<Long, E> map = new HashMap<Long, E>();
private static Map<Class, IdentityMap> singleton =
new HashMap<Class, IdentityMap>();
public static <E> IdentityMap<E> getInstance(E e) {
IdentityMap<E> result = singletons.get(e.getClass());
if (result == null) {
result = new IdentityMap<E>();
singletons.put(e.getClass(), result);
}
return result;
}
public void put(long id, E o) {
map.put(id, o);
}
public E get(long id) {
return map.get(id);
}
}
アイデンティティマップ的优缺点
長所
==
比较对象,而不是使用 equals()
短所
怠惰荷重
必要なデータの全てを含まないオブジェクトですが、取得する方法を知っています.
怠惰荷重旨在降低对数据库的读操作,只读需要的数据.
实现怠惰荷重的四种方法:
怠惰な初期化:每一个对象在创建的时候,它的所有属性都设置为NULL需要某个属性的时候再从数据库里读取这个属性;
ゴースト与怠惰な初期化类似,只是需要某个属性时,从数据库里读取这个对象的全部属性.
怠惰な初期化
public class Student {
private int id;
private String firstName;
private String lastName;
...
public String getLastName() {
if(this.lastName == null) {
// load lastName from db
Record record = gateway.find(this.id);
this.lastName = record.get("lastName");
}
return this.lastName;
}
...
}
ゴースト
public class Student {
private int id;
private String firstName;
private String lastName;
...
public String getLastName() {
if(this.lastName == null) {
load();
}
return this.lastName;
}
...
// load all the attributes from db
public void load() {
Record record = gateway.find(this.id);
if(this.lastName == null) {
this.lastName = record.get("lastName");
}
// load other attributes
...
}
}
仮想プロキシ
与代理模式相同.
プロキシは元のオブジェクトへのアクセスを制御し、元のオブジェクトへのリクエストの前または後に実行することができます.
首先创建一个接口,里面的方法和实体类里的一样,
public interface StudentI {
public int getId();
public void setId(int id);
public String getFitstName();
public void setFitstName(String firstName);
...
}
public class StudentProxy implements StudentI {
// the real object
private StudentI source;
private StudentI getSource() {
if (source == null) {
load();
}
}
public void setLastName(String lastName) {
getSource().setLastName(lastName);
}
public String getLastName() {
return getSource().getLastName();
}
...
}
バリューホルダー
与仮想プロキシ类似,只是バリューホルダー类不像仮想プロキシ一样拥有一样的方法接口.所有的实体类都共享一个バリューホルダー.
// Java function to illustrate
// Lazy Initialization in
// Lazy Loading Design Pattern
public class ValueHolder<T> {
private T value;
private readonlyFunc<object, T> valueRetrieval;
// Constructor
public ValueHolder(Func<object, T> valueRetrieval) {
valueRetrieval= this.valueRetrieval;
}
// We'll use the signature "GetValue" for convention
public T GetValue(object parameter) {
if (value == null)
value = valueRetrieval(parameter);
return value;
}
}
怠惰荷重的优缺点
長所
短所
Reference
この問題について(関係行動設計へのオブジェクト), 我々は、より多くの情報をここで見つけました https://dev.to/declair/da04-object-to-relational-behavioural-design-4hk8テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol