Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我错过了什么模式_C#_.net_Oop_Design Patterns - Fatal编程技术网

C# 我错过了什么模式

C# 我错过了什么模式,c#,.net,oop,design-patterns,C#,.net,Oop,Design Patterns,我有以下接口 interface IConsoleHistory { void Add(string entry); HistoryEntry GetNextEntry(); HistoryEntry GetPreviousEntry(); void ResetHistoryMarker(); void Delete(HistoryEntry entry); void DeleteEntireHistory(); } public cl

我有以下接口

interface IConsoleHistory
{
    void Add(string entry);

    HistoryEntry GetNextEntry();

    HistoryEntry GetPreviousEntry();

    void ResetHistoryMarker();

    void Delete(HistoryEntry entry);

    void DeleteEntireHistory();
}

public class HistoryEntry
{
    public HistoryEntry(string value, int index, bool isCommand)
    {
        Value = value;
        Index = index;
        IsCommand = isCommand;
    }

    public string Value { get; private set; }

    public int Index { get; private set; }

    public bool IsCommand { get; private set; }
}
基于此,我实现了InMemoryHistory:

public class InMemoryHistory : IConsoleHistory
{
    protected List<string> History { get; private set; }
    private int _currentIndex;

    public InMemoryHistory() :this(new List<string>())
    {
    }

    protected InMemoryHistory(List<string> history)
    {
        History = history;
        _currentIndex = -1;
    }

    public virtual void Add(string entry)
    {
        History.Insert(0, entry);
    }

    public HistoryEntry GetNextEntry()
    {
        if (GetHighestIndex() > _currentIndex)
        {
            _currentIndex++;
            return ReturnAtIndex(_currentIndex);
        }

        return null;
    }

    private int GetHighestIndex()
    {
        return History.Count - 1;
    }

    private int GetLowestIndex()
    {
        return History.Count > 0 ? 0 : -1;
    }

    public HistoryEntry GetPreviousEntry()
    {
        if (_currentIndex > GetLowestIndex())
        {
            _currentIndex--;
            return ReturnAtIndex(_currentIndex);
        }
        _currentIndex = -1;
        return null;
    }

    private HistoryEntry ReturnAtIndex(int index)
    {
        return new HistoryEntry(History[index], index, false);
    }

    public void ResetHistoryMarker()
    {
        _currentIndex = -1;
    }

    public void Delete(HistoryEntry entry)
    {
        if (History.ElementAtOrDefault(entry.Index) != null)
        {
            History.RemoveAt(entry.Index);
        }
    }

    public void DeleteEntireHistory()
    {
        History.Clear();
    }
}
MemoryHistory中的公共类:IConsoleHistory
{
受保护列表历史记录{get;private set;}
私有int_currentIndex;
public InMemoryHistory():此(新列表())
{
}
受保护的内存历史记录(列表历史记录)
{
历史=历史;
_currentIndex=-1;
}
公共虚拟空添加(字符串条目)
{
历史记录。插入(0,条目);
}
公共历史条目GetNextEntry()
{
如果(GetHighestIndex()>\u currentIndex)
{
_currentIndex++;
返回索引(_currentIndex);
}
返回null;
}
私有int GetHighestIndex()
{
返回历史。计数-1;
}
private int GetLowestIndex()
{
返回历史记录。计数>0?0:-1;
}
公共历史条目GetPreviousEntry()
{
如果(_currentIndex>GetLowestIndex())
{
_当前索引--;
返回索引(_currentIndex);
}
_currentIndex=-1;
返回null;
}
私有历史条目返回索引(int索引)
{
返回新的HistoryEntry(历史[索引],索引,false);
}
public void ResetHistoryMarker()
{
_currentIndex=-1;
}
公共作废删除(历史记录条目)
{
if(History.ElementAtOrDefault(entry.Index)!=null)
{
历史.RemoveAt(entry.Index);
}
}
public void deleteEntityHistory()
{
历史;
}
}
现在我想要一个基于文件的历史记录。为了保持代码的干性,我想继承InMemoryHistory,并在每次添加后保留整个列表

public class FileBasedHistory : InMemoryHistory
{
    private readonly string _fileName;

    public FileBasedHistory():this("history.txt")
    {
    }

    public FileBasedHistory(string fileName) :base(GetHistoryFromFile(fileName))
    {
        _fileName = fileName;
    }

    public override void Add(string entry)
    {
        base.Add(entry);
        WriteToDisk();
    }

    private void WriteToDisk()
    {
        using(var textWriter = new StreamWriter(_fileName, false, Encoding.UTF8))
        {
            History.ForEach(textWriter.WriteLine);
        }
    }

    private static List<string> GetHistoryFromFile(string fileName)
    {
        if (!File.Exists(fileName))
            return new List<string>();

        return File
            .ReadAllLines(fileName)
            .ToList();
    }
}
公共类FileBasedHistory:InMemoryHistory
{
私有只读字符串\u文件名;
public FileBasedHistory():此(“history.txt”)
{
}
public FileBasedHistory(字符串文件名):base(GetHistoryFromFile(文件名))
{
_fileName=文件名;
}
公共覆盖无效添加(字符串条目)
{
添加(条目);
WriteToDisk();
}
私有void WriteToDisk()
{
使用(var textWriter=newstreamWriter(_fileName,false,Encoding.UTF8))
{
历史.ForEach(textWriter.WriteLine);
}
}
私有静态列表GetHistoryFromFile(字符串文件名)
{
如果(!File.Exists(fileName))
返回新列表();
返回文件
.ReadAllLines(文件名)
.ToList();
}
}
这就像一个咒语。但让我困扰的是,我需要静态
GetHistoryFromFile
方法。这并不是什么大问题,但我想知道我是否错过了一个更适合这种情况的模式

更新

正如基思已经建议的那样。这也是让我有点困扰的继承方法。继承应该始终是一个问题

您不能说:“基于文件的历史是内存历史中的历史”


所以我想知道我是否应该尝试使用这个策略模式。或者编写一个抽象控制台,实现部分逻辑,但为扩展留出空间。有没有关于如何重构它的建议?

我想你已经做得非常完美了
GetHistoryFromFile
只适用于
FileBasedHistory
,因此它应该在那里是有意义的。

我认为您已经拥有了它
GetHistoryFromFile
仅适用于
FileBasedHistory
,因此它应该在那里是有意义的。

我觉得奇怪的是,您以构造函数的身份传递列表。你根本不必那样做

与其将GetHistoryFromFile视为创建一个新列表,不如将其视为加载到现有列表中的一种方法(这样也会变得更有用……因为它可以将多个文件加载到历史中)

此外,删除和清除操作无法正常写入磁盘

此外,将一行一行写入磁盘可能会变得非常缓慢


此外,InMemory和基于文件的存储可能同时受到耦合的影响。这意味着,虽然他们目前是相似的,但他们很可能会出现分歧。例如,如果基于磁盘的系统使用滚动历史文件和缓存历史。因此,不要过于依赖InMemory和文件而保留在继承结构中,将它们分开可能更容易

我觉得奇怪的是,您以构造函数的身份传入了一个列表。你根本不必那样做

与其将GetHistoryFromFile视为创建一个新列表,不如将其视为加载到现有列表中的一种方法(这样也会变得更有用……因为它可以将多个文件加载到历史中)

此外,删除和清除操作无法正常写入磁盘

此外,将一行一行写入磁盘可能会变得非常缓慢


此外,InMemory和基于文件的存储可能同时受到耦合的影响。这意味着,虽然他们目前是相似的,但他们很可能会出现分歧。例如,如果基于磁盘的系统使用滚动历史文件和缓存历史。因此,不要过于依赖InMemory和文件而保留在继承结构中,将它们分开可能更容易

您可以在此处使用
迭代器。这三种方法仅用于迭代数据:

HistoryEntry GetNextEntry();
HistoryEntry GetPreviousEntry();
void ResetHistoryMarker();
这些方法用于管理数据:

void Add(string entry);
void Delete(HistoryEntry entry);
void DeleteEntireHistory();

我认为这是一个不同的职责,我将它们转移到了不同的类。

您可以在这里使用
迭代器。这三种方法仅用于迭代数据:

HistoryEntry GetNextEntry();
HistoryEntry GetPreviousEntry();
void ResetHistoryMarker();
这些方法用于管理数据:

void Add(string entry);
void Delete(HistoryEntry entry);
void DeleteEntireHistory();

我认为这是一种不同的责任,我把他们转移到了不同的班级。

是静态让我感到不安。是静态让我感到不安。我想