日期:2014-05-16  浏览次数:20857 次

工厂模式对修改封闭,对扩展开放的迷惑
最经在学习工厂模式时遇到一个迷惑的问题:
场景如下:
有一个IDAL层创建一个IUserDAL接口,该接口有UpdateStatus一个方法
DAL层创建一个UserDAL类实现IUserDAL接口,并实现IUserDAL的UpdateStatus方法
DAL层创建一个InnerUserDAL类实现IUserDAL接口,并实现IUserDAL的UpdateStatus方法
DAL层创建一个OuterUserDAL类实现IUserDAL接口,并实现IUserDAL的UpdateStatus方法
Factory类分别有三个方法返回UserDAL,InnerUserDAL,InnerUserDAL的实例
结构就是这样,现在用户提出一个需求,需要更新UserName,我就需要在IUserDAL里面新增一个方法UpdateUserName
同时,修改IDAL新增UpdateUserName,由于修改了接口,就需要修改所有实现接口的类,需要所有类都要实现接口的所有方法,所以我必须修改InnerUserDAL,OuterUserDAL同时新增UpdateUserName方法。

我觉得这样就改起来很麻烦,并且违背了开放封闭原则,请高手来帮忙解惑。
所以按照我的理解,我只需要在UserDAL里面扩展一个UpdateUserName的方法,却由于工厂模式导致需要去修改IDAL的IUserDAL,是我选择的设计模式不合理,还是我的理解有问题?
------解决方案--------------------
你动了你设计的程序结构的根基(接口),所以导致了全部都得修改!
你可以试着多重实现接口,而不是去修改一个接口,可以达到只修改你实现的接口类!
interface A { function a }
class AA implements A
class BB implements A
class Factory { A getAA();   B getBB();}
当你需要添加一个函数时,可新建一个接口B
interface B {function b}
class AA implements A,B
你这样实际并不需要修改BB以及Factory类,也能达到目的
------解决方案--------------------
写错一个地方
class Factory { A getAA();   B getBB();}
修改成
class Factory { A getAA();   A getBB();}
------解决方案--------------------
再啰嗦一句:接口是整个程序的合同契约,如果你变动了接口,也就是擅自修改了合同,既然违约了,就要承担违约带来的后果!呵呵
------解决方案--------------------

public interface IUserDAL
    {
        IList Query();

        void Login(string UserCode);
        
        //增加新函数
    }

    public abstract class AUserDAL : IUserDAL
    {

        public abstract IList Query();

        public virtual void Login(string UserCode)
        {
            if (UserCode != "admin")
            {
                throw new Exception("用户不存在。");
            }
        }

        //实现新函数若有可能不同则添加 virtual 关键字
    }

    public class InnerUserDAL : AUserDAL
    {
        public override IList Query()
        {
            return null;
        }
    }

    public class UserDAL : AUserDAL
    {
        public override IList Query()
        {
            return null;