Open closed principle 开闭原则,重构
我正在尝试将OCP应用到一个代码片段中,我有一个代码片段,它的当前状态非常糟糕,但我觉得我并没有走到最后 当前代码:Open closed principle 开闭原则,重构,open-closed-principle,Open Closed Principle,我正在尝试将OCP应用到一个代码片段中,我有一个代码片段,它的当前状态非常糟糕,但我觉得我并没有走到最后 当前代码: public abstract class SomeObject {} public class SpecificObject1 : SomeObject {} public class SpecificObject2 : SomeObject {} // Smelly code public class Model { public void Store(SomeO
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,它的责任是它不知道如何存储自己
如果出现某个对象的新实现,则缺少谁的存储实现
由于模型类中的异常存储方法,我将得到一个运行时错误,它也感觉像一种代码味道
这是因为调用代码将以
IEnumerable<SomeObject> sequence;
IEnumerable序列;
我不知道序列对象的具体类型
我似乎无法理解OCP的概念。任何人都有任何具体的例子或链接,而不仅仅是一些汽车/水果的例子?我正在介绍的模式试图为特定对象注册处理程序。对于可能出现的每种类型的对象,都必须有处理程序registerd。如果没有处理程序可以处理它,则会引发异常 您可以从您的程序集或其他程序集动态加载处理程序(实现
IHandler
)并实例化和添加它们。因此,为实现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;
}
}
}
公共接口IHandler{
bool TryHandle(SomeObject o);//返回true
}
公共类模型
{
私有列表_Handlers=新列表();
//注册一个新的处理程序
公共无效登记管理器(IHandler h){
_添加(h);
}
//这将尝试通过让所有处理程序尝试存储对象来存储对象
公共空存储(SomeObject o){
foreach(变量h在_处理程序中){
如果(h.Store(o))返回;
}
//没有处理程序能够处理该类型
抛出新异常();
}
}
公共类特定的1处理程序:IHandler
{
公共布尔句柄(SomeObject o){
如果(o是SpecificType1){
/*商店*/
return true;//我们处理了这个对象
}否则{
//我们没有资格
返回false;
}
}
}
我相信这会符合你的需要。(顺便说一句,我不知道这个模式是否有名字,如果有,我会很高兴知道。)如果你能展示哪些存储方法有不同的功能会更好。在
SomeObject
中有一个虚拟的Store
函数真的那么糟糕吗?()您可能希望实现一种策略模式,因为您的代码不太臭,违反了单一责任原则。@tafa:存储方法的不同之处在于每个SomeObject将数据存储在不同的表/类中,这些表/类具有不同的列/字段。@Andreas Brinck IMHO模型不应该是贫乏的,但它也不应该承担不属于它的责任。模型对象应该具有域功能。这是一种策略和/或责任链。