解决方案 »

  1.   

    你动了你设计的程序结构的根基(接口),所以导致了全部都得修改!
    你可以试着多重实现接口,而不是去修改一个接口,可以达到只修改你实现的接口类!
    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类,也能达到目的
      

  2.   

    写错一个地方
    class Factory { A getAA();   B getBB();}
    修改成
    class Factory { A getAA();   A getBB();}
      

  3.   

    但是我觉得这没解决根本问题,对我来说我的重点的,我只是想扩展UserDAL,给它新增一个UpdateUserName的方法,却要动到它的接口IUserDAL,假如我InnerUserDAL,OuterUserDAL都没有实现IUserDAL接口,也就是说他们都有自己单独实现的接口,与IUserDAL没关系。所以我问题的最重心是我只是想扩展UserDAL,给它新增一个UpdateUserName的方法,不想去修改其他的地方,我的模式是不是需要做其他的调整,是不是用了工厂模式,这就是它的弊端了,无法避免?
      

  4.   

    并且按照你说的,我不去修改IUserDAL接口,而是去新增新的接口,让UserDAL去实现它,但是这样就有问题了,我工厂模式返回的实例是IUserDAL,对这个接口产生的实例,就不会有新增接口的UpdateUserName方法
    IUserDAL user=(IUserDAL )Factory.CreateUserDAL();
      

  5.   


    对工厂模式的调用者来说,不存在UserDAL/InnerUserDAL/OuterUserDAL,
    它只知道接口IUserDAL。如果你只扩展UserDAL, 当然没问题,只是外面看不到而已。所以问题的关键就是新增的UpdateUserName方法是不是要被外面看到。
      

  6.   

    定义一个抽象类叫AUserDAL,并实现IUserDAL接口, UserDAL\InnerUserDAL\OuterUserDAL 这个都继承 AUserDAL,当你新增接口函数时,若都是通用或可调用实现类已有参数数就能实现的,则只需修改 AUserDAL 类,若个别有差异的,则在差异类实现类重写。
    同一接口有多个实现类,并且有部份功能相同的话,建议使用抽象类,这样很方便扩展,包括接口扩展。
      

  7.   


    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;
            }        public override void Login(string UserCode)
            {
                if (UserCode != "system")
                {
                    throw new Exception("用户不存在。");
                }
            }
        }
      

  8.   

    首先你要知道,接口一旦定义好,没有足够理由就不应该再去修改
    像你这种情况可以重新定义一个接口,至于继不继承老接口,还是业务来决定
    .Net中也有类似的接口和类
      

  9.   

    DAL只负责数据访问,那么业务逻辑的变化,绝对不会涉及到DAL的变化,
    DAL层中根本就不应该出现User或者UserName之类的对象
      

  10.   


    如果你去修改你发布的接口,你如何保持“对修改封闭”呢?如果要把一种设计定型下来,并且要扩展其子类型,应该这样写public interface IDAL
    {
       ......
    }public interface IDAL_V2: IDAL
    {
    .....
    }public interface IDAL_V3:IDAL, iDAL_V2
    {
    .......
    }
      

  11.   

    你说的这个很好,虽然跟我的问题不相关,但是提出了我犯的一个错误【DAL层应与model无关】,但是同你说的DAL层负责数据访问,如果已有的方法是更新Status栏位,我现在需要更新UserName栏位,所以我还是需要在DAL层新增方法。
      

  12.   


    是我一开始选择这个原则就不对,不应该硬套原则,需要有自己的理解和变通,我觉得【ycg_893】给的方案是可行的。
      

  13.   


    你看看微软提供的DAL:ado.net的组织架构就知道了,它是通用的,
    无论你有多少查询方法,跟DAL没有关系
      

  14.   

    你把业务逻辑的东西放在了DAL,
    如果每次增加或者更新一些查询方法,还需要修改DAL,那干脆不要分层了,分层是为了重复利用已有的设计,
    分层设计的目的是使得绝大部分的设计可以在不同的项目中重复利用的,
    按照你的设计,你看看换个不同的项目,你还有多少可以重复使用