关键词搜索

源码搜索 ×
×

一篇文章带你搞定 Java 中的设计模式

发布2020-01-12浏览491次

详情内容

一、工厂设计

interface Fruit{//定义一个水果的接口
    public void eat();//吃水果的方法
}
class Apple implements Fruit{//定义子类 Apple
    public void eat(){
        System.out.println("** 吃萍果");
    }
}
class Orange implements Fruit{//定义子类Orange
    public void eat(){//覆写eat()方法
        System.out.println("**吃橘子");
    }
}

public class Test{
    public static void main(String[] args) {
        Fruit f = new Apple();//实例化接口
        f.eat();//调用方法
    }
}

    在这里插入图片描述
    子类为接口实例化后,调用被子类覆写过的方法。

    我们已知主方法实际如同一个客户端,如果此时需要更换一个子类,就必须要修改主方法,这就存在问题了。

    我们可以在接口和具体子类之间加入一个过渡段,通过过渡段取得接口实例
    在这里插入图片描述
    这个过渡段一般被称为工厂类

    class Factory{//定义工厂类
        public static Fruit getInstance(String className){
            Fruit f = null;//定义接口对象
            if("apple".equals(className)){//判断是哪个子类的标记
                f = new Apple();//通过 Apple 类实例化接口
            }
            if("orange".equals(className)){//判断是哪个子类的标记
                f = new Apple();//通过 orange 类实例化接口
            }
            return f;
        }
    }
    public class Test{
        public static void main(String[] args) {
            Fruit f = null;//定义接口对象
            f = Factory.getInstance("apple");//通过工厂取得实例
            f.eat();//调用方法
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    此时以后再有子类扩充,可以直接修改工厂类客户端就可以根据标记得到相应的实例,灵活性较高。

    同时这里的

    if("orange".equals(className))
    而不是
    if(className.equals("orange"))
    
    • 1
    • 2
    • 3

    这样做可以避免空指向异常,因为这里的className可能为空需要注意

    二、代理设计

    代理设计也是在 Java 代理主题来操作真实主题,真实主题执行具体的业务操作,而代理主题负责其他相关业务的处理,如同生活中使用的代理上网一样,客户通过网络代理连接网络,由代理服务器完成用户权限和访问限制等与上网操作相关的操作。

    interface Network{//定义 Network 接口
        public void browse();//定义浏览的抽象方法
    }
    class Real implements Network{//真实的上网操作
        public void browse(){//覆写抽象方法
            System.out.println("上网浏览信息");
        }
    }
    class Proxy implements Network{
        //代理上网
        private Network network;
        public Proxy(Network network){
            //设置代理的真实操作
            this.network = network;//设置代理的子类
        }
        public void check(){//与具体上网相关的操作
            System.out.println("检查用户是否合法");
        }
        public void browse(){
            this.check();//可以同时调用多个与具体业务相关的操作
            this.network.browse();//调用真实上网操作
        }
    }
    
    public class Test{
        public static void main(String[] args) {
            Network net = null;//定义接口对象
            //相当于向上转型,执行的都是子类覆盖后的方法
            net = new Proxy(new Real());//实例化代理,同时传入代理的真实操作
            net.browse();//客户只关心上网浏览一个功能
        }
    }
    
      21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    三、适配器设计

    对于 Java 程序来说,如果一个类要实现一个接口,必须覆写此接口中的全部抽象方法,那么如果此时一个接口中定义的抽象方法过多,但是子类中又用不到这么多抽象方法,肯定很麻烦,此时就需要一个中间的过渡,但是此过渡类又不希望被直接使用,
    所以将此过渡类定义成抽象类最合适,即一个接口首先被一个抽象类先实现(此抽象类通常称为适配器),并在此抽象类中实现若干方法(方法体为空),则以后的子类直接继承此抽象类,就可以有选择地覆写所需要的方法。

    interface Window{
        //定义Window 接口,表示窗口操作
        public void open();//窗口打开
        public void close();//窗口关闭
        public void activated();//窗口活动
        public void iconified();//窗口最小化
        public void deiconified();//窗口恢复大小
    }
    //定义抽象类实现接口,在此类中覆写方法,但是所有的方法体为空
    //这个抽象类称为适配器
    abstract class WindowAdapter implements Window{
        public void activated(){};//覆写 activated()方法,方法体为空
        public void close(){}
        public void deiconified(){}
        public void iconified(){}
        public void open(){}
    }
    //子类直接继承 WindowAdapter 类,有选择地实现需要的方法
    class WindowImp1 extends WindowAdapter{
        public void open(){
            //真正实现 open()方法
            System.out.println("窗口打开");
        }
        public void close(){
            //真正实现 close() 方法
            System.out.println("窗口关闭");
        }
    }
    public class Test{
        public static void main(String[] args) {
            Window win = new WindowImp1();//实现接口对象
            win.open();//调用 open()方法
            win.close();//调用 close()方法
        }
    }
    
      21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    由于代码中采用了适配器这个中间环节,所以子类就不用必须实现接口中的全部方法,而是有选择的实现所需要的方法

    在以后学习图形界面部分时,会有大量的事件监听接口,如果全部实现方法会相当不方便,所以在Java中提供大量的适配器类来使用

    相关技术文章

    点击QQ咨询
    开通会员
    返回顶部
    ×
    微信扫码支付
    微信扫码支付
    确定支付下载
    请使用微信描二维码支付
    ×

    提示信息

    ×

    选择支付方式

    • 微信支付
    • 支付宝付款
    确定支付下载