当前位置: 首页 > news >正文

Java面向对象七大原则以及设计模式单例模式和工厂模式简单工厂模式

面向对象的七大原则(OOP)

1,开闭原则:

对扩展开发,对修改关闭

2.里氏替换原则:

继承必须确保超类所拥有的子类的性质在子类中仍然成立

3.依赖倒置原则:

面向接口编程,不要面向实现编程,降低程序之间的耦合性

4.单一职责原则:

控制类的粒度大小,将对象解耦,提高其内聚性

5.接口隔离原则:

要为各个类创建他们专用的接口

6.迪米特法则:

只于你的直接朋友交谈,不跟陌生人交谈

7.合成复用法则:

尽量先使用组合或者聚合等关联来实现,其次才考虑使用集成关系来实现

单例模式

饿汉模式

public class Hunger{
    private Hunger(){}
    private final static Hunger HUNGER_SINGLTON = new Hunger();
    public static Hunger getInstrente(){
        return HUNGER_SINGLTON;
    }
}

懒汉模式

第一种,不考虑安全的问题

public class LayzeMan{
    private static LayzMan LAYZE_MAN;
    private LayzeMan(){
        System.out.println(Thread.currentThread().getName()+"ok");
    }
    public static LayzeMan getInstrence(){
        if(LAYZE_MAN == null){
            LATZE_MAN = new LayzeMan();
        }
        return LAYZE_MAN;
    }
}
/**

该单例模式在使用普通创建对象时,可以实现对象的单例

还存在两个问题

  1. 使用多线程可以破坏该单例模式
  2. 使用反射可以破坏该单例模式

解决多线程破坏单例模式的方法

public class Layze{
    private volatile static Layze lay;
    private Layze(){
        
    }
    /**
    三重检测锁   DCL模式
    **/
    public static Layze getInstance(){
        if(lay == null){
            synchorized(Layze.class){
                if(lzy == null){
                     lay = new Layze();   
                }
            }
        }
    }
}

此时使用多线程破坏单例模式的问题已经可以解决

解决反射破坏单例模式的问题

public calss LayzeMan{
    private static volatile LayzeMan layze;
    private LayzeMan(){
        synchorized(LayzeMan.class){
            if(layze !=null){
                throw new RuntimeException("不要试图使用反射去破坏我的单例模式");
            }
        }
    }
    public static LayzeMan getInstrence(){
        if(layze == null){
            synchorized(LayzeMan.class){
                if(layze == null){
                    layze = new LayzeMan();
                }
            }
        }
        return layze;
    }
}
class test{
    public static void main(String[] args){
        LayzeMan layzeMan = LayzeMan.getInstrence();
        Constructor<LazyPJie> declaredConstructor = LazyPJie.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);
        LazyPJie lazyPJie1 = declaredConstructor.newInstance();
        System.out.println(lazyPJie);
        System.out.println(lazyPJie1);
    }
}


此时会报错

Exception in thread "main" java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
	at com.itcast.designMode.single.Test01.main(LazyPJie.java:41)
Caused by: java.lang.RuntimeException: 不要试图使用反射破坏单例模式

此时还会有一个问题:就是在类中判断对象是否为空时,判断了有没有第一个对象用普通方式去创建对象的时候,这个时候使用反射的时候就会报出异常,但是,此时如果两个对象都使用反射去创建就会出问题,单例模式就会又被破坏

代码如下

 public static void main(String[] args) throws Exception {
     /* LazyPJie lazyPJie = LazyPJie.getInstance();*/
      Constructor<LazyPJie> declaredConstructor = LazyPJie.class.getDeclaredConstructor(null);
      declaredConstructor.setAccessible(true);
      LazyPJie lazyPJie1 = declaredConstructor.newInstance();
      LazyPJie lazyPJie = declaredConstructor.newInstance();
      System.out.println(lazyPJie);
      System.out.println(lazyPJie1);
   }

解决完全使用反射破坏单例模式

public calss LayzeMan{
    private static volatile LayzeMan layze;
    private static boolean flag = flase;
    private LayzeMan(){
        synchorized(LayzeMan.class){
           if(!flag){
               flag = ture;
           }else{
                throw new RuntimeException("不要试图使用反射去破坏我的单例模式");
           }
        }
    }
    public static LayzeMan getInstrence(){
        if(layze == null){
            synchorized(LayzeMan.class){
                if(layze == null){
                    layze = new LayzeMan();
                }
            }
        }
        return layze;
    }
}
class test{
    public static void main(String[] args) throws Exception {
     /* LazyPJie lazyPJie = LazyPJie.getInstance();*/
      Constructor<LazyPJie> declaredConstructor = LazyPJie.class.getDeclaredConstructor(null);
      declaredConstructor.setAccessible(true);
      LazyPJie lazyPJie1 = declaredConstructor.newInstance();
      LazyPJie lazyPJie = declaredConstructor.newInstance();
      System.out.println(lazyPJie);
      System.out.println(lazyPJie1);
   }
}

枚举(天然的单例模式)

package com.itcast.designMode.single;

/**
 * author:hlc
 * date:2023/9/18
 */
public enum EnumClass {
   ENUM_CLASS;
   public EnumClass getEnumClass(){
      return ENUM_CLASS;
   }
}
class Test03{
   public static void main(String[] args) {
      EnumClass enumClass = EnumClass.ENUM_CLASS;
   }
}

静态内部类

package com.itcast.designMode.single;

/**
 * author:hlc
 * date:2023/9/18
 */
public class Holder {
   /**
    * 静态内部类实现单例模式
    */
   private Holder(){}
   public static Holder getInstance(){
      return InnerClass.HOLDER;
   }
   public static class InnerClass{
      private static final Holder HOLDER = new Holder();
   }
}

工厂模式

  1. 实现了创建者和调用者的分离
  2. 满足原则
    1. 开闭原则
    2. 依赖倒转原则
    3. 迪米特法则

实例化对象不使用new,而是使用方法

简单工厂模式

package com.itcast.designMode.factory;

public interface Car {
   void name();
}

package com.itcast.designMode.factory;

/**
 * author:hlc
 * date:2023/9/18
 */
public class Tesila implements Car{
   @Override
   public void name() {
      System.out.println("特斯拉");
   }
}



package com.itcast.designMode.factory;

/**
 * author:hlc
 * date:2023/9/18
 */
public class WuLing implements Car{
   @Override
   public void name() {
      System.out.println("五菱");
   }
}

package com.itcast.designMode.factory;

/**
 * author:hlc
 * date:2023/9/18
 */
public class CarFactory {
   public static Car getCar(String name){
      if (name.equals("五菱")){
         return new WuLing();
      }else if (name.equals("特斯拉")){
         return new Tesila();
      }else {
         return null;
      }
   }
}

 public static void main(String[] args) {
      Car car = CarFactory.getCar("五菱");
      Car car1 = CarFactory.getCar("特斯拉");
      car1.name();
      car.name();
   }

相关文章:

  • 什么是回归测试?
  • C++QT day9
  • 区域气象-大气化学在线耦合模式(WRF/Chem)在大气环境领域实践技术应用
  • java基础题--数组
  • qt day2
  • postman连接websocket, 建立连接、聊天测试(v8.5.1)
  • docker 网络模式 与 ftp 主动模式与被动模式
  • 如何获取美团的热门商品和服务
  • 数据结构与算法之Set布隆过滤器
  • Jenkins List Git Branches插件 构建选择指定git分支
  • 外包干了2个月,技术退步明显。。。。。
  • python基础语法(三)
  • 【八大经典排序算法】冒泡排序
  • 目标检测中生成锚框函数详解
  • Python爬虫:获取必应图片的下载链接
  • MySQL 解决数据重复添加
  • C语言——贪吃蛇小游戏
  • 82 # koa-bodyparser 中间件的使用以及实现
  • Java程序连接 Mysql 超时问题 - 数据包过大,导致超时,# 配置网络超时时间 socketTimeout: 1800000
  • Python3.10 IDLE更换主题
  • 金光耀:被激活的复旦记忆
  • 对话|四代中国缘的麦肯锡前高管:在混乱中制定规则,而不是复制旧秩序
  • 上海消保委调查二次元消费:手办与卡牌受欢迎,悦己和社交是动力
  • 外交部:中方近日派出停火监督组赴缅,监督缅军和果敢同盟军停火
  • 去年净流入人口达45万,居各省份第一:浙江带来哪些启示?
  • 大理杨徐邱上诉案开庭:当事人称曾接受过两次测谎测试