装饰者模式和桥接模式

装饰者模式

装饰者模式的话相对简单一些,其中只有两个重要的角色,一个是被装饰者,一个就是装饰器。

下面来看一个例子。在这个例子当中,被装饰者是Human类(这里Human是以一种接口的形式)的对象(当然也包括Human类的子类),装饰器是我们自定义的一些类名,只是逻辑上抽象出来的,就暂且叫它们Decorator_first、Decorator_second。。。。等,而这些类都是Decorator接口的实现类。

以下是代码例子:

1.定义一个接口

package decorator;

public interface Human {
    void wearClothes();
    void goAndPlay();
}

2.实现改接口的抽象类

package decorator;

public abstract class Decorator implements Human{
}

3.定义一个装饰器Decorator_first

package decorator;

public class Decorator_first extends Decorator{
    Human human;

    public Decorator_first(Human human) {
        this.human = human;
    }

    void methodsForWearingClothes(){
        System.out.println("先起床");
        System.out.println("找衣服");
        System.out.println("穿衣服");
    }
    @Override
    public void wearClothes() {
        this.human.wearClothes();
        methodsForWearingClothes();
    }

    @Override
    public void goAndPlay() {
        this.human.goAndPlay();
    }
}

4.定义一个装饰器Decorator_second

package decorator;

public class Decorator_second extends Decorator{
    Human human;

    public Decorator_second(Human human) {
        this.human = human;
    }

    void methodsForGoingToPlay(){
        System.out.println("找地图");
        System.out.println("找自己喜欢的地方");
        System.out.println("出发");
    }

    @Override
    public void wearClothes() {
        this.human.wearClothes();
    }

    @Override
    public void goAndPlay() {
        this.human.goAndPlay();
        methodsForGoingToPlay();
    }
}

5.测试类

package decorator;

public class Test {
    public static void main(String[] args) {
        Human human=new Human() {
            @Override
            public void wearClothes() {
                System.out.println("想要穿衣服");
            }

            @Override
            public void goAndPlay() {
                System.out.println("我想要出去玩");
            }
        };
        human=new Decorator_second(new Decorator_first(human));
        human.wearClothes();
        human.goAndPlay();
    }
}

6.测试结果

想要穿衣服
先起床
找衣服
穿衣服
我想要出去玩
找地图
找自己喜欢的地方
出发

1.这里为了对被装饰者进行装饰,将装饰者聚合在了装饰器类中(或者是装饰器接口的实现类中)

2.为了实现装饰完被装饰者后能够再次装饰,需要装饰器本身就是被装饰者类的继承类或者是实现类,所以这里Decorator本身就是一个Human,这里是用了实现,而Decorator作为一个抽象类,不做任何具体实现

桥接模式

先分享一个图:

在这里插入图片描述 桥接模式的本质还是聚合,利用java的多态特性。

首先是有右侧Implementor的实现树,然后在抽象层中的Abstraction类中聚合了Implementor这个多态对象,而在Abstraction这棵继承树上可以再对聚合的Implementor这个对象进行更多的处理,比如RefinedAbstraction通过继承的方式以对implementor在另一个维度进行拓展。

代码例子:

1.一个电子器件的接口

package bridge2;

public interface Electronics {
    void printName(String brand);
}

2.电子器件有不同的实现类,例如手机、电视机、电冰箱。。。

package bridge2;

public class Phone implements Electronics{
    @Override
    public void printName(String brand) {
        System.out.println("我是一个手机,品牌是;"+brand);
    }
}
package bridge2;

public class Refrigirator implements Electronics{
    @Override
    public void printName(String brand) {
        System.out.println("我是一个电冰箱,品牌是;"+brand);
    }
}
package bridge2;

public class Televition implements Electronics{
    @Override
    public void printName(String brand) {
        System.out.println("我是一个电视机,品牌是;"+brand);
    }
}

3.上面是对电子器件在产品品类上的拓展,如果想要在品牌上再进行拓展:

package bridge2;

public abstract class ElectronicsWithBrand {
    Electronics electronics;
    String brand;

    public ElectronicsWithBrand(Electronics electronics) {
        this.electronics = electronics;
    }

    public void sayNameWithBrand() {
        this.electronics.printName(this.brand);
    }
}

4.拓展不同的品牌

package bridge2;

public class HuaweiPhone extends ElectronicsWithBrand{
    public HuaweiPhone(Electronics electronics) {
        super(electronics);
        this.brand="huawei";
    }
}
package bridge2;

public class SamsungPhone extends ElectronicsWithBrand{

    public SamsungPhone(Electronics electronics) {
        super(electronics);
        this.brand="samsung";
    }

}

5.测试

package bridge2;

public class Test {
    public static void main(String[] args) {
        ElectronicsWithBrand samsungPhone=new SamsungPhone(new Phone());
        samsungPhone.sayNameWithBrand();
        ElectronicsWithBrand huaweiPhone=new HuaweiPhone(new Phone());
        huaweiPhone.sayNameWithBrand();
    }
}

6.测试结果

我是一个手机,品牌是;samsung
我是一个手机,品牌是;huawei

jdbc的话感觉并不是桥接模式,更多的是一个工厂模式:

private static Connection getConnection(
        String url, java.util.Properties info, Class<?> caller) throws SQLException {
        /*
         * When callerCl is null, we should check the application's
         * (which is invoking this class indirectly)
         * classloader, so that the JDBC driver class outside rt.jar
         * can be loaded from here.
         */
        ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
        synchronized(DriverManager.class) {
            // synchronize loading of the correct classloader.
            if (callerCL == null) {
                callerCL = Thread.currentThread().getContextClassLoader();
            }
        }

        if(url == null) {
            throw new SQLException("The url cannot be null", "08001");
        }

        println("DriverManager.getConnection(\"" + url + "\")");

        // Walk through the loaded registeredDrivers attempting to make a connection.
        // Remember the first exception that gets raised so we can reraise it.
        SQLException reason = null;

        for(DriverInfo aDriver : registeredDrivers) {
            // If the caller does not have permission to load the driver then
            // skip it.
            if(isDriverAllowed(aDriver.driver, callerCL)) {
                try {
                    println("    trying " + aDriver.driver.getClass().getName());
                    Connection con = aDriver.driver.connect(url, info);
                    if (con != null) {
                        // Success!
                        println("getConnection returning " + aDriver.driver.getClass().getName());
                        return (con);
                    }
                } catch (SQLException ex) {
                    if (reason == null) {
                        reason = ex;
                    }
                }

            } else {
                println("    skipping: " + aDriver.getClass().getName());
            }

        }

        // if we got here nobody could connect.
        if (reason != null)    {
            println("getConnection failed: " + reason);
            throw reason;
        }

        println("getConnection: no suitable driver found for "+ url);
        throw new SQLException("No suitable driver found for "+ url, "08001");
    }

这里从registeredDrivers中找到对应的Driver的实现类对象后,调用connect可以获得到对象的Connection的实现类对象,而不同的Connection实现类对象具体的操作数据库的方式必然不同。

那因为不同的数据库操作方式肯定不同,所以不同的数据库驱动会对应获得到不同的Connection实现类对象,这里也是用了多态的概念,只有这里有一点桥接模式的影子。事实上桥接模式解决的问题是防止类爆炸,实现对一个抽象概念在不同维度上的拓展。而jdbc驱动这块更像是一个工厂模式。(个人见解,勿喷哈)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_34116044

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值