日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

Unity应用架构设计(9)——构建统一的 Repository

發(fā)布時(shí)間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Unity应用架构设计(9)——构建统一的 Repository 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

談到 『Repository』 倉(cāng)儲(chǔ)模式,第一映像就是封裝了對(duì)數(shù)據(jù)的訪問(wèn)和持久化。Repository 模式的理念核心是定義了一個(gè)規(guī)范,即接口『Interface』,在這個(gè)規(guī)范里面定義了訪問(wèn)以及持久化數(shù)據(jù)的行為。開(kāi)發(fā)者只要對(duì)接口進(jìn)行特定的實(shí)現(xiàn)就可以滿足對(duì)不同存儲(chǔ)介質(zhì)的訪問(wèn),比如存儲(chǔ)在Database,File System,Cache等等。軟件開(kāi)發(fā)領(lǐng)域有非常多類似的想法,比如JDBC就是定義了一套規(guī)范,而具體的廠商MySql,Oracle根據(jù)此開(kāi)發(fā)對(duì)應(yīng)的驅(qū)動(dòng)。

Unity 中的Repository模式

在Unity 3D中,數(shù)據(jù)的存儲(chǔ)其實(shí)有很多地方,比如最常見(jiàn)的內(nèi)存可以高速緩存一些臨時(shí)數(shù)據(jù),PlayerPrefs可以記錄一些存檔信息,TextAsset可以存一些配置信息,日志文件可以用IO操作寫(xiě)入,關(guān)系型數(shù)據(jù)結(jié)構(gòu)可以使用Sqlite存儲(chǔ)。Repository 是個(gè)很抽象的概念,操作的數(shù)據(jù)也不一定要在本地,很有可能是存在遠(yuǎn)程服務(wù)器,所以也支持以Web Service的形式對(duì)數(shù)據(jù)進(jìn)行訪問(wèn)和持久化。

根據(jù)上述的描述,Repository 模式的架構(gòu)圖如下所示:

可以看到,通過(guò)統(tǒng)一的接口,可以實(shí)現(xiàn)對(duì)不同存儲(chǔ)介質(zhì)的訪問(wèn),甚至是訪問(wèn)遠(yuǎn)程數(shù)據(jù)。

定義Repository規(guī)范

Repository的規(guī)范就是接口,這個(gè)接口功能很簡(jiǎn)單,封裝了數(shù)據(jù)增,刪,查,改的行為:

public interface IRepository<T> where T:class,new()
{void Insert(T instance);void Delete(T instance);void Update(T instance);IEnumerable<T> Select(Func<T,bool> func );
}

這只是一個(gè)最基本的定義,也是最基礎(chǔ)的操作,完全可以再做擴(kuò)展。

值得注意的是,對(duì)于一些只讀數(shù)據(jù),比如TextAssets,Insert,Delete,Update 往往不用實(shí)現(xiàn)。這就違反了『里式替換原則』,解決方案也很簡(jiǎn)單,使用接口隔離,對(duì)于只讀的數(shù)據(jù)只實(shí)現(xiàn) ISelectable 接口。但這往往會(huì)破環(huán)了我們的Repository結(jié)構(gòu),你可能會(huì)擴(kuò)展很多不同的行為接口,從代碼角度很優(yōu)化,但可讀性變差。所以,在uMVVM框架中,我為了保證Repository的完整性和可讀性,選擇違背『里式替換原則』。

開(kāi)發(fā)者根據(jù)不同的存儲(chǔ)介質(zhì),決定不同的操作方法,這是顯而易見(jiàn)的,下面就是一些常見(jiàn)Repository實(shí)現(xiàn)。

定義UnityResourcesRepository:用來(lái)訪問(wèn)Unity的資源TextAssets

public class UnityResourcesRepository<T> : IRepository<T> where T : class, new()
{//...省略部分代碼...public IEnumerable<T> Select(Func<T, bool> func){List<T> items = new List<T>();try{TextAsset[] textAssets = Resources.LoadAll<TextAsset>(DataDirectory);for (int i = 0; i < textAssets.Length; i++){TextAsset textAsset = textAssets[i];T item = Serializer.Deserialize<T>(textAsset.text);items.Add(item);}}catch (Exception e){throw new Exception(e.ToString());}return items.Where(func);}
}

定義PlayerPrefsRepository:用來(lái)訪問(wèn)和持久化一些存檔相關(guān)信息

public class PlayerPrefsRepository<T> : IRepository<T> where T : class, new()
{//...省略部分代碼...public void Insert(T instance){try{string serializedObject = Serializer.Serialize<T>(instance, true);PlayerPrefs.SetString(KeysIndexName, serializedObject);}catch (Exception e){throw new Exception(e.ToString());}}}

定義FileSystemRepository:用來(lái)訪問(wèn)和持久化一些日志相關(guān)信息

public class FileSystemRepository<T> : IRepository<T> where T:class,new()
{   //...省略部分代碼...public void Insert(T instance){try{string filename = GetFilename(Guid.NewGuid());if (File.Exists(filename)){throw new Exception("Attempting to insert an object which already exists. Filename=" + filename);}string serializedObject = Serializer.Serialize<T>(instance, true);using (StreamWriter stream = new StreamWriter(filename)){stream.Write(serializedObject);}}catch (Exception e){throw new Exception(e.ToString());}}}

定義MemoryRepository:用來(lái)高速緩存一些臨時(shí)數(shù)據(jù)

public class MemoryRepository<T> : IRepository<T> where T : class, new()
{//...省略部分代碼...private Dictionary<object, T> repository = new Dictionary<object, T>();public MemoryRepository(){FindKeyPropertyInDataType();}public void Insert(T instance){try{var id = KeyPropertyInfo.GetValue(instance, null);repository[id] = instance;}catch (Exception e){throw new Exception(e.ToString());}}private void FindKeyPropertyInDataType(){foreach (PropertyInfo propertyInfo in typeof(T).GetProperties()){object[] attributes = propertyInfo.GetCustomAttributes(typeof(RepositoryKey), false);if (attributes != null && attributes.Length == 1){KeyPropertyInfo = propertyInfo;}else{throw new Exception("more than one repository key exist");}}}
}

定義DbRepository:用來(lái)操作關(guān)系型數(shù)據(jù)庫(kù)Sqlite

public class DbRepository<T> : IRepository<T> where T : class, new()
{private readonly SQLiteConnection _connection;//...省略部分代碼...public void Insert(T instance){try{_connection.Insert(instance);}catch (Exception e){throw new Exception(e.ToString());}}}

定義RestRepository:以WebService的形式訪問(wèn)和持久化遠(yuǎn)程數(shù)據(jù)

public class RestRepository<T, R>:IRepository<T> where T : class, new() where R : class, new()
{//...省略部分代碼...public void Insert(T instance){//通過(guò)WWW像遠(yuǎn)程發(fā)送消息}
}

小結(jié)

Repository 模式是很常見(jiàn)的數(shù)據(jù)層技術(shù),對(duì)于.NET 程序員來(lái)說(shuō)就是DAL,而對(duì)于Java程序員而言就是DAO。我們擴(kuò)展了不同的Repository 對(duì)象來(lái)對(duì)不同的介質(zhì)進(jìn)行訪問(wèn)和持久化,這也是今后對(duì)緩存的實(shí)現(xiàn)做準(zhǔn)備。
源代碼托管在Github上,點(diǎn)擊此了解

轉(zhuǎn)載于:https://www.cnblogs.com/OceanEyes/p/thinking_in_repository_pattern.html

總結(jié)

以上是生活随笔為你收集整理的Unity应用架构设计(9)——构建统一的 Repository的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。