访问者模式属于行为型模式。
    访问者模式是一种将数据结构和数据操作分离的设计模式。
    访问者模式比较复杂,而且实际使用的地方并不多。
    访问者模式适用于数据结构稳定的元素操作上,一旦数据结构易变,则不适用。

    角色说明:

    Visitor(抽象访问者):接口或者抽象类,为每一个元素(Element)声明一个访问的方法。
    ConcreteVisitor(具体访问者):实现抽象访问者中的方法,即对每一个元素都有其具体的访问行为。
    Element(抽象元素):接口或者抽象类,定义一个accept方法,能够接受访问者(Visitor)的访问。
    ConcreteElementA、ConcreteElementB(具体元素):实现抽象元素中的accept方法,通常是调用访问者提供的访问该元素的方法。
    Client(客户端类):即要使用访问者模式的地方。

    1. //创建抽象访问接口
    2. //因为需要存放属性所以采用abstract 抽象
    3. public abstract class web {
    4. private String name;
    5. public web(String name){
    6. this.name=name;
    7. }
    8. //授权
    9. public abstract void accept(Visitor visitor);
    10. //定义下载接口
    11. public abstract void dowonload();
    12. public String getName(){
    13. return this.name;
    14. }
    15. }
    16. //创建具体实现类
    17. public class Music extends web {
    18. public Music(String name) {
    19. super( name );
    20. }
    21. @Override
    22. public void accept(Visitor visitor) {
    23. visitor.visit(this);
    24. }
    25. @Override
    26. public void dowonload() {
    27. System.out.println("下载音乐");
    28. }
    29. }
    30. //创建具体实现类
    31. public class Video extends web {
    32. public Video(String name) {
    33. super( name );
    34. }
    35. @Override
    36. public void accept(Visitor visitor) {
    37. visitor.visit(this);
    38. }
    39. @Override
    40. public void dowonload() {
    41. System.out.println("下载视频");
    42. }
    43. }
    44. //抽象访问者
    45. public interface Visitor {
    46. void visit(Music music);
    47. void visit(Video video);
    48. }
    49. //具体访问者 PERSON ONE
    50. public class Idler implements Visitor{
    51. private String name;
    52. public Idler(String name){
    53. this.name=name;
    54. }
    55. @Override
    56. public void visit(Music music) {
    57. System.out.println(name+"正在浏览音乐");
    58. }
    59. @Override
    60. public void visit(Video video) {
    61. System.out.println(name+"正在浏览视频");
    62. }
    63. }
    64. //具体访问者 PERSON ONE
    65. public class IdlerTwo implements Visitor{
    66. private String name;
    67. public IdlerTwo(String name){
    68. this.name=name;
    69. }
    70. @Override
    71. public void visit(Music music) {
    72. System.out.println(name+"正在浏览音乐");
    73. }
    74. @Override
    75. public void visit(Video video) {
    76. System.out.println(name+"正在浏览视频");
    77. }
    78. }
    79. public class Websites {
    80. // 元素集合
    81. List <web> list = new ArrayList <>();
    82. public void accept(Visitor visitor) {
    83. Iterator <web> iterator = list.iterator();
    84. while (iterator.hasNext()) {
    85. iterator.next().accept( visitor );
    86. }
    87. }
    88. public void addWeb(web web) {
    89. list.add( web );
    90. }
    91. }
    92. public class VisitorClient {
    93. public static void main(String[] args) {
    94. Music wangyiyue = new Music("网易云音乐");
    95. Music kugou = new Music("酷狗");
    96. Video youku = new Video("优酷");
    97. Video iqiyi = new Video("爱奇艺");
    98. // 放入对象结构中
    99. Websites websites = new Websites();
    100. websites.addWeb(wangyiyue);
    101. websites.addWeb(kugou);
    102. websites.addWeb(youku);
    103. websites.addWeb(iqiyi);
    104. // 集合接受idler1的访问
    105. Visitor idler1 = new Idler("闲人1号");
    106. websites.accept(idler1);
    107. System.out.println("-------------------------------------");
    108. // 集合接受busy1的访问
    109. Visitor busy1 = new IdlerTwo("忙人2号");
    110. websites.accept(busy1);
    111. }
    112. }

    总结:单一职责,从上面代码可以看出我们要控制用户的访问的元素,对某一个音乐产品下架,其实也只需要在对象结构中移除就可以了。