How can you tell whether to use Composite Pattern or a Tree Structure, or a third implementation?

I have two client types, an “Observer“-type and a “Subject“-type. They’re both associated with a hierarchy of groups.

The Observer will receive (calendar) data from the groups it is associated with throughout the different hierarchies. This data is calculated by combining data from ‘parent’ groups of the group trying to collect data (each group can have only one parent).

The Subject will be able to create the data (that the Observers will receive) in the groups they’re associated with.
When data is created in a group, all ‘children’ of the group will have the data as well, and they will be able to make their own version of a specific area of the data, but still linked to the original data created (in my specific implementation, the original data will contain time-period(s) and headline, while the subgroups specify the rest of the data for the receivers directly linked to their respective groups).

However, when the Subject creates data, it has to check if all affected Observers have any data that conflicts with this, which means a huge recursive function, as far as I can understand.

So I think this can be summed up to the fact that I need to be able to have a hierarchy that you can go up and down in, and some places be able to treat them as a whole (recursion, basically).

Also, I’m not just aiming at a solution that works. I’m hoping to find a solution that is relatively easy to understand (architecture-wise at least) and also flexible enough to be able to easily receive additional functionality in the future.

Is there a design pattern, or a good practice to go by, to solve this problem or similar hierarchy problems?

EDIT:

Here’s the design I have:

The “Phoenix”-class is named that way because I didn’t think of an appropriate name yet.

But besides this I need to be able to hide specific activities for specific observers, even though they are attached to them through the groups.


A little Off-topic:

Personally, I feel that I should be able to chop this problem down to smaller problems, but it escapes me how. I think it’s because it involves multiple recursive functionalities that aren’t associated with each other and different client types that needs to get information in different ways. I can’t really wrap my head around it. If anyone can guide me in a direction of how to become better at encapsulating hierarchy problems, I’d be very glad to receive that as well.

9

Here’s a simple “Group” implementation that allows you to navigate to the Root, and navigate that Root’s tree as a collection.

public class Group
{
  public Group Parent
  public List<Group> Children

  public IEnumerable<Group> Parents()
  {
    Group result = this;
    while (result.Parent != null)
    {
      result = result.Parent;
      yield return result;
    }
  }
  public Group Root()
  {
    return Parents.LastOrDefault() ?? this;
  }


  public IEnumerable<Group> WalkTreeBreadthFirst(
  {
    //http://en.wikipedia.org/wiki/Breadth-first_search
    HashSet<Group> seenIt = new HashSet<Group>()
    Queue<Group> toVisit = new Queue<Group>();
    toVisit.Enqueue(this);

    while (toVisit.Any())
    {
      Group item = toVisit.Dequeue();
      if (!seenIt.Contains(item))
      {
        seenIt.Add(item);
        foreach (Group child in item.Children)
        {
          toVisit.Enqueue(child);
        }
        yield return item;
      }
    }
  }

  public static IEnumerable<Group> WalkTreeDepthFirst()
  {
    // http://en.wikipedia.org/wiki/Depth-first_search
    HashSet<Group> seenIt = new HashSet<Group>();
    Stack<Group> toVisit = new Stack<Group>();

    toVisit.Push(this);

    while (toVisit.Any())
    {
      Group item = toVisit.Pop();
      if (!seenIt.Contains(item))
      {
        seenIt.Add(item);
        foreach (Group child in item.Children.Reverse())
        {
          toVisit.Push(child);
        }
        yield return item;
      }
    }
  }
}

So – given a group, you can walk that Group’s tree:

Group myGroup = GetGroup();
Group root = myGroup.Root;
foreach(Group inTree in root.WalkTreeBreadthFirst())
{
  //do something with inTree Group.
}

My hope in posting this, is that by showing how to navigate a tree (and dispelling the complexity thereof), you may be able to visualize about the operations you want to perform on the tree, and then revisit the patterns on your own to see what best applies.

With the limited view we have of the usage or implementation requirements of your system it’s hard to get too specific. For example, things that would come into consideration might be:

  • is the system highly concurrent (lots of users)?
  • what is the read/write ratio of data access? (high read, low write is common)

As for patterns etc., I would worry less about what exact patterns crop up in your solution, and more about the design of the actual solution. I think knowledge of design patterns is useful, but not the be-all and end-all: to use a writer analogy, design patterns are more like a dictionary of commonly seen phrases, rather than a dictionary of sentences you must write an entire book from.

Your diagram looks generally ok to me.

There’s one mechanism you’ve not mentioned and that is of having some sort of cache in your hierarchy. Obviously you must implement this with great care, but it could significantly improve the performance of your system. Here’s a simple take on it (caveat emptor):

For each node in your hierarchy, store inherited data with the node. Do this lazily or pro-actively, that’s up to you. When an update is made the hierarchy, you can either regenerate the cache data for all affected nodes there and then, or set ‘dirty’ flags in the appropriate places, and have the affected data lazily re-generated when necessary.

I have no idea how appropriate this is in your system, but may be worth considering.

Also, this question on S.O. may be relevant:

https://stackoverflow.com/questions/1567935/how-to-do-inheritance-modeling-in-relational-databases

I know this is Kind of Obvious but I am going to say it anyway,
I think you should take a look at the Observer Pattern you mentioned that you have an Observer Type and what you have looks kind of like the Observer Pattern to me.

couple of links:

DoFactory

oodesign

check those out.
otherwise I would just Code what you have in your Diagram and then use the Design Pattern to simplify if necessary. you already know what needs to happen and how the program is supposed to work. Write some Code and see if it still fits.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật