• 设计模式--享元模式和组合模式


    享元模式

    享元模式(Flyweight Pattern)又称为轻量模式,是对象池的一种实现。类似于线程池,线程池可以避免不停的创建和销毁多个对象,销毁性能。提供了减少对象数量从而改善应用所需的对象结构的方式。其宗旨是共享细粒度对象,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗,属于结构型模式。

    应用场景:

    1. 常常应用于系统底层的开发,以便解决系统的性能问题。
    2. 系统有大量相似对象,需要缓存池的场景。

    利用缓存机制实现享元模式: 

    1. import java.util.Map;
    2. import java.util.Random;
    3. import java.util.concurrent.ConcurrentHashMap;
    4. interface ITicket{
    5. void showInfo(String bunk);
    6. }
    7. class TrainTicket implements ITicket{
    8. private String from;
    9. private String to;
    10. private int price;
    11. public TrainTicket(String from, String to) {
    12. this.from = from;
    13. this.to = to;
    14. }
    15. @Override
    16. public void showInfo(String bunk) {
    17. this.price = new Random().nextInt(500);
    18. System.out.println(String.format("%s->%s: %s价格: %s 元",this.from,this.to,bunk,this.price));
    19. }
    20. }
    21. class TicketFactory{
    22. private static Map sTicketPool = new ConcurrentHashMap<>();
    23. public static ITicket queryTicket(String from, String to){
    24. String key = from + "->" + to;
    25. if(TicketFactory.sTicketPool.containsKey(key)){
    26. System.out.println("使用缓存:"+ key);
    27. return TicketFactory.sTicketPool.get(key);
    28. }
    29. System.out.println("首次查询,创建对象:" + key);
    30. ITicket ticket = new TrainTicket(from, to);
    31. TicketFactory.sTicketPool.put(key,ticket);
    32. return ticket;
    33. }
    34. }

    JDK中Integer类型使用了享元模式,例如:。在Java中-128到127之间的数据在int范围类是直接从缓存中取值的。

    1. public class Test {
    2. public static void main(String[] args) {
    3. Integer a = Integer.valueOf(100);
    4. Integer b = 100;
    5. Integer c = Integer.valueOf(1000);
    6. Integer d = 1000;
    7. System.out.println(a==b); //true
    8. System.out.println(b==d); //false
    9. }
    10. }

    组合模式 

    组合模式(Composite Pattern)也称为整体-部分模式,它的宗旨是通过将单个对象和组合对象用相同的接口进行表示,使得客户对单个对象和组合对象的使用具有一致性,属于结构型模式。

    组合关系和聚合关系的区别:

    1. 组合关系:一只狗可以生多只小狗,但每只小狗只有一个妈妈(具有相同的生命周期)。
    2. 聚合关系:一个老师有很多学生,但每个学生又有多个老师(具有不同的生命周期)。

    透明组合模式的写法:透明组合模式把所有的公共方法都定义在Component中,这样做的好处是客户端无需分辨是叶子节点和树枝节点,它们具备完全一致性的接口;缺点是叶子节点得到一些它所不需要的方法,这与设计模式 接口隔离相违背。

    1. import lombok.Data;
    2. import java.util.ArrayList;
    3. import java.util.List;
    4. abstract class CourseComponent{
    5. public void addChild(CourseComponent catalogComponent){
    6. throw new UnsupportedOperationException("不支持添加操作");
    7. }
    8. public void removeChild(CourseComponent catalogComponent){
    9. throw new UnsupportedOperationException("不支持删除操作");
    10. }
    11. public String getName(CourseComponent catalogComponent){
    12. throw new UnsupportedOperationException("不支持获取名称操作");
    13. }
    14. public double getPrice(CourseComponent catalogComponent){
    15. throw new UnsupportedOperationException("不支持获取价格操作");
    16. }
    17. public void print(){
    18. throw new UnsupportedOperationException("不支持打印操作");
    19. }
    20. }
    21. @Data
    22. class Course extends CourseComponent{
    23. private String name;
    24. private double price;
    25. public Course(String name, double price) {
    26. this.name = name;
    27. this.price = price;
    28. }
    29. @Override
    30. public void print() {
    31. System.out.println(name + "(¥" + price + "元)");
    32. }
    33. }
    34. class CoursePackage extends CourseComponent{
    35. private List items = new ArrayList<>();
    36. private String name;
    37. private Integer level;
    38. public CoursePackage(String name, Integer level) {
    39. this.name = name;
    40. this.level = level;
    41. }
    42. @Override
    43. public void addChild(CourseComponent catalogComponent) {
    44. items.add(catalogComponent);
    45. }
    46. @Override
    47. public String getName(CourseComponent catalogComponent) {
    48. return this.name;
    49. }
    50. @Override
    51. public void removeChild(CourseComponent catalogComponent) {
    52. items.remove(catalogComponent);
    53. }
    54. @Override
    55. public void print() {
    56. System.out.println(this.name);
    57. for (CourseComponent catalogComponent : items){
    58. if(this.level != null){
    59. for(int i=0;i<this.level;i++){
    60. System.out.print(" ");
    61. }
    62. for(int i=0;i<this.level;i++){
    63. System.out.print("-");
    64. }
    65. }
    66. catalogComponent.print();
    67. }
    68. }
    69. }
    70. public class Test {
    71. public static void main(String[] args) {
    72. System.out.println("=========透明组合模式==========");
    73. CourseComponent javaBase = new Course("Java入门",8200);
    74. CourseComponent ai = new Course("人工智能",5000);
    75. CourseComponent packageCourse = new CoursePackage("Java架构师",2);
    76. CourseComponent design = new Course("设计模式",1500);
    77. packageCourse.addChild(design);
    78. CourseComponent catalog = new CoursePackage("课程主目录",1);
    79. catalog.addChild(javaBase);
    80. catalog.addChild(ai);
    81. catalog.addChild(packageCourse);
    82. catalog.print();
    83. }
    84. }

    安全组合模式的写法:好处是接口定义职责清晰,符合设计模式单一职责原则和接口隔离原则;缺点是客户需要区分树枝节点和叶子节点,客户端无法依赖抽象,违背了设计模式依赖倒置原则。

    1. import lombok.Data;
    2. import java.util.ArrayList;
    3. import java.util.List;
    4. abstract class CourseComponent{
    5. public void print(){
    6. throw new UnsupportedOperationException("不支持打印操作");
    7. }
    8. }
    9. @Data
    10. class Course extends CourseComponent{
    11. private String name;
    12. private double price;
    13. public Course(String name, double price) {
    14. this.name = name;
    15. this.price = price;
    16. }
    17. @Override
    18. public void print() {
    19. System.out.println(name + "(¥" + price + "元)");
    20. }
    21. }
    22. class CoursePackage extends CourseComponent{
    23. private List items = new ArrayList<>();
    24. private String name;
    25. private Integer level;
    26. public CoursePackage(String name, Integer level) {
    27. this.name = name;
    28. this.level = level;
    29. }
    30. public void addChild(CourseComponent catalogComponent) {
    31. items.add(catalogComponent);
    32. }
    33. public String getName(CourseComponent catalogComponent) {
    34. return this.name;
    35. }
    36. public void removeChild(CourseComponent catalogComponent) {
    37. items.remove(catalogComponent);
    38. }
    39. @Override
    40. public void print() {
    41. System.out.println(this.name);
    42. for (CourseComponent catalogComponent : items){
    43. if(this.level != null){
    44. for(int i=0;i<this.level;i++){
    45. System.out.print(" ");
    46. }
    47. for(int i=0;i<this.level;i++){
    48. System.out.print("-");
    49. }
    50. }
    51. catalogComponent.print();
    52. }
    53. }
    54. }
    55. public class Test {
    56. public static void main(String[] args) {
    57. System.out.println("=========透明组合模式==========");
    58. CourseComponent javaBase = new Course("Java入门",8200);
    59. CourseComponent ai = new Course("人工智能",5000);
    60. CoursePackage packageCourse = new CoursePackage("Java架构师",2);
    61. CourseComponent design = new Course("设计模式",1500);
    62. packageCourse.addChild(design);
    63. CoursePackage catalog = new CoursePackage("课程主目录",1);
    64. catalog.addChild(javaBase);
    65. catalog.addChild(ai);
    66. catalog.addChild(packageCourse);
    67. catalog.print();
    68. }
    69. }

  • 相关阅读:
    目标检测网络系列——Faster-RCNN(实验部分)
    数据库的基本操作
    OpenDRIVE地图第二篇:车道LANE
    华为认证 | 11月底这门HCIP认证即将发布!
    2022 极术通讯-“周易”NPU软件开源项目上线,适配100多种AI算法
    vue中禁止ios浏览器页面滚动的橡皮筋效果
    2022杭电多校(五)
    原论文一比一复现 | RT-DETR更换华为最新主干网络【VanillaNet-5】【VanillaNet-6】【VanillaNet-9】【VanillaNet-12】【VanillaNet-13】
    【Vue】数据监视&输入绑定
    【VUE】Vue中实现树状表格结构编辑与版本对比的详细技术实现
  • 原文地址:https://blog.csdn.net/qq_38619449/article/details/136289083