Finding the best design: read-only read engine

I have an object (class) of a category that has zero or one parent category and many child categories are a tree structure. These categories are stored in the DBMS, so to improve performance I want to load all categories and cache them in memory when the application starts.

There may be plugins in our system, and we allow the plugin authors to access the category tree, but they should not change the cached elements and the tree (I think that a design without reading can cause some subtle errors in this senario) only the system knows when and how to update a tree.

Here are some demo codes:

public interface ITreeNode<T>
    where T : ITreeNode<T>
{
    // No setter
    T Parent { get; }
    IEnumerable<T> ChildNodes { get; }
}

// This class is generated by O/R Mapping tool (e.g. Entity Framework)
public class Category : EntityObject
{
    public string Name { get; set; }
}

// Because Category is not stateless, so I create a cleaner view class for Category.
// And this class is the Node Type of the Category Tree
public class CategoryView : ITreeNode<CategoryView>
{
    public string Name { get; private set; }

    #region ITreeNode Memebers

    public CategoryView Parent { get; private set; }

    private List<CategoryView> _childNodes;
    public IEnumerable<CategoryView> ChildNodes {
        return _childNodes;
    }

    #endregion

    public static CategoryView CreateFrom(Category category) {
        // here I can set the CategoryView.Name property
    }
}

. , ITreeNode , . ITreeNode, , ITreeNode :

public interface ITreeNode<T> {
    // has setter
    T Parent { get; set; }
    // use ICollection<T> instead of IEnumerable<T>
    ICollection<T> ChildNodes { get; }
}

ITreeNode , readonly, .

, :

public interface ITreeNode<T> {
    T Parent { get; }
    IEnumerable<T> ChildNodes { get; }
}

public interface IWritableTreeNode<T> : ITreeNode<T> {
    new T Parent { get; set; }
    new ICollection<T> ChildNodes { get; }
}

? - ? !:)

+3
1

<T> IEnumerable, . , , AsReadOnly() , ReadOnlyCollection <T> , .

ReadOnly , , , .

, ITreeNode , .

- ...


public class TreeNode : ITreeNode
{
    private bool _isReadOnly;
    private List<ITreeNode> _childNodes = new List<ITreeNode>();

    public TreeNode Parent { get; private set; }

    public IEnumerable<ITreeNode> ChildNodes
    {
        get
        {
            return _isReadOnly ? _childNodes.AsReadOnly() : _childNodes;
        }
    }
}
+1

Source: https://habr.com/ru/post/1745046/


All Articles