具有查询的全局对象缓存的设计模式

时间:2019-06-22 18:15:40

标签: design-patterns data-structures

我目前正在从事一个项目,该项目需要一个用于定义,共享和查找对象层次结构的通用接口。本质上,将存在一个共享项目,该共享项目为所有对象定义了公共结构,而消费项目可以使用它来定义对象并在其他项目之间共享它们。 我想知道是否存在适合这种情况并很好地实现的设计模式。

我已经尝试过了,但是我对结果并不完全满意。我目前的方法定义了一个Tag类,该类使用唯一的string作为名称,并使用一个Guid作为运行时生成的ID,以实现更快的查找(散列和等于Guid值比使用字符串快得多)。然后,要在全局项目之间共享的对象将Tag定义为成员。

在当前设计中,Tag个对象仅用作标识符,不包含任何数据。我想对此进行重新设计,以使标签确实包含数据并用作基类。但是,这正变得越来越复杂,因此我希望找到已建立的设计模式或实施类似系统的现有项目

[DebuggerDisplay( "Name = {Name}, Children = {ChildCount}" )]
public class Tag : IDisposable, IEquatable<Tag>
{

  #region Data Members

  public readonly Guid Id;

  public readonly string Name;

  public readonly string FullName;

  public readonly Tag Parent;

  protected readonly HashSet<Tag> children_;

  protected readonly int hash_;

  protected bool isDisposed_;

  #endregion

  #region Properties

  public IReadOnlyCollection<Tag> Children
  {
    [MethodImpl( MethodImplOptions.AggressiveInlining )]
    get => children_;
  }

  public int ChildCount
  {
    [MethodImpl( MethodImplOptions.AggressiveInlining )]
    get => children_.Count;
  }

  public bool HasChildren
  {
    [MethodImpl( MethodImplOptions.AggressiveInlining )]
    get => children_.Count > 0;
  }

  public bool HasParent
  {
    [MethodImpl( MethodImplOptions.AggressiveInlining )]
    get => Parent != null;
  }

  #endregion

  #region Constructor

  public Tag( string name )
    : this( Guid.NewGuid(), name, null )
  {
  }

  public Tag( string name, Tag parent )
    : this( Guid.NewGuid(), name, parent )
  {
  }

  public Tag( Guid id, string name )
    : this( id, name, null )
  {
  }

  public Tag( Guid id, string name, Tag parent )
  {
    Id = id;
    FullName = Name = name;

    children_ = new HashSet<Tag>();
    hash_ = Name.GetHashCode( StringComparison.InvariantCultureIgnoreCase );

    if( parent != null )
    {
      Parent = parent;
      FullName = $"{parent.FullName}.{Name}";
      Parent.AddChild( this );
    }
  }

  ~Tag()
  {
    Dispose( false );
  }

  #endregion

  #region Public Methods

  [MethodImpl( MethodImplOptions.AggressiveInlining )]
  internal void AddChild( Tag child )
  {
    if( !children_.Add( child ) )
    {
      children_.TryGetValue( child, out var existingChild );
      throw new DuplicateTagChildException( this, existingChild, child );
    }
  }

  [MethodImpl( MethodImplOptions.AggressiveInlining )]
  internal void RemoveChild( Tag child )
  {
    children_.Remove( child );
  }

  [MethodImpl( MethodImplOptions.AggressiveInlining )]
  public bool HasChild( Tag child )
  {
    return children_.Contains( child );
  }

  #endregion

  #region Overrides

  [MethodImpl( MethodImplOptions.AggressiveInlining )]
  public bool Equals( Tag other )
  {
    return Name.Equals( other.Name, StringComparison.InvariantCultureIgnoreCase );
  }

  [MethodImpl( MethodImplOptions.AggressiveInlining )]
  public override bool Equals( object obj )
  {
    return obj is Tag other
      && Name.Equals( other.Name, StringComparison.InvariantCultureIgnoreCase );
  }

  [MethodImpl( MethodImplOptions.AggressiveInlining )]
  public override int GetHashCode()
  {
    return hash_;
  }

  #endregion

  #region IDisposable Methods

  public void Dispose()
  {
    Dispose( true );
    GC.SuppressFinalize( this );
  }

  public virtual void Dispose( bool disposing )
  {
    if( isDisposed_ )
      return;

    if( disposing )
    {
    }

    Parent?.RemoveChild( this );
    TagCache.TryRemove( this );

    isDisposed_ = true;
  }

  #endregion

}

0 个答案:

没有答案