首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Analytical Widgets的分层设计-这是代码的味道吗?

使用Analytical Widgets的分层设计-这是代码的味道吗?
EN

Stack Overflow用户
提问于 2010-03-30 05:23:52
回答 3查看 128关注 0票数 2

我现在的想法是有一个多层次的分析对象“层”系统,它在一个公共对象上执行特定的计算,然后根据结果创建一组新的分析对象。然后,新创建的分析对象将轮流运行,并有选择地创建更多分析对象,依此类推。要点是,子分析对象将始终在创建它们的对象之后执行,这一点相对重要。整个装置将由单个线程调用,所以我目前并不关心线程安全。只要满足一定的基本条件,我不认为这是一个不稳定的设计,但我仍然对它有点反胃。

这是一些严重的代码气味,还是我应该继续这样实现它?有没有更好的方法?

下面是一个示例实现:

代码语言:javascript
复制
namespace WidgetTier
{
    public class Widget
    {
        private string _name;

        public string Name
        {
            get { return _name; }
        }

        private TierManager _tm;
        private static readonly Random random = new Random();

        static Widget()
        {
        }

        public Widget(string name, TierManager tm)
        {
            _name = name;
            _tm = tm;
        }

        public void DoMyThing()
        {
            if (random.Next(1000) > 1)
            {
                _tm.Add();
            }
        }
    }

    //NOT thread-safe!
    public class TierManager
    {
        private Dictionary<int, List<Widget>> _tiers;
        private int _tierCount = 0;
        private int _currentTier = -1;
        private int _childCount = 0;

        public TierManager()
        {
            _tiers = new Dictionary<int, List<Widget>>();
        }

        public void Add()
        {
            if (_currentTier + 1 >= _tierCount)
            {
                _tierCount++;
                _tiers.Add(_currentTier + 1, new List<Widget>());
            }
            _tiers[_currentTier + 1].Add(new Widget(string.Format("({0})", _childCount), this));
            _childCount++;
        }

        //Dangerous?
        public void Sweep()
        {
            _currentTier = 0;
            while (_currentTier < _tierCount)  //_tierCount will start at 1 but keep increasing because child objects will keep adding more tiers.
            {
                foreach (Widget w in _tiers[_currentTier])
                {
                    w.DoMyThing();
                }
                _currentTier++;
            }
        }

        public void PrintAll()
        {
            for (int t = 0; t < _tierCount; t++)
            {
                Console.Write("Tier #{0}: ", t);
                foreach (Widget w in _tiers[t])
                {
                    Console.Write(w.Name + "  ");
                }
                Console.WriteLine();
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            TierManager tm = new TierManager();

            for (int c = 0; c < 10; c++)
            {
                tm.Add();   //create base widgets;
            }

            tm.Sweep();
            tm.PrintAll();

            Console.ReadLine();
        }
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-03-30 20:23:52

Randolpho和LBushkin均为+1。

然而,我仔细考虑了一下,我想我知道为什么会有这种味道。我所实现的模式似乎是Builder模式的某种变态。更好的做法是从一系列分析步骤中创建一个组合,作为一个整体,它代表了某种有意义的状态。分析过程(行为)的每个步骤都应该与输出复合(状态)不同。我在上面实现的东西将状态和行为结合在一起。由于状态持有者和状态分析器是同一个对象,这也违反了单一责任原则。具有复合“构建本身”的方法打开了创建恶性循环的可能性,即使我上面的原型具有确定性完成。

链接:

Builder Pattern

Composite Pattern

票数 0
EN

Stack Overflow用户

发布于 2010-03-30 05:32:01

是的,我把下面的代码称为嗅觉:

代码语言:javascript
复制
        _currentTier = 0; 
        while (_currentTier < _tierCount)  //_tierCount will start at 1 but keep increasing because child objects will keep adding more tiers. 
        { 
            foreach (Widget w in _tiers[_currentTier]) 
            { 
                w.DoMyThing(); 
            } 
            _currentTier++; 
        } 

当集合发生变化时,您正在对它进行迭代。我指的是第一次迭代,而不是第二次。你显然是在解释这个变化(因此是< _tierCount而不是标准的foreach),但它仍然是一种气味,国际海事组织。

我会让它进入生产代码吗?有可能。这取决于场景。但我会对此感到肮脏。

另外:你的_tiers成员可以很容易地成为一个List<List<Widget>>

票数 2
EN

Stack Overflow用户

发布于 2010-03-30 05:29:32

这里最大的潜在问题是,Sweep方法正在迭代一个集合(_tiers),该集合在调用Widget.DoMyThing()时可能会发生变化。

.NET BCL类不允许在迭代时更改集合。代码的结构方式暴露了可能发生这种情况的风险。

除此之外,另一个问题是程序的结构使得很难理解以什么顺序发生了什么。也许您可以将递归组装模型的程序阶段与访问模型并执行计算的部分分开。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2541375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档