zoukankan      html  css  js  c++  java
  • 设计模式大类--结构模式(上)

    大概有7中结构模式,分为上下两篇。
    一、Adapter(适配器)
    描述:将两个不兼容的类结合一起使用,一般需要用到其中某个类的若干方法
    好处:在两个类直接创建一个混合接口,而不必修改类里面的其他代码

    例子:
    假设我们要打桩,有两种类:方形桩 圆形桩.
    public class SquarePeg{
      public void insert(String str){
        System.out.println("SquarePeg insert():"+str);
      }

    }

    public class RoundPeg{
      public void insertIntohole(String msg){
        System.out.println("RoundPeg insertIntoHole():"+msg);
    }
    }

    现在有一个应用,需要既打方形桩,又打圆形桩.那么我们需要将这两个没有关系的类综合应用.假设RoundPeg我们没有源代码,或源代码我们不想修改,那么我们使用Adapter来实现这个应用:

    public class PegAdapter extends SquarePeg{

      private RoundPeg roundPeg;

      public PegAdapter(RoundPeg peg)(this.roundPeg=peg;)

      public void insert(String str){ roundPeg.insertIntoHole(str);}

    }

    二、Facade(外观)
    描述:为子系统的一组接口提供一个一致的界面
    好处:将其中不变的部分提炼出来,做成一个接口供上层使用,降低系统的复杂性,增加了灵活性

    例子:
    新建赛车类:
    package car_package;

    public class car {

    public void start() {
    System.out.println("车子已启动");
    }

    public void check_stop() {
    System.out.println("刹车检查");
    }

    public void check_box() {
    System.out.println("检查油箱");
    }

    public void check_console() {
    System.out.println("检查仪表盘是否异常");
    }

    }

    新建赛车操作的外观类:
    package car_facade;

    import car_package.car;

    public class car_facade_imple {

    public void car_go_go(car car_ref) {
    car_ref.check_box();
    car_ref.check_console();
    car_ref.check_stop();
    car_ref.start();
    }
    }


    新建客户端运行类:
    package run_main;

    import car_facade.car_facade_imple;
    import car_package.car;

    public class run_main {

    public static void main(String[] args) {
    car_facade_imple car_facade_imple_ref = new car_facade_imple();
    car_facade_imple_ref.car_go_go(new car());
    }
    }

    三、Proxy(代理模式)
    描述:为其他对象提供一种代理已控制对这个对象的访问
    好处:对于开销很大,只有使用时才创建的情况下,可以使用代理

    例子:
    比如西门庆找潘金莲,那潘金莲不好意思答复呀,咋办,找那个王婆做代理,表现在程序上时是这样的体现的
    先说说这个场景中的要素:一种类型的女人,潘金莲,王婆,西门庆,后来扩展的贾氏也和西门庆勾上了,我们是假设的,然后西门庆找潘金莲happy,但潘金莲不好意思直接,就找个王婆代理呗。我们看看具体代码。

    先定义一种女人
    public interface KindWoman {

    //这种女人能做什么事情呢?
    public void makeEyesWithMan();//抛媚眼

    public void happyWithMan();//和男人那个....

    }

    一种类型嘛,那肯定是接口,定义个潘金莲
    public class PanJinLian implements KindWoman{

    @Override
    public void happyWithMan() {
    System.out.println("潘金莲和男人在做那个...");

    }

    @Override
    public void makeEyesWithMan() {
    System.out.println("潘金莲抛媚眼...");

    }

    }

    再定义个丑陋的王婆

    public class WangPo implements KindWoman {

    private KindWoman kindWoman;

    public WangPo(){
    //默认的话是潘金莲的代理
    this.kindWoman = new PanJinLian();
    }
    //她可以是KindWomam的任何一个女人的代理,只要你是这一类型
    public WangPo(KindWoman kindWoman){
    this.kindWoman = kindWoman;
    }

    @Override
    public void happyWithMan() {
    //自己老了,干不了了,但可以叫年轻的代替。
    this.kindWoman.happyWithMan();

    }

    @Override
    public void makeEyesWithMan() {
    //王婆年纪大了,谁看她抛媚眼啊
    this.kindWoman.makeEyesWithMan();

    }

    }

    两个女主角都上场了,该男主角了,定义个西门庆
    package com.yangguangfu.proxy;

    public class XiMenQiang {

    /**
    * @param args
    */
    public static void main(String[] args) {
    WangPo wangPo;
    //把王婆叫出来
    wangPo = new WangPo();
    //然后西门庆说,我要和潘金莲Happy,然后王婆就安排了西门庆丢筷子哪出戏:
    wangPo.makeEyesWithMan();
    //看到没有表面是王婆在做,其实爽的是潘金莲
    wangPo.happyWithMan();

    }

    }

    那这就是活生生的一个例子,通过代理人实现了某种目的,如果真去了王婆这个中间环节,
    大郎看得紧(理解为这个对象开销很大),估计西门庆很难和潘金莲勾搭。

    四、Composite(组合)
    描述:将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性
    好处:a、可以一致使用组合结构和单个对象;b、不必关心组合体内是否加入新部件

    例子:
    Component接口:
    public interface Component {

    public void add(Component e);

    public void del(Component e);

    public Component get(int i);

    public void operate();
    }
    元素节点 Leaf:
    public class Leaf implements Component {

    private String name;
    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    @Override
    public void add(Component e) {
    }

    @Override
    public void del(Component e) {
    }

    @Override
    public Component get(int i) {
    return null;
    }

    @Override
    public void operate() {
    System.out.println(name);
    }
    }
    部分整体Composite:
    public class Composite implements Component {

    private List<Component> list = new ArrayList();

    @Override
    public void add(Component e) {
    list.add(e);
    }

    @Override
    public void del(Component e) {
    list.remove(e);
    }

    @Override
    public Component get(int i) {
    return list.get(i);
    }

    @Override
    public void operate() {

    Iterator it = list.iterator();
    while(it.hasNext()){
    Component component = (Component) it.next();
    component.operate();
    }
    }
    }
    客户端代码调用:
    public class Customer {

    public static void main(String[] args) {

    Leaf leaf1 = new Leaf();
    leaf1.setName("leaf1");
    Leaf leaf2 = new Leaf();
    leaf2.setName("leaf2");
    Leaf leaf3 = new Leaf();
    leaf3.setName("leaf3");
    Leaf leaf4 = new Leaf();
    leaf4.setName("leaf4");
    Leaf leaf5 = new Leaf();
    leaf5.setName("leaf5");

    Composite composite1 = new Composite();
    Composite composite2 = new Composite();
    Composite composite3 = new Composite();

    composite3.add(leaf5);
    composite2.add(composite3);
    composite2.add(leaf4);
    composite2.add(leaf3);
    composite1.add(composite2);
    composite1.add(leaf2);
    composite1.add(leaf1);

    composite1.operate();
    }
    }

    客户端代码可以轻松的调用组合对象的方法,不管里面的元素的个数有多少,树形组织结构如何,客户端都只用相同的代码便可,不用修改原有的代码

  • 相关阅读:
    2019-05-21 ping net telent命令的使用
    2019-05-21 黑客常用那几招
    2019-05-21 黑客简介
    2019-05-20 查看后台redis的进程
    清除img和文字间的空隙【vertical-align的用途】
    overflow溢出
    solr中的一些常见错误
    eclipse更改workspace中出现The superclass "javax.servlet.http.HttpServlet" was not found on the Java----问题》》
    maven遇到的一些问题
    null与“ ”
  • 原文地址:https://www.cnblogs.com/aiguozhe/p/3753844.html
Copyright © 2011-2022 走看看