Java设计模式-结构性设计模式(享元设计模式)

简介

  属于结构型模式,主要⽤于减少创建对象的数量,以减少内存占⽤和提⾼性能, 它提供了减少对象数量从⽽改善应⽤所需的对象结构的⽅式
  享元模式尝试重⽤现有的同类对象,如果未找到匹配的对象,则创建新对象

应用场景

  JAVA 中的 String,如果字符串常量池⾥有则返回,如果没有则创建⼀个字符串保存在字符串常量池⾥⾯
  数据库连接池、线程池等
  如果系统有⼤量相似对象,或者需要⽤需要缓冲池的时候可以使⽤享元设计模式,也就是⼤家说的池化技术
  如果发现某个对象的⽣成了⼤量细粒度的实例,并且这些实例除了⼏个参数外基本是相同的,如果把那些共享参数移到类外⾯,在⽅法调⽤时将他们传递进来,就可以通过共享对象,减少实例的个数

内部状态

  不会随环境的改变⽽有所不同,是可以共享的

外部状态

  不可以共享的,它随环境的改变⽽改变的,因此外部状态是由客户端来保持(因为环境的变化⼀般是由客户端引起的)

Java设计模式-结构性设计模式(享元设计模式)_第1张图片

角色

  抽象享元⻆⾊:为具体享元⻆⾊规定了必须实现的⽅法,⽽外部状态就是以参数的形式通过此⽅法传⼊
  具体享元⻆⾊:实现抽象⻆⾊规定的⽅法。如果存在内部状态,就负责为内部状态提供存储空间
  享元⼯⼚⻆⾊:负责创建和管理享元⻆⾊。要想达到共享的⽬的,这个⻆⾊的实现是关键
  客户端⻆⾊:维护对所有享元对象的引⽤,⽽且还需要存储对应的外部状态

案例demo

  某人接了外包项⽬,开发了⼀个AI⽹站模板,可以根据不同的客户需求⾃动⽣成不同类型的⽹站电商类、企业产品展示、信息流等。
  在部署的时候就麻烦了,是不是每个机器都⽤租⽤云服务器,购买独⽴域名呢
  这些⽹站结构相似度很⾼,⽽且都不是⾼访问量⽹站,可以先公⽤服务器资源,减少服务器资源成本,类似虚拟机或者Docker

抽象享元⻆⾊

public abstract class CloudWebSite {

    public abstract void run(Company company);

}

具体享元⻆⾊

public class ConcreteWebSite extends CloudWebSite {

    private String category;

    public  ConcreteWebSite(String category){
        this.category = category;
    }


    @Override
    public void run(Company company) {
        System.out.println("网站分类:"+category+", 公司:"+company.getName());

    }
}

享元⼯⼚⻆⾊

public class WebSiteFactory {

    /**
     * map里面的key是分类
     */
    private Map<String,ConcreteWebSite> map = new HashMap<>();


    /**
     * 根据key获取分类站点
     * @param category
     * @return
     */
    public CloudWebSite getWebSiteByCategory(String category){

        if(map.containsKey(category)){
            return map.get(category);
        }else {
            ConcreteWebSite site = new ConcreteWebSite(category);
            map.put(category,site);
            return site;
        }
    }
    /**
     * 获取分类个数
     * @return
     */
    public int getWebsiteCategorySize(){
        return map.size();
    }

}

客户端⻆⾊

public class Company {

    private String name;

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

    public Company(){}

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

测试

public class Main {

    public static void main(String[] args) {


        WebSiteFactory factory = new WebSiteFactory();

        CloudWebSite companySite1 =  factory.getWebSiteByCategory("企业官网");
        companySite1.run(new Company("aa课堂"));

        CloudWebSite companySite2 =  factory.getWebSiteByCategory("企业官网");
        companySite2.run(new Company("bb课堂"));

        CloudWebSite byteDanceSite =  factory.getWebSiteByCategory("信息流");
        byteDanceSite.run(new Company("字节跳动"));

        CloudWebSite ucNews =  factory.getWebSiteByCategory("信息流");
        ucNews.run(new Company("优视科技"));

        System.out.println("网站分类总数:" +factory.getWebsiteCategorySize());


    }
}

结果

网站分类:企业官网,公司: aa课堂
网站分类:企业官网,公司: bb课堂
网站分类:信息渡,公司:字节跳动
网站分类:信息流,公司:优视科技
网站分类总数:2

优缺点

优点

  ⼤⼤减少了对象的创建,降低了程序内存的占⽤,提⾼效率

缺点

  提⾼了系统的复杂度,需要分离出内部状态和外部状态
  注意划分内部状态和外部状态,否则可能会引起线程安全问题,必须有⼀个⼯⼚类加以控制

享元设计模式和原型、单例模式的区别

  原型设计模式是指定创建对象的种类,然后通过拷⻉这些原型来创建新的对象
  单例设计模式保证⼀个类仅有⼀个实例

你可能感兴趣的:(java,设计模式,享元设计模式)