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();
   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值