设计模式之扩展型模式

扩展型模式包括了:装饰器模式、迭代器模式和访问者模式。

1、装饰器模式(Decorator)

        以对客户透明的方式动态地给一个对象附加上更多的责任,装饰者模式相比生成子类可以更灵活地增加功能。

        优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

        缺点:多层装饰比较复杂。

       使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。 

       实现过程

              实现的核心步骤:创建装饰器继承于装饰对象的抽象类,实现装饰器抽象类,在实体装饰器里添加新的功能,这里要注意的是,装饰器里必须传入你要装饰的对象,这样才知道你要装饰的是“谁”;

              调用:通过装饰器调用被装饰对象的方法同时也调用了装饰器里新加的功能。

       举个栗子:给单一的手机功能扩展其它的功能。

       第一步:创建手机抽象类

        

        第二步:创建手机实体类(继承手机抽象类)

        

        第三步:创建装饰器抽象类(继承手机抽象类,这样才能给手机添加装饰)

       

       第四步:创建装饰实体类(继承装饰器抽象类)

       

       

       最后:实现扩展功能

       

       输出:

       

 2、 迭代器模式(Iterator)

       迭代器模式提供了一种方法顺序访问一个聚合对象(理解为集合对象)中各个元素,而又无需暴露该对象的内部表示,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

       优点: 1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。

       缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。使用foreach语句只能在对集合进行遍历,不能在遍历的同时更改集合中的元素。

       实现过程

              实现的核心步骤:创建迭代器实体类继承于迭代器抽象类,在迭代器里必须有需要遍历的集合对象,并且自定义的集合对象里需要获取到迭代器才能进行迭代遍历;

              调用:创建的迭代器对象通过集合对象获取迭代器实例,再通过迭代器遍历集合。

       举个栗子:创建一个迭代器去遍历自定义的集合

       第一步:创建迭代器抽象类或者接口

       

       第二步:创建迭代器实体类

       

       第三步:创建集合抽象类或者接口

       

       第四步:创建聚合实体类

       

       最后:使用迭代器对集合对象进行变量

       

       输出:

       

3、访问者模式(Visitor)

       表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。主要将数据结构与数据操作分离。

       优点: 1、符合单一职责原则。 2、优秀的扩展性。 3、灵活性。

       缺点: 1、具体元素对访问者公布细节,违反了迪米特原则。 2、具体元素变更比较困难。 3、违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

       使用场景: 1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。 2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。

       实现过程

              实现的核心步骤:创建的被访问实体类需要接受访问者,而访问者的访问方法里需要传入被访问实体对象,在访问者里面扩展被访问者的功能;

              调用:创建访问者实例,传入到被访问者实例,再通过被访者调用。

       举个栗子:

       第一步:创建一个表示抽象类

       

       第二步:创建表示抽象类的实体类

       

       

       第三步:创建访问者抽象类或者接口

       

        第四步:创建访问者实体类

       

       最后:调用访问者扩展表示元素的功能

      

      输出:

      

      上面的表示元素本来只有一个Accept(引入访问者)这一个方法,然而通过访问者,可以在访问者实体类里面扩展了输出的功能(当然也可以是其它的)

原文地址:https://www.cnblogs.com/Vam8023/p/8471260.html