您的位置:首页 > 其它

设计模式(十五)—模版方法(行为型)

2013-04-11 21:32 471 查看

一、简介(Brief Introduction)

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模版方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤(通过把不变行为搬移到超类,去除子类中重复代码来体现它的优势)。

二、模式分析(Analysis)



抽象类(AbstractClass): 定义抽象的原语操作,具体的子类将重定义它们以实现一个算法, 实现一个模板方法,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义

具体子类 (ConcreteClass): 实现原语操作以完成算法中与特定子类相关的步骤。

三、案例分析(Example)

namespace 模版方法

{

1、改成虚方法Answer1(),用来子类重写父类的方法,因为每个人的答案都是不同的

class TestPaper                                                                              

    {

        //试题1

        public void TestQuestion1()

        {

           Console.WriteLine("鲁迅最爱吃的水果[]a.苹果 b.香蕉 c.橘子");

            Console.WriteLine("答案是:"+ Answer1());

        }

 

        //试题2

        public void TestQuestion2()

        {

           Console.WriteLine("鲁迅最喜欢的颜色[]a.红b.蓝c.绿");

            Console.WriteLine("答案是:"+Answer2());

        }

 

        //试题3

        public void TestQuestion3()

        {

            Console.WriteLine("人口大国[]a.中国b.美国 c.俄罗斯");

            Console.WriteLine("答案是:"+Answer3());

        }

        protected virtual string Answer1()   //此方法是用来子类重写父类的

        {

            return "";

        }

        protected virtual string Answer2()

        {

            return "";

        }

        protected virtual string Answer3()

        {

            return "";

        }

    }


2、子类重写父类方法后,把答案写上就可

//甲的试卷

    class TestPaperA : TestPaper

    {

        protected override string Answer1()

        {

            return "b";

        }

        protected override string Answer2()

        {

            return "c";

 

        }

        protected override string Answer3()

        {

            return "b";

        }

 

    }

    //乙的试卷

    class TestPaperB : TestPaper

    {

        protected override string Answer1()

        {

            return "a";

        }

        protected override string Answer2()

        {

            return "b";

        }

        protected override string Answer3()

        {

            return "c";

        }

    }


3、客户端

class Program

    {

        static void Main(string[] args)

        {

           Console.WriteLine("甲的试卷:");

            TestPaper studentA = newTestPaperA();           //用子类变量声明改成了父类,利用了多态性,实现了代码的复用

            studentA.TestQuestion1();

            studentA.TestQuestion2();

            studentA.TestQuestion3();

 

           Console.WriteLine("乙的试卷:");

            TestPaper studentB = newTestPaperB();

            studentB.TestQuestion1();

            studentB.TestQuestion2();

            studentB.TestQuestion3();

 

            Console.Read();

        }

    }

}

四、解决的问题(What To Solve)

1) 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。

2)各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。

3)控制子类扩展。模板方法只在特定点调用“ hook”操作 ,这样就只允许在这些点进行扩展。

五、优缺点(Advantage and Disadvantage)

优点:

(1)模板方法模式在一个类中形式化地定义算法,而由它的子类实现细节的处理。

(2)模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。

(3)模板方法模式导致一种反向的控制结构,这种结构有时被称为“好莱坞法则”,即“别找我们,,我们找你”通过一个父类调用其子类的操作(而不是相反的子类调用父类),通过对子类的扩展增加新的行为,符合“开闭原则”

缺点:
(1)每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,但是更加符合“单一职责原则”,使得类的内聚性得以提高。

六、联系(Link)

1)策略模式:模板方法使用继承来改变算法的一部分。Strategy使用委托来改变整个算法。模板方法模式与策略模式的作用十分类似,有时可以用策略模式替代模板方法模式。模板方法模式通过继承来实现代码复用,而策略模式使用委托,把不确定的行为集中到一个接口中,并在主类委托这个接口。委托比继承具有更大的灵活性。

七、总结(Summary)

1)模板方法模式是一种类的行为型模式,在它的结构图中只有类之间的继承关系,没有对象关联关系。

2)模版方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一。在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。

3)在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意。模板方法模式是一种使用频率较高的模式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: