Open/Close OOPS 中的原理

Open/Close Principle in OOPS

我正在从事一个电信项目。我在我的项目中实现了 Open/Closed 原则。以下是我的 classes.

MainServiceClass.CS

public abstract class BaseServiceClass
{
    public abstract IEnumerable<string> GetServiceData();
    public abstract IEnumerable<string> GetDashBoardData();
}

Web_Service.CS

public class WebServiceClass : BaseServiceClass
{
    public override IEnumerable<string> GetServiceData()
    {
        List<string> MyList = new List<string>();
        return MyList;
    }

    public override IEnumerable<string> GetDashBoardData()
    {
        List<string> MyList = new List<string>();
        return MyList;
    }
}

Voice_Service.CS

public class VoiceSericeClass : BaseServiceClass
{
    public override IEnumerable<string> GetServiceData()
    {
        List<string> MyList = new List<string>();
        return MyList;
    }

    public override IEnumerable<string> GetDashBoardData()
    {
        List<string> MyList = new List<string>();
        return MyList;
    }
}

以后如果需要实现Video服务,我会新建一个Video_Service class.I相信我会实现Open/Close的原则。

如果我需要在我的 MainServiceClass.cs 中添加一个新方法,我将添加一个新方法 (GetNewTypeOfData())。

问题:在这里,我正在修改一个class。不过,我是否在遵循 OCP?或者,有没有办法在 MainServiceClass.cs 中添加新方法??

求推荐。

P.S。我需要在所有派生的 class 中实现此方法,即 Web_Service.cs、Voice_Service.cs 和 Video_Service.cs

Updating my question after CrudaLilium reply.

这是我的理解。如有不妥请指正

我的当前代码:

 public interface IMainBase
{
    IEnumerable<string> GetData2016();
}

public class VoiceService : IMainBase
{
    public IEnumerable<string> GetData2016()
    {
        return Enumerable.Empty<string>();
    }
}

我将在 2017 年收到新要求。因此,我将在 2017 年更新我的代码

public interface IMainBase
{
    IEnumerable<string> GetData2016();
}    

public class VoiceService : IMainBase
{
    public IEnumerable<string> GetData2016()
    { 
        return Enumerable.Empty<string>();
    }
}

//New Code will be Added in 2017....Start

public interface IMainBase2017 : IMainBase
{
    IEnumerable<string> GetData2017();
}

public class voiceService2017 : VoiceService, IMainBase2017
{
    public IEnumerable<string> GetData2017()
    {
        return Enumerable.Empty<string>();
    }
}

//New Code Added be in 2017...Ended

我将在 2018 年再次收到新需求。因此,我将在 2018 年更新我的代码。

 public interface IMainBase
{
    IEnumerable<string> GetData2016();
}    

public class VoiceService : IMainBase
{
    public IEnumerable<string> GetData2016()
    { 
        return Enumerable.Empty<string>();
    }
}

//New Code will be Added in 2017....Start

public interface IMainBase2017 : IMainBase
{
    IEnumerable<string> GetData2017();
}

public class voiceService2017 : VoiceService, IMainBase2017
{
    public IEnumerable<string> GetData2017()
    {
        return Enumerable.Empty<string>();
    }
}

//New Code Added be in 2017...Ended

//New Code will be Added in 2018...Start

public class WebService2018 : IMainBase2017
{
    public IEnumerable<string> GetData2016()
    {
        return Enumerable.Empty<string>();
    }

    public IEnumerable<string> GetData2017()
    {
        return Enumerable.Empty<string>();
    }
}


//New Code will be Added in 2018...End

根据上面的代码,我没有违反OCP。这是一个好的做法还是我还有其他方法?

创建 Video_Service 不是问题,但更改 BaseServiceClass 是问题,您不会遵循原则。

如果将其抽象化,则需要修改从 BaseServiceClass 继承的所有其他 class。但是,即使您不将其抽象化,它似乎也毫无意义,因为所有当前使用您的 BaseServiceClass 的客户端 class 不使用任何其他方法,除了您已经拥有的 2 种方法。

如果您的客户 class 需要使用第三种方法,如果您创建另一个继承自 [=12 的抽象 class(例如 BaseServiceClass2)会更好=] 并在那里添加新方法并使您的客户端依赖于此 class。从那里扩展你现有的 classes WebServiceClassVoiceSericeClass 你必须创建新的 class 并继承 BaseServiceClass2 并使用适配器模式。

示例代码:

    public abstract class BaseServiceClass
    {
        public abstract IEnumerable<string> GetServiceData();
        public abstract IEnumerable<string> GetDashBoardData();
    }

    public abstract class BaseServiceClass2 : BaseServiceClass
    {
        public abstract IEnumerable<string> GetNewTypeOfData();
    }


    public class WebServiceClass2 : BaseServiceClass2
    {
        private BaseServiceClass adaptee;

        WebServiceClass2(BaseServiceClass adaptee)
        {
            this.adaptee = adaptee;
        }

        public override IEnumerable<string> GetDashBoardData()
        {
            return adaptee.GetDashBoardData();
        }

        public override IEnumerable<string> GetNewTypeOfData()
        {
            return Enumerable.Empty<string>();
        }

        public override IEnumerable<string> GetServiceData()
        {
            return adaptee.GetServiceData();
        }
    }

如果你制作 BaseServiceClass 一个界面会更好,如果你需要添加任何新的东西,你只需创建继承它的新界面,就像前面的例子一样,让你的客户端 class 取决于你的新接口,从那里你可以创建新的 class 继承自 WebServiceClassVoiceSericeClass 等并实现新接口。

示例:

    public interface IBaseServiceClass
    {
        IEnumerable<string> GetServiceData();
        IEnumerable<string> GetDashBoardData();
    }

    public interface IBaseServiceClass2 : IBaseServiceClass
    {
        IEnumerable<string> GetNewTypeOfData();
    }


    public class WebServiceClass2 : WebServiceClass, IBaseServiceClass2
    {
        public IEnumerable<string> GetNewTypeOfData()
        {
            return Enumerable.Empty<string>();
        }
    }

    public class WebServiceClass : IBaseServiceClass
    {
        public IEnumerable<string> GetServiceData()
        {
            List<string> MyList = new List<string>();
            return MyList;
        }

        public IEnumerable<string> GetDashBoardData()
        {
            List<string> MyList = new List<string>();
            return MyList;
        }
    }

Class/interface 名称仅用作占位符,最好以更有意义的方式命名。