享元模式和组合模式

一、享元模式

类似于线程池这一类,将使用的类缓存起来的方式就叫做享元模式。

二、使用步骤

1.示例

比方说我想实现买车,不同的车类型显示不同的价格

代码如下(示例):
抽象一个车类

public interface ICar {

    void showMessage(String type);
}

车类

public class Car implements ICar{

    private String name;

    private int price;


    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public Car(String name) {
        this.name = name;
    }


    public String getName() {
        return name;
    }

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

    public void showMessage(String type) {
        price = new Random().nextInt(800);
        System.out.println("名称为:"+name+"的,类型为:"+type+"的车售价"+price+"万元");
    }
}

车场

public class CarFactory {

    /**
     * 和容器式单例的区别是在于,我不管你创建了几次,我的重点是重复利用
     */
    private static Map<String,ICar> cars = new HashMap<String,ICar>();

    public static ICar getCar(String name){
        String key = name;
        if(cars.containsKey(key)){
            System.out.println("缓存");
            return cars.get(key);
        }else {
            System.out.println("首次");
            ICar car = new Car(name);
            cars.put(key, car);
            return car;
        }
    }
}

测试一下
在这里插入图片描述
咱们来看一下jdk中的运用看一下代码

        String s1 = "hello";
        String s2 ="he"+"llo";
        String s3 = new String("hello");
        String s4 = "he"+new String("llo");
        String s5="he";
        String s6="llo";
        String s7=s5+s6;
        System.out.println(s1==s2);
        System.out.println(s1==s3);
        System.out.println(s1==s4);
        System.out.println(s1==s7);
        System.out.println(s3==s4);
  1. s1==s2为true 原因就是String的常量池,其实就是一个享元模式。在编译阶段,jvm在常量池中加了一个对象s1,然后s2发现在常量池中有,所以是相等的。
  2. s1==s3为false 因为new了一个,在堆内存中开辟了一块内存,所以自然不相等。new 出了一个对象hello,然后常量池中放了一个hello,s3一共是两个对象。
  3. s1==s4 为false同上。但是s4有三个对象,he,new的llo,llo。
  4. s1==s7为false,因为s5和s6是变量,所以需要程序运行时才能计算,这样的话就跟 hello不是一个对象了。

再来看一个例子
        Integer integer = Integer.valueOf(127);
        Integer i=127;
        Integer integer2 = Integer.valueOf(128);
        Integer i2=128;
         System.out.println(integer==i);//true
        System.out.println(integer2==i2);//false

看一下源码
在这里插入图片描述
可以发现如果这个值在-128到127之间就从缓存中拿,否则new,这就是也是为啥超过了127就不相等

2.组合模式

组合模式,其实就是对多态的一种灵活运用,及所有类都会调用同一种方法来实现各自不同的功能。

场景:省市级 北京–朝阳区—亚运村

城市树抽象类

public abstract class CityTree {
    public String name;

    public String getName() {
        return name;
    }

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

    public CityTree(String name) {
        this.name = name;
    }

    public void show(){};
}

省份类

public class Provice extends CityTree{

    private List<CityTree> trees = new ArrayList<CityTree>();

    private int level;

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public Provice(String name,int level) {
        super(name);
        this.level = level;
    }

    public void show(){
        System.out.println(this.name);
        for (CityTree tree:trees) {
            if(this.level!=0){
                for (int j = 0; j < level; j++) {
                    System.out.print("  ");
                }
                for (int j = 0; j < level; j++) {
                    if(j==0){
                        System.out.print("+");
                    }
                    System.out.print("-");
                }
            }
            tree.show();
        }
    }

    public void add(CityTree ... cityTrees){
        trees.addAll(Arrays.asList(cityTrees));
    }
}

城市类

public class City extends CityTree{
    public City(String name) {
        super(name);
    }

    public void show() {
        System.out.println(this.name);
    }
}

测试一下

在这里插入图片描述
出来了,Spring中对此也有运用,例如SqlNode,他的实现类都会调用apply这个方法,是一条线。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值