设计模式(一) 单例模式/工厂模式

设计模式一 单例模式,工厂模式

单例模式

简述:是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

  1. 单例类只能有一个实力
  2. 单例类必须自己创建自己的唯一实力
  3. 单例类可以给所有其他对象提供这一个实例

如今实际开发中,单例模式都交给spring的bean工厂进行处理

/**
 * 饿汉式
 * 类加载到内存后,就实例化一个单例,JVM保证线程安全
 * 简单实用,推荐使用!
 * 唯一缺点:不管用到与否,类装载时就完成实例化
 * Class.forName("")
 * (话说你不用的,你装载它干啥)
 */
public class Mgr01 {
    private static final Mgr01 INSTANCE = new Mgr01();

    private Mgr01() {};

    public static Mgr01 getInstance() {
        return INSTANCE;
    }

    public void m() {
        System.out.println("m");
    }

    public static void main(String[] args) {
        Mgr01 m1 = Mgr01.getInstance();
        Mgr01 m2 = Mgr01.getInstance();
        System.out.println(m1 == m2);
    }
}

/**
 * 跟01是一个意思
 */
public class Mgr02 {
    private static final Mgr02 INSTANCE;
    static {
        INSTANCE = new Mgr02();
    }

    private Mgr02() {};

    public static Mgr02 getInstance() {
        return INSTANCE;
    }

    public void m() {
        System.out.println("m");
    }

    public static void main(String[] args) {
        Mgr02 m1 = Mgr02.getInstance();
        Mgr02 m2 = Mgr02.getInstance();
        System.out.println(m1 == m2);
    }
}
/**
 * lazy loading(懒加载模式)
 * 也称懒汉式
 * 虽然达到了按需初始化的目的,但却带来线程不安全的问题
 */
public class Mgr03 {
    private static Mgr03 INSTANCE;

    private Mgr03() {
    }

    public static Mgr03 getInstance() {
        if (INSTANCE == null) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            INSTANCE = new Mgr03();
        }
        return INSTANCE;
    }

    public void m() {
        System.out.println("m");
    }

    public static void main(String[] args) {
        for(int i=0; i<100; i++) {
            new Thread(()->
                System.out.println(Mgr03.getInstance().hashCode())
            ).start();
        }
    }
}

/**
 * lazy loading
 * 也称懒汉式
 * 虽然达到了按需初始化的目的,但却带来线程不安全的问题
 * 可以通过synchronized解决,但也带来效率下降
 */
public class Mgr04 {
    private static Mgr04 INSTANCE;

    private Mgr04() {
    }

    public static synchronized Mgr04 getInstance() {
        if (INSTANCE == null) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            INSTANCE = new Mgr04();
        }
        return INSTANCE;
    }

    public void m() {
        System.out.println("m");
    }

    public static void main(String[] args) {
        for(int i=0; i<100; i++) {
            new Thread(()->{
                System.out.println(Mgr04.getInstance().hashCode());
            }).start();
        }
    }
}

/**
 * 静态内部类方式
 * JVM保证单例
 * JVM在装载静态方法的时候只装在一次,加之其加了final关键词;
 * 加载外部类时不会加载内部类,这样可以实现懒加载
 */
public class Mgr05 {

    private Mgr05() {
    }

    private static class Mgr05Holder {
        private final static Mgr05 INSTANCE = new Mgr07();
    }

    public static Mgr05 getInstance() {
        return Mgr05Holder.INSTANCE;
    }

    public void m() {
        System.out.println("m");
    }

    public static void main(String[] args) {
        for(int i=0; i<100; i++) {
            new Thread(()->{
                System.out.println(Mgr05.getInstance().hashCode());
            }).start();
        }
    }


}

/**
 * 不仅可以解决线程同步,还可以防止反序列化。
 * 枚举类没有构造方法; 
 */
public enum Mgr06 {

    INSTANCE;

    public void m() {}

    public static void main(String[] args) {
        for(int i=0; i<100; i++) {
            new Thread(()->{
                System.out.println(Mgr06.INSTANCE.hashCode());
            }).start();
        }
    }

}

工厂模式

  1. 简单工厂–可拓展性差
  2. 静态工厂–单例模式
  3. 抽象工厂
    1. 抽象类和接口的区别问题:
      1. 抽象类主要是代码层面,因为其可以有普通方法,可以增加代码的复用,接口是在架构设计层面,起到约束代码的作用
      2. 接口都是抽象方法,抽象类可以有普通方法,接口无普通成员变量,抽象类可以有普通成员变量(如1所述);
      3. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型;
      4. 抽象类可以包含静态方法,接口不行,1.8之后可以,1.8以后的接口不再纯净
      5. 继承与实现的问题,单继承,多实现;
      6. 另,抽象类和接口,表达的语意不同,抽象类–》具体事物的抽象
    2. 抽象工厂更多是为了进行生成对象族;用工厂的方法,继承实现其方法得到不同族系的工厂类,从而从不同的工厂得到不同族系的对象;
  4. 更好的解决方案–>Spring的bean工厂 ,Spring->IOC,控制反转;spring的ioc可以理解为工厂模式的高级实现

抽象工厂的代码如下:

public abstract class AbastractFactory {
    abstract Food createFood();
    abstract Vehicle createVehicle();
    abstract Weapon createWeapon();
}
public abstract class Weapon {
    abstract void shoot();
}
public abstract class Vehicle { //interface
    abstract void go();
}
public abstract class Vehicle { //interface
    abstract void go();
}
public class AK47 extends Weapon{
    public void shoot() {
        System.out.println("tututututu....");
    }
}
public class MagicStick extends Weapon{
    public void shoot() {
        System.out.println("diandian....");
    }
}

public class Car extends Vehicle{

    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}
public class Broom extends Vehicle{
    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}

public class MushRoom extends Food{
    public void printName() {
        System.out.println("dmg");
    }
}
public class Bread extends Food{
    public void printName() {
        System.out.println("bread talk");
    }
}
public class MagicFactory extends AbastractFactory {
    @Override
    Food createFood() {
        return new MushRoom();
    }

    @Override
    Vehicle createVehicle() {
        return new Broom();
    }

    @Override
    Weapon createWeapon() {
        return new MagicStick();
    }
}
public class ModernFactory extends AbastractFactory {
    @Override
    Food createFood() {
        return new Bread();
    }

    @Override
    Vehicle createVehicle() {
        return new Car();
    }

    @Override
    Weapon createWeapon() {
        return new AK47();
    }
}

public class Main {
    public static void main(String[] args) {
        AbastractFactory f = new ModernFactory();

        Vehicle c = f.createVehicle();
        c.go();
        Weapon w = f.createWeapon();
        w.shoot();
        Food b = f.createFood();
        b.printName();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值