2

我正在尝试将 OCP 应用到我拥有的代码片段,在它的当前状态下真的很臭,但我觉得我并没有走到最后。

当前代码:

public abstract class SomeObject
{}

public class SpecificObject1 : SomeObject
{}

public class SpecificObject2 : SomeObject
{}


// Smelly code
public class Model
{
  public void Store(SomeObject someObject)
  {
    if (someObject is SpecificObject1)
    {}
    else if (someObject is SpecificObject2)
    {}
  }
}

这真的很难看,我的新方法是这样的:

// No so smelly code
public class Model
{
  public void Store(SomeObject someObject)
  {
    throw new Expception("Not allowed!");
  }

  public void Store(SpecificObject1 someObject)
  {}

  public void Store(SpecificObject2 someObject)
  {}

}

当出现新的 SomeObject 类型时,我必须实现该特定对象的存储方式,这将破坏 OCP,因为我需要更改模型类。

将存储逻辑移动到 SomeObject 也感觉不对,因为我会违反 SRP(?),因为在这种情况下 SomeObject 几乎就像一个 DTO,它的责任不是如何知道如何存储自己。

如果出现了 SomeObject 的新实现,缺少谁的 store 实现,我会因为 Model 类的 Store 方法中的异常而出现运行时错误,这也感觉像是代码异味。

这是因为调用代码的形式为

IEnumerable<SomeObject> sequence;

我不会知道序列对象的具体类型。

我似乎无法掌握 OCP 的概念。任何人都有任何具体示例或链接,而不仅仅是一些汽车/水果示例?

4

1 回答 1

1

我提出的模式尝试为特定对象注册处理程序。必须为可能发生的每种类型的对象注册处理程序。如果没有处理程序可以处理它,则会引发异常。

IHandler您可以从您的或从其他程序集动态加载处理程序(实现的所有内容)并实例化并添加注册它们。因此,为 implements 的任何类型创建一个处理程序类就足够了SomeObject

public interface IHandler {
    bool TryHandle (SomeObject o); // return true iff handled
}

public class Model
{
    private List<SIandler> _Handlers = new List<IHandlers>();

    // registers a new handler
    public void RegisterHandler (IHandler h) {
        _Handlers.Add(h);
    }

    // this tries to store an object by letting all handlers attempts to store
    public void Store (SomeObject o) {
        foreach (var h in _Handlers) {
            if (h.Store(o)) return;
        }

        // no handler was able to handle the type
        throw new Exception();
    }
}

public class Specific1Handler: IHandler
{
    public bool Handle (SomeObject o) {
        if (o is SpecificType1) {
            /* store... */
            return true; // we handled this object
        } else {
            // we're not qualified
            return false;
        }
    }
}

我相信这会满足您的需求。(顺便说一下,我不知道这种模式是否有名字,如果有的话会很高兴学习。)

于 2010-04-22T13:21:39.833 回答