单例设计模式.多例设计模式及工厂设计模式

概述:

Java基础中常用的几种设计模式:单例设计模式、多例设计模式、工厂设计模式,
模式通俗地说就是套路.根据不同的需求选择不同的编程模式

1 单例设计模式

单例模式是Java中最简单的设计模式之一.属于创建式模式.主要作用就是在整个程序期间保证某个类只能创建一个对象,节省资源.而单例设计模式又分为饿汉设计模式和懒汉设计模式

1.1饿汉设计模式

示例如下

public class Dog {
    //构造方法私有化
    private Dog() {
    }

    //直接在内部创建一个实体化对象,作为静态的成员变量,并将其私有化,唯一化
    private final static Dog dog = new Dog();

    public static Dog getInstance() {
        return dog;
    }
}

主要实现的步骤:
1.构造方法私有化,不能在类的外部再通过new创建Dog对象
2.定义一个Dog类型的成员变量,并且创建dog对象进行初始化,使用私有,静态,唯一修饰
3.提供一个公共的静态方法获取这个dog对象
由于使用类的时候已经将对象创建完毕,不管会不会使用,都先创建了,像个饿汉一样,所以称为饿汉设计模式

1.2 懒汉设计模式

示例如下:

package com.bmw.desionMode.danLi.lazy;

import java.awt.*;

public class LazyMan {
    //构造方法私有化
    private LazyMan() {
    }

    //定义私有、静态的本类型成员变量,不初始化
    private static LazyMan lazyMan;

    //提供公用的、静态的成员方法获取此对象
    //注意:多线程的时候,注意线程安全
    //解决办法就是在方法中加synchronized线程锁
    public static synchronized LazyMan getInstance() {

        //在方法内,先判断成员变量是否被初始化,如果没有被初始化再进行赋值
        //如果已经初始化,就直接返回初始值(本类对象).
        if (lazyMan == null) {
            lazyMan = new LazyMan();
        }
        return lazyMan;
    }
}

懒汉单例的实现步骤
1.构造方法私有化;
2.内部定义私有,静态的LazyMan类型的成员变量,不初始化
3.提供公有静态的成员方法,获取lazyMan对象
4.方法内先判读成员属性是否被初始化
4.1没有被初始化就进行初始化
4.2已经初始化就直接返回lazyMan这个对象
懒汉单例设计模式只有调用getInstance()方法才创建对象.
所以称为"懒汉模式"

2 多例设计模式

多例模式,是常用的软件设计模式,主要作用限制某些类,只能创建固定数量的几个对象.
多例设计模式也分为通用多例和特定多例.

2.1通用多例设计模式

示例如下:

public class CommonClass {
```//构造方法私有化
    private CommonClass() {
    }

    //定义一个私有化,唯一化的静态成员变量作为集合的最大容量
    private static final int NUM = 5;

    //定义一个私有化 静态成员变量的集合作为存储本类对象的容器
    private static List<CommonClass> list = new ArrayList<>();


    //在静态代码块中给集合添加本类对象
    static {
        for (int i = 0; i < NUM; i++) {
            CommonClass commonClass = new CommonClass();
            list.add(commonClass);
        }

    }
    //提供一个公共的静态方法,随机提供本类的对象
   public static CommonClass getInstance(){
       Random random = new Random();
       int i=random.nextInt(NUM);
       return list.get(i);
   }

}

2.2 特定多例设计模式

获取特定对象的多例模式:
1.创建一个类, 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
2.内部成员位置定义“几个本类对象” ,使用 public static final修饰

 private SpecificClass() {
    }

    // 定义固定数量的本类对象,使用public static final修饰
    public static final SpecificClass sc1 = new SpecificClass();
    public static final SpecificClass sc2 = new SpecificClass();
    public static final SpecificClass sc3 = new SpecificClass();

}

3 工厂设计模式

工厂设计模式是Java中最常用的设计模式之一,属于创建型模式.
主要作用其实就是帮助我们快速创建某些需要很多参数的类的实例对象.
需要注意一点的是,复杂对象适合使用工厂模式,但是如果创建简单对象就没必要使用工厂模式.
这里举了一个游戏中创建弓箭手和近战兵对象的例子
示例如下:
1.定义一个Role接口

public  interface Role {
     void attack();
}

2.需要创建对象的复杂类去实现Role接口

近战兵类


public class Archer implements Role {

    private Integer defence;
    private Integer atk;
    private Integer bloodVolume;
    private Integer mana;
    private String color;
    private Integer speed;
    
    public Archer(Integer defence, Integer atk, Integer bloodVolume, Integer mana, String color, Integer speed) {
        this.defence = defence;
        this.atk = atk;
        this.bloodVolume = bloodVolume;
       this.mana = mana;
        this.color = color;
        this.speed = speed;
    }

    @Override
    public void attack() {
        System.out.println("弓箭手后排   射箭");
    }
}

弓箭手类

public class MeleeCreeps implements Role {


    //如果一个类中参数较多
    private Integer defence;
    private Integer atk;
    private Integer bloodVolume;
    private Integer mana;
    private String color;
    private Integer speed;

    public MeleeCreeps(Integer defence, Integer atk, Integer bloodVolume, Integer mana, String color, Integer speed) {
        this.defence = defence;
        this.atk = atk;
        this.bloodVolume = bloodVolume;
        this.mana = mana;
        this.color = color;
        this.speed = speed;
    }

    @Override
    public void attack() {
        System.out.println("战士前排攻击");
    }
}

大本营类

public class BaseCamp {
    /**
     * @param flag : 标识
     *             close : 代表需要近战兵
     *             far : 代表需要远程兵
     *             如果传入的标识不正确,代表大本营生成不了所需对象,则返回null
     *             }
     **/


    public Role Call(String flag) {
        if ("close".equals(flag)) {
           return new MeleeCreeps(100,70,600,100,"蓝色",60);
        }else if("far".equals(flag)){
            return new Archer(80,90,550,150,"红色",60);
        }else{
            return null;
        }
    }
}

Army类测试一下效果

public class Army {
    public static void main(String[] args) {
        BaseCamp baseCamp = new BaseCamp();
        Role far = baseCamp.Call("far");
        Role far1 = baseCamp.Call("far");
        Role far2 = baseCamp.Call("far");
        Role close = baseCamp.Call("close");
        Role close1 = baseCamp.Call("close");
        Role close2 = baseCamp.Call("close");

        far.attack();
        far1.attack();
        far2.attack();
        close.attack();
        close1.attack();
        close2.attack();
    }
}

以上第一篇博客,很多地方不严谨,欢迎指正.本博客主要是为了日后工作中遇到相关问题便于回顾.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值