设为首页 收藏本站
查看: 1471|回复: 0

[经验分享] OCP开放-封闭原则

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-11-8 12:51:54 | 显示全部楼层 |阅读模式
  软件实体(类,模块,函数等)应该是可扩展的,但是不可修改
优点:通过扩展已有软件系统,可以提供新的行为,以满足对软件的新的需求,使变化中的软件有一定的适应性和灵活性。已有软件模块,特别是最重要的抽象层模块不能再修改,这使变化中的软件系统有一定的稳定性和延续性。
下边举一个从不符合ocp到符合ocp的例子,shap示例在很多书中提到,我们这里用它来阐明ocp。不符合ocp的代码如下:
DSC0000.gif class Circle
DSC0001.gif DSC0002.gif    
...{
DSC0003.gif         
private double Radius;

        
public double radius
DSC0004.gif DSC0005.gif         
...{
            
get ...{ return Radius; }
            
set ...{ Radius = value; }
DSC0006.gif         }

        
private double x;

        
public double X
        
...{
            
get ...{ return x; }
            
set ...{ x = value; }
        }

        
private double y;

        
public double Y
        
...{
            
get ...{ return y; }
            
set ...{ y = value; }
        }

        
public void Draw()
        
...{
            Console.WriteLine(
"画圆");
        }

DSC0007.gif     }

class Square
   
...{
        
private double x;

        
public double X
        
...{
            
get ...{ return x; }
            
set ...{ x = value; }
        }

        
private double y;

        
public double Y
        
...{
            
get ...{ return y; }
            
set ...{ y = value; }
        }


        
private double lenth;

        
public double Lenth
        
...{
            
get ...{ return lenth; }
            
set ...{ lenth = value; }
        }

        
private double width;

        
public double Width
        
...{
            
get ...{ return width; }
            
set ...{ width = value; }
        }

        
public void Draw()
        
...{
            Console.WriteLine(
"画正方形");
        }


    }

static void Main(string[] args)
        
...{
            List
<object> list = new List<object>();
            list.Add(
new Circle());
            list.Add(
new Square());
            DrawAll(list);
        }

        
static void DrawAll(List<object> list)
        
...{
            
foreach (object var in list)
            
...{
               
if (var is Circle)
               
...{
                    ((Circle)var).Draw();
                }

               
else
               
...{
                    ((Square)var).Draw();
                }

            }

        }
  以上代码的问题是当增加新的图形时DrawAll函数要做比较大的修改工作,这很容易影响原本可以正常工作的部分,因为增加图形的变化可能性非常大,而且实际上当从画一种图形到画两种图形时我们已经发现了问题,我们不能再错过改成错误的机会,我们要对以上源代码进行大规模的重构。
interface IShap
   
...{
        
void Draw();
    }

class Circle : IShap
   
...{
        
private double Radius;

        
public double radius
        
...{
            
get ...{ return Radius; }
            
set ...{ Radius = value; }
        }

        
private double x;

        
public double X
        
...{
            
get ...{ return x; }
            
set ...{ x = value; }
        }

        
private double y;

        
public double Y
        
...{
            
get ...{ return y; }
            
set ...{ y = value; }
        }

        
public void Draw()
        
...{
            Console.WriteLine(
&quot;画圆&quot;);
        }


    }

class Square : IShap
   
...{
        
private double x;

        
public double X
        
...{
            
get ...{ return x; }
            
set ...{ x = value; }
        }

        
private double y;

        
public double Y
        
...{
            
get ...{ return y; }
            
set ...{ y = value; }
        }


        
private double lenth;

        
public double Lenth
        
...{
            
get ...{ return lenth; }
            
set ...{ lenth = value; }
        }

        
private double width;

        
public double Width
        
...{
            
get ...{ return width; }
            
set ...{ width = value; }
        }

        
public void Draw()
        
...{
            Console.WriteLine(
&quot;画正方形&quot;);
        }


    }

static void Main(string[] args)
        
...{
            List
<IShap> list = new List<IShap>();
            list.Add(
new Circle());
            list.Add(
new Square());
            DrawAllShap(list);
        }

        
static void DrawAllShap(List<IShap> list)
        
...{
            
foreach (IShap shap in list)
            
...{
                shap.Draw();
            }

        }
  以上代码在增加新的图形的时候只需实现Ishap接口,根本就不需要修改DrawAllShap函数,这样DrawAllShap函数就符合了ocp。
  当画图时需要按某种顺序时,这种设计就没办法符合ocp原则了,如下更改是在需要顺序支持德尔符合ocp设计的代码(表格法)
class CompareShap:IComparer<IShap>
   
...{
        Dictionary
<Type, int> table = new Dictionary<Type, int>();
        
public CompareShap()
        
...{
            table.Add(
typeof(Circle), 1);
            table.Add(
typeof(Square), 2);
        }


        
private int PriorityFor(Type type)
        
...{
            
if (table.ContainsKey(type))
            
...{
               
return table[type];
            }

            
else
            
...{
               
return 0;
            }

        }


        
IComparer 成员#region IComparer<IShap> 成员

        
public int Compare(IShap x, IShap y)
        
...{

            
int p1 = PriorityFor(x.GetType());
            
int p2 = PriorityFor(y.GetType());
            
return p1.CompareTo(p2);
        }


      
        
#endregion
    }
  调用程序:
class Program
   
...{
        
static void Main(string[] args)
        
...{
            List
<IShap> list = new List<IShap>();
            list.Add(
new Circle());
            list.Add(
new Square());
            DrawAllShap(list);
        }

        
static void DrawAllShap(List<IShap> list)
        
...{
            list.Sort(
new CompareShap());
            
foreach (IShap shap in list)
            
...{
                shap.Draw();
            }

        }

    }
             版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-136602-1-1.html 上篇帖子: OCP 培训经历 下篇帖子: 【9】OCP:开放--封闭原则
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表