大话设计模式,让你的代码更完美6---模版方法模式/迪米特

来源:互联网 发布:轩辕剑崆峒印进阶数据 编辑:程序博客网 时间:2024/06/05 03:34

需求:甲乙学生对同样的试卷进行回答,并写出作答答案。

甲的代码:

    //学生甲抄的试卷    class TestPaperA    {        //试题1        public void TestQuestion1()        {            Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 ");            Console.WriteLine("答案:b");        }        //试题2        public void TestQuestion2()        {            Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化  ");            Console.WriteLine("答案:a");        }        //试题3        public void TestQuestion3()        {            Console.WriteLine(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对   ");            Console.WriteLine("答案:c");        }    }

乙的代码:

    //学生乙抄的试卷    class TestPaperB    {        //试题1        public void TestQuestion1()        {            Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 ");            Console.WriteLine("答案:d");        }        //试题2        public void TestQuestion2()        {            Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化  ");            Console.WriteLine("答案:b");        }        //试题3        public void TestQuestion3()        {            Console.WriteLine(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对   ");            Console.WriteLine("答案:a");        }    }
主函数:

        static void Main(string[] args)        {            Console.WriteLine("学生甲抄的试卷:");            TestPaperA studentA = new TestPaperA();            studentA.TestQuestion1();            studentA.TestQuestion2();            studentA.TestQuestion3();            Console.WriteLine("学生乙抄的试卷:");            TestPaperB studentB = new TestPaperB();            studentB.TestQuestion1();            studentB.TestQuestion2();            studentB.TestQuestion3();            Console.Read();        }
第一次改进,将两者相同的部分抽取出来:

    //考题试卷    class TestPaper    {        public void TestQuestion1()        {            Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 ");        }        public void TestQuestion2()        {            Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化  ");        }        public void TestQuestion3()        {            Console.WriteLine(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对   ");        }    }
学生甲:
    class TestPaperA : TestPaper    {        public new void TestQuestion1()        {            base.TestQuestion1();            Console.WriteLine("答案:b");        }        public new void TestQuestion2()        {            base.TestQuestion2();            Console.WriteLine("答案:b");        }        public new void TestQuestion3()        {            base.TestQuestion3();            Console.WriteLine("答案:b");        }    }
学生乙:

    class TestPaperB : TestPaper    {        public new void TestQuestion1()        {            base.TestQuestion1();            Console.WriteLine("答案:b");        }        public new void TestQuestion2()        {            base.TestQuestion2();            Console.WriteLine("答案:b");        }        public new void TestQuestion3()        {            base.TestQuestion3();            Console.WriteLine("答案:b");        }    }
主函数:

        static void Main(string[] args)        {            Console.WriteLine("学生甲抄的试卷:");            TestPaperA studentA = new TestPaperA();            studentA.TestQuestion1();            studentA.TestQuestion2();            studentA.TestQuestion3();            Console.WriteLine("学生乙抄的试卷:");            TestPaperB studentB = new TestPaperB();            studentB.TestQuestion1();            studentB.TestQuestion2();            studentB.TestQuestion3();            Console.Read();        }
最终改进,第一次修改中,学生的作答过于麻烦,需要进一步凝练代码,即将相同的部分尽最大化的放置在父类中:

    class TestPaper    {        public void TestQuestion1()        {            Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 ");            Console.WriteLine("答案:" + Answer1());        }        public void TestQuestion2()        {            Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化  ");            Console.WriteLine("答案:" + Answer2());        }        public void TestQuestion3()        {            Console.WriteLine(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对   ");            Console.WriteLine("答案:" + Answer3());        }        protected virtual string Answer1()        {            return "";        }        protected virtual string Answer2()        {            return "";        }        protected virtual string Answer3()        {            return "";        }    }
学生甲和学生乙:

    //学生甲抄的试卷    class TestPaperA : TestPaper    {        protected override string Answer1()        {            return "b";        }        protected override string Answer2()        {            return "c";        }        protected override string Answer3()        {            return "a";        }    }    //学生乙抄的试卷    class TestPaperB : TestPaper    {        protected override string Answer1()        {            return "c";        }        protected override string Answer2()        {            return "a";        }        protected override string Answer3()        {            return "a";        }    }
主函数:

        static void Main(string[] args)        {            Console.WriteLine("学生甲抄的试卷:");            TestPaper studentA = new TestPaperA();            studentA.TestQuestion1();            studentA.TestQuestion2();            studentA.TestQuestion3();            Console.WriteLine("学生乙抄的试卷:");            TestPaper studentB = new TestPaperB();            studentB.TestQuestion1();            studentB.TestQuestion2();            studentB.TestQuestion3();            Console.Read();        }
总结:所谓继承,就是将重复的代码提升到父类上去,而不是让每个子类重复。

在最终修改中,使用了所谓的模板模式,即当要完成某一细节层次一致的一个过程或一系列步骤,

其个别步骤在更详细的层次上的实现可能不同需要用模版方法方式处理。(在本例中主要体现在甲乙两人试卷相同,只有答案不同

于是在父类中,把试卷放到父类中,然后把答案放到子类中,即创建了一个虚方法给子类重写,使得子类完全不需要关心试卷是什么样的,只需要返回答案即可。


结构图的演进:



下列代码为模版方法模式的模板:

顶级父类中放了抽象行为,让子类去实现。

然后放了个模版方法给出了逻辑的骨架,而逻辑的组成是一些相应操作,这些操作都推迟到子类实现。

(逻辑骨架里面可也放试卷,抽象方法让子类去填写答案,这里的抽象没有参数和返回值,根据个人情况更改)

在主函数中:首先声明试卷,然后填写答案。

    ///顶级父类    abstract class AbstractClass    {        public abstract void PrimitiveOperation1();        public abstract void PrimitiveOperation2();        public void TemplateMethod()        {            PrimitiveOperation1();            PrimitiveOperation2();            Console.WriteLine("");        }    }    ///具体实现类A    class ConcreteClassA : AbstractClass    {        public override void PrimitiveOperation1()        {            Console.WriteLine("具体类A方法1实现");        }        public override void PrimitiveOperation2()        {            Console.WriteLine("具体类A方法2实现");        }    }    ///具体实现类B    class ConcreteClassB : AbstractClass    {        public override void PrimitiveOperation1()        {            Console.WriteLine("具体类B方法1实现");        }        public override void PrimitiveOperation2()        {            Console.WriteLine("具体类B方法2实现");        }    }   ///主函数:        static void Main(string[] args)        {            AbstractClass c;            c = new ConcreteClassA();            c.TemplateMethod();            c = new ConcreteClassB();            c.TemplateMethod();            Console.Read();        }
迪米特法则:其根本思想就是强调类的松耦合,如果两个类不直接彼此通信,那么这两个类就不应该发生直接的相互作用,

若其中一个类需要调用另外一个类的某个方法,最好是通过第三者。

其中每个类都应该降低成员的访问权限,使得类与类之间松耦合。

例子:张三刚去一个公司,人事部李四安排IT部王五给你装系统,然后王五有事走了,你又去找李四,李四说你去找IT部的小六,可是小刘说我忙,

你等李四回来吧,其实这时应该让人事部李四去找IT部主管,让IT部主管安排人给你装电脑。也就是说通过主管,间接的达到目的。


所以:类之间的耦合越弱,越容易复用,一个处于弱耦合的类被修改,不会对已有关系的类造成波及影响。

即王五被修改不应该影响你的电脑系统,换句话说就是IT部应该是抽象的,只要认识该抽象类即可。

0 0
原创粉丝点击