C#使用不同的“处理器”处理相同的对象是一个flyweight模式?

时间:2013-08-06 18:03:08

标签: c# design-patterns tree flyweight-pattern

我一直在研究不同的设计模式,我正在尝试确定这样做的正确方法。

我有一个上传我正在开发的MVC应用程序的图像需要以几种不同的方式处理图像,例如创建缩略图和保存数据库记录。接近这个的最好方法是通过flyweight模式吗?以此为例:

var image = new Image();    

List<IProcessors> processors = processorFactory.GetProcessors(ImageType.Jpeg);

foreach(IProcessor processor in processors)
{
    processor.process(image);
}

我也有这个问题的第二部分。如果处理器具有较小的相关“子处理器”怎么办?我脑子里的一个例子就是图书生成器。

I have a book generator 
     that has page generators
          that has paragraph generators
               that has sentence generators

这也是一个轻量级模式吗?我该如何处理该树的遍历?

修改

我在下面问过这个问题,但我想在此处添加:

我看到的复合模式的所有示例似乎都与值的处理有关,而flyweight模式似乎处理对象状态的处理(或共享)。我只是过多地阅读这些例子吗?结合模式是否可以解决问题?

2 个答案:

答案 0 :(得分:1)

我至少可以处理问题的第二部分。要展开树(或复合树),请使用简单的递归。

void Recusion(TreeItem parent) 
{
    // First call the same function for all the children.
    // This will take us all the way to the bottom of the tree.
    // The foreach loop won't execute when we're at the bottom.
    foreach (TreeItem child in parent.Children) 
    {
         Recursion(child);
    }

    // When there are no more children (since we're at the bottom)
    // then finally perform the task you want. This will slowly work
    // it's way up the entire tree from bottom most items to the top.
    Console.WriteLine(parent.Name);
}

答案 1 :(得分:1)

您的描述可能有一些代表每个嵌套类的flyweights。但在这种情况下,更多的是实现细节。根据我的经验,flyweights通常在架构级别或实现级别上被要求,但很少作为设计元素。

考虑这个类 -

public interface IMyData {
    IdType MyId { get; }
    byte[] BlobData { get; }
    long SizeOfBlob { get; }
}
public class MyData : IMyData {
    public IdType MyId { get; private set; }
    public byte[] BlobData { get; set; }
    public long SizeOfBlob { get { return BlobData.LongLength; } }
    }
}

在您的多层应用程序中,此对象需要从源数据库传输到管理器的IPhone,以便根据blob大小进行审批,然后再到会计系统进行计费。因此,不是将整个事物传输到iPhone应用程序,而是替换flyweight:

public class MyDataFlyWeight : IMyData {
    public MyDataFlyWeight(IdType myId, long blobSize){
        MyId = myId;
        BlobSize = blobSize;
    }
    public IdType MyId { get; set; }
    public byte[] MutableBlobData { get { 
            throw new NotImplmentedException();
            }
        }
    public long BlobSize { get; private set; }
    }
}

通过同时实现IMyData并使用接口构建系统而不是具体类型(你做了这个,对吗?!),那么你可以使用来自iPhone应用程序的MyDataFlyweight个对象系统其余部分中的MyData个对象。您所要做的就是使用blob大小正确初始化MyDataFlyweight

要求使用iPhone应用程序的架构将要求在iPhone应用程序中使用flyweight。

此外,请考虑较新的Lazy<T>类:

public class MyData : IMyData {
    public IdType MyId { get; private set; }

    private Lazy<byte[]> _blob = new Lazy<byte[]>(() => 
                                 StaticBlobService.GetBlob(MyId));
    public byte[] BlobData { get { return _blob.Value; } }
    public long SizeOfBlob { get { return BlobData.LongLength; } }
    }
}

这是一个纯粹作为实现细节使用flyweight的例子。