2

我一直在对不同的设计模式进行大量研究,并试图确定正确的方法。

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

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

这也是蝇量级模式吗?我将如何处理那棵树的遍历?

编辑

我在下面问了这个问题,但我想在这里添加它:

我看到的所有关于复合模式的示例似乎都与值的处理有关,而享元模式似乎与对象状态的处理(或共享)有关。我只是读了太多的例子吗?将模式结合起来是解决方案吗?

4

2 回答 2

2

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

void Recursion(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);
}
于 2013-08-06T18:16:04.723 回答
1

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

考虑这个类 -

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 应用程序,而是替换为享元:

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使用接口而不是具体类型来实现和构建系统(您这样做了,对吗?!),然后您可以使用MyDataFlyweight来自 iPhone 应用程序的MyData对象和系统其余部分中的对象。您所要做的就是使用MyDataFlyweightblob 大小正确初始化。

调用 iPhone 应用程序的架构将规定在 iPhone 应用程序中使用享元。

此外,考虑较新的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; } }
    }
}

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

于 2013-08-06T19:26:27.023 回答