初学者,自用笔记
用于把“抽象部分(Abstraction)”与“实现部分(Implementation)”解耦, 让它们可以独立变化、自由组合,而不是靠继承层层扩展导致类爆炸
例如,让存储方式在json或xml间快速切换。
类似于抽象工厂
- Abstraction:对外暴露的高层接口/抽象(业务视角),描述规则
- RefinedAbstraction:抽象的扩展版本(可选)
- Implementation:实现接口(底层能力视角)
- ConcreteImplementation:具体实现(A/B/C 多种)
Implementation
// 序列化接口
public interface ISerializer
{
string Serialize<T>(T data);
T Deserialize<T>(string text);
}
// 文件读写
public interface IFileIO
{
void WriteAllText(string fullPath, string text);
string ReadAllText(string fullPath);
bool Exists(string fullPath);
void Delete(string fullPath);
}
ConcreteImplementation
// 序列化具体实现
public sealed class JsonUtilityAdapter : ISerializer
{
public string Serialize<T>(T data) => JsonUtility.ToJson(data, true);
public T Deserialize<T>(string text) => JsonUtility.FromJson<T>(text);
}
public sealed class XmlSerializerAdapter : ISerializer
{
public string Serialize<T>(T data)
{
var serializer = new XmlSerializer(typeof(T));
using (var ms = new MemoryStream())
{
serializer.Serialize(ms, data);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
public T Deserialize<T>(string text)
{
var serializer = new XmlSerializer(typeof(T));
using (var sr = new StringReader(text))
{
return (T)serializer.Deserialize(sr);
}
}
}
// 文件读写
public sealed class DiskFileIO : IFileIO
{
public void WriteAllText(string fullPath, string text)
{
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
File.WriteAllText(fullPath, text, Encoding.UTF8);
}
public string ReadAllText(string fullPath) => File.ReadAllText(fullPath, Encoding.UTF8);
public bool Exists(string fullPath) => File.Exists(fullPath);
public void Delete(string fullPath) { if (File.Exists(fullPath)) File.Delete(fullPath); }
}
Abstraction
public sealed class SaveService
{
private readonly string _dataPath;
private readonly string _fileName;
private readonly ISerializer _serializer; // << 桥接:实现端(序列化)可替换
private readonly IFileIO _fileIO; // << 桥接:实现端(存储介质)可替换
private readonly bool _encrypt;
private readonly string _codeWord = "mycodeword";
public SaveService(string dataPath, string fileName, ISerializer serializer, IFileIO fileIO, bool encrypt)
{
_dataPath = dataPath;
_fileName = fileName;
_serializer = serializer;
_fileIO = fileIO;
_encrypt = encrypt;
}
public void Save(GameData data)
{
string fullPath = Path.Combine(_dataPath, _fileName);
string text = _serializer.Serialize(data);
if (_encrypt) text = Xor(text);
_fileIO.WriteAllText(fullPath, text);
}
public GameData Load()
{
string fullPath = Path.Combine(_dataPath, _fileName);
if (!_fileIO.Exists(fullPath)) return null;
string text = _fileIO.ReadAllText(fullPath);
if (_encrypt) text = Xor(text);
return _serializer.Deserialize<GameData>(text);
}
public void Delete()
{
string fullPath = Path.Combine(_dataPath, _fileName);
_fileIO.Delete(fullPath);
}
private string Xor(string s)
{
var sb = new StringBuilder(s.Length);
for (int i = 0; i < s.Length; i++)
sb.Append((char)(s[i] ^ _codeWord[i % _codeWord.Length]));
return sb.ToString();
}
}

京公网安备 11010502036488号