定义和实现分离
定义和实现分离,oop的编程,或则.....我也不知道,这边文章改定义什么样的标题好呢,然后......
我们来看一段代码的优化,来逐步的体会一下;
public enum ScheduleType { Once=0, Daily=1, Weekly=2 } //这种方式,我们可以使用多种方式来进行优化滴呀; //简单的swich case 方式滴啊; //然后就是我们的 委托的方式滴呀 //还有我们的 就是我们的重载的方式滴啊 //多种多样的方式和写法滴啊; public class TaskInfo { public void ShowScheduleDescription(ScheduleType type) { //这种将判断的逻辑写在了我们的函数内部滴呀; //这种方式将功能的实现(业务逻辑混合在一起了滴呀)和方法的定义 switch (type) { case ScheduleType.Once: Console.WriteLine("this is once activitys"); break; case ScheduleType.Daily: Console.WriteLine("this is week activitys"); break; case ScheduleType.Weekly: Console.WriteLine("this si weekly activitys"); break; default: throw new InvalidOperationException("unsupported sceduled..."); } } }
接下来我们做到了“看似分离的一个状态滴呀”,注意,我这里强调的是看似;
public class TaskInfo2 { public void ShowScheduleDescription(ScheduleType type) { ScheduleActivity s = new ScheduleActivity(); switch (type) { case ScheduleType.Once: s.Once("this is once"); break; case ScheduleType.Daily: s.Daily("this is dail"); break; case ScheduleType.Weekly: s.Weekly("this is weekly"); break; default: throw new InvalidOperationException("unsupported sceduled..."); } } } //这样就将我们的方法定义和我们的具体实现给分离的滴呀; public class ScheduleActivity //动态的扩展就可以在我们的这里进行了滴啊; { public void Once(string Str) { Console.WriteLine(Str); } public void Daily(string Str) { Console.WriteLine(Str); } public void Weekly(string Str) { Console.WriteLine(Str); } }
然后,就算我们通过委托将将具体的实现进行分离;也是无预计与是的,以为,我们优化的开始方向就错了;这样优化,有种多此一举的感觉;
public delegate void Del(string str); public class TaskInfo2 { public void ShowScheduleDescription(ScheduleType type) { ScheduleActivity s = new ScheduleActivity(); string val = string.Empty; Del del; switch (type) { case ScheduleType.Once: val = "this is once"; del=new Del(s.Once); break; case ScheduleType.Daily: val = "this is dail"; del=new Del(s.Daily); break; case ScheduleType.Weekly: val = "this is weekly"; del = new Del(s.Weekly); break; default: throw new InvalidOperationException("unsupported sceduled..."); } del(val); } }
其实一开始,我们只是在改变代码所在的地方,并没有实现真正意义的分离,
对于一个有经验的OO开发者,一旦看到switch,if(type=typeof(…))之类的代码马上会提高警惕
把真正意义的上实现暴露在代码的外部注册,而是不是内部;
这些改写,也许会好一点底呀;
//到了某个点之后,调用什么样的方法,我们不写在这里,而是通过事件在外部进行我们的注册 //这样我们的额程序,就有很大的扩展和提升性了滴呀; //这就给了我们这个类,足够的扩展性了滴呀; public class TaskInfo { public string val; public delegate void BoyHandler(string value); // 声明委托 public event BoyHandler BoyEvent; // 注册事件 public void ShowScheduleDescription() { if (BoyEvent != null) { BoyEvent(val); } } } 这里就是我们外部调用类的滴呀;将我们的定义和实现分离的滴呀; public class OuterClass { public void Info(ScheduleType type) { TaskInfo t = new TaskInfo(); ScheduleActivity s = new ScheduleActivity(); switch (type) { case ScheduleType.Once: t.val = "this is once"; t.BoyEvent += s.Once; break; case ScheduleType.Daily: t.val = "this is Daily"; t.BoyEvent += s.Daily; break; case ScheduleType.Weekly: t.val = "this is once"; t.BoyEvent += s.Weekly; break; default: throw new InvalidOperationException("unsupported sceduled..."); } } }
好了,上面的优化,之路很别扭,因为一开始的房方向就错了,好了,现在我们来oop优化吧
switch中进行变动;所以,并不是那么的完美,那么我们再进一步的进行优化;
public class Schedule { public virtual void ShowShowScheduleDescriptions() { //这里我们只定义,具体的实现,交给我们的额子类去实现; //这样就有了很好的扩展性,这个也是我们多肽的变现形式之一滴呀; } } public class OnceSchedule : Schedule { public override void ShowShowScheduleDescriptions() { Console.WriteLine("this is once activity"); } } public class DailySchedule : Schedule { public override void ShowShowScheduleDescriptions() { Console.WriteLine("this is daily activity"); } } public class WeeklySchedule : Schedule { public override void ShowShowScheduleDescriptions() { Console.WriteLine("this is daily Weekly"); //这样的代码很好的解决了面向过程代码的两个问题,看起来更加具有扩展性,随着新类型的Schedule引入,旧的代码完全不用改动。 } //同样我们可以使用接口来实现,不过这种方式,接种方式显德更好一些滴呀 }
over~
然后再来看看我们一段js代码 oop的优化过程;
//div0 - 长度长度加1 //div1 //div2 //div3 //div4 //div5 //div6 //div7 //上面这个就是面向过程的写法; function Change() { var div0 = document.getElementById("div0"); var div1 = document.getElementById("div1"); var div2 = document.getElementById("div2"); var div3 = document.getElementById("div3"); var div4 = document.getElementById("div4"); var div5 = document.getElementById("div5"); var div6 = document.getElementById("div6"); div0.length = div0.length + 10 + "px"; div1.length = div1.length + 10 + "px"; div2.length = div2.length + 10 + "px"; div3.length = div3.length + 10 + "px"; div4.length = div4.length + 10 + "px"; div5.length = div5.length + 10 + "px"; div6.length = div6.length + 10 + "px"; } function ChangeInfo(id,AddVal) { var obj = document.getElementById(id) obj.length = obj.length + AddVal; } function Do() { ChangeInfo("div0", AddVal) //如果,这样,就出现了,很多的副本;没有达到代码的重用id呀;没有oo的感觉 ChangeInfo("div1", AddVal) ChangeInfo("div2", AddVal) ChangeInfo("div3", AddVal) } //下面这个就是面向对象的写法; function DivObj(id,AddVal) { this.obj = document.getElementById(id) this.AddVal = AddVal; this.AddLen = function () { this.obj.length = this.length + this.AddVal + "px"; } //获取到的东东,已经是一个对象了,这个叫对象的多台扩展滴呀; //正确的做法是应该对它进行拓展,英文,当document.getElementById(id) 之后,已经是一个对象了; //有点类似于它的扩展了滴呀 } function ChangeLen() { var obj = new DivObj("div0", 10) //这些,仅仅是我抽象的一个实例吧了; obj.AddLen(); var obj1 = new DivObj("div1", 10) obj1.AddLen(); var obj2 = new DivObj("div2", 10) obj2.AddLen(); var obj3 = new DivObj("div3", 10) obj3.AddLen(); } //个人觉得,贯穿oo 的就是我们的this关键字
参考文献: http://blog.jobbole.com/102236/