使用单例和中介来在项目之间进行通信

时间:2011-08-16 11:41:42

标签: c# .net design-patterns

我有项目calles仓库。在仓库里有产品。我想写一个选项来告知仓库有关预期产品的信息。这就是我在考虑这样做的方式:

  1. 创建一个新的Warehose.Common项目,该项目将由愿意与仓库进行交互的其他项目引用。
  2. 在Warehose.Common项目中,我将创建一个Product接口并将其命名为IProduct。
  3. 使用单例和中介设计模式如下(不确定我是否正确实现了这些设计模式):

    public sealed class ExpectedProductsMediator
    {
        private static volatile ExpectedProductsMediator _Instance;
        private static object _SyncRoot = new Object();
    
    
        delegate IEnumerable<INoteProduct> ExpectedProductsGenerator(DateTime startDate, DateTime endDate);
    
        private IList<ExpectedProductsGenerator> _ExpectedProductsGenerators;
    
        private ExpectedProductsMediator()
        {
            _ExpectedProductsGenerators = new List<ExpectedProductsGenerator>();
        }
    
        public static ExpectedProductsMediator Instance
        {
            get
            {
                if (_Instance == null)
                {
                    lock (_SyncRoot)
                    {
                        if (_Instance == null)
                            _Instance = new ExpectedProductsMediator();
                    }
                }
                return _Instance;
            }
        }
    
        public void AddExpectedProductsGenerator(ExpectedProductsGenerator generator)
        {
            _ExpectedProductsGenerators.Add(generator);
        }
    
        public void RemoveExpectedProductsGenerator(ExpectedProductsGenerator generator)
        {
            _ExpectedProductsGenerators.Remove(generator);
        }
    
        public IEnumerable<INoteProduct> GetExpectedProducts(DateTime startDate, DateTime endDate)
        {
            IEnumerable<INoteProduct> products = null;
            if (_ExpectedProductsGenerators.Any())
            {
                products = _ExpectedProductsGenerators.First()(startDate, endDate);
                foreach (ExpectedProductsGenerator generator in _ExpectedProductsGenerators.Skip(1))
                {
                    products = products.Concat(generator(startDate, endDate));
                }
            }
            return products;
        }
    }
    
  4. 此介体将位于Warehouse.Common项目中。现在,如果项目B想要提供预期的产品,则需要使用AddExpectedProductsGenerator()方法注册其生成器:

    public static class ExpectedProductsRegistrar {
        static ExpectedProductsRegistrar() {
            ExpectedProductsMediator.Instance.AddExpectedProductsGenerator(someGenerator);
        }
    }
    

    每当仓库需要获得预期的产品时,它所要做的就是调用GetExpectedProducts()方法。

    这个实现有两个问题:
    - 它将GetExpectedProducts()方法暴露给所有其他项目 - 为了注册调解器,我需要使用静态约束器。

    您如何看待我的实施?对于这种需求有没有更好的解决方案?我是否正确使用设计模式?

2 个答案:

答案 0 :(得分:1)

我会让您的API接受新产品,然后写入存储(文件,数据库等)。然后Warehouse项目从存储中读取预期的产品。然后,你可以摆脱你的单身,并通过API尽可能少地暴露。

答案 1 :(得分:0)

最终我使用了这个实现。我没有找到更好的东西,这个代码更容易维护。