1、接口隔离原则
(1)原生
package Thread;
public class test2 {
}
interface IUser{
void register(User user);
void deleteUser();
//...
void sms(String mobilePhone);
}
class DefaultUser implements IUser{
@Override
public void register(User user) {
//..
}
@Override
public void deleteUser() {
//..
}
@Override
public void sms(String mobilePhone) {
//.. 用户的接口中含有发送短信的方法 不合理
}
}
class ActivityService {
IUser iUser;
public void test(){
// 此处的iUer可以使用IUser中的所有方法存在安全隐患
iUser.sms("123XXXXXXX");
}
}
class User{
}
(2)改造后
把无关的接口隔离出去
package Thread;
public class test2 {
}
//用户接口
interface IUser{
void register(User user);
void deleteUser();
//...
}
class DefaultUser implements IUser{
@Override
public void register(User user) {
//..
}
@Override
public void deleteUser() {
//..
}
}
//短信接口 把短信功能从用户中剥离 接口隔离
interface MsgSender{
void sms(String mobilePhone);
}
class DefaultMsgSender implements MsgSender{
@Override
public void sms(String mobilePhone) {
//...
}
}
class ActivityService {
MsgSender msgSender;
public void test(){
// 此处的iUer可以使用IUser中的所有方法存在安全隐患
msgSender.sms("123XXXXXXXX");
}
}
class User{
}
2、依赖倒置原则
3、单例设计模式
(1)懒汉式单例
package Thread;
public class LazySingletonTest {
public static void main(String[] args) {
}
}
//懒汉式单例 单线程环境下线程安全 多线程线程下,懒汉式单例在实例化的过程中是线程不安全的
class LazySingleton{
private static LazySingleton instance;
//私有构造函数 避免在其他类中直接new对象
private LazySingleton() {
}
public static LazySingleton getInstance(){
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
懒汉模式改造后:
package Thread;
public class LazySingletonTest {
public static void main(String[] args) {
}
}
//双重检测机制 多线程环境下安全,但由于锁,影响效率
class LazySingleton{
private volatile static LazySingleton instance;
//私有构造函数 避免在其他类中直接new对象
private LazySingleton() {
}
public static LazySingleton getInstance(){
if (null == instance) {
synchronized (LazySingleton.class) {
//双重检测
if(null == instance){
instance = new LazySingleton();
// 1 开辟空间
// 2 初始化空间
// 3 赋值 demo
}
}
}
return instance;
}
}
(2)饿汉式单例
饿汉式单例:单例在实例化的过程是线程安全的
package Thread;
public class HungrySingletonTest {
public static void main(String[] args) {
HungrySingleton instance = HungrySingleton.getInstance(); //有实例化
}
}
//饿汉式单例 单例在实例化的过程是线程安全的
class HungrySingleton{
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return instance;
}
}
扩展问题
何时会触发单例的初始化:
实例初始化测试代码:
package Thread;
public class HungrySingletonTest {
public static void main(String[] args) {
//Class<HungrySingleton> hungrySingletonClass = HungrySingleton.class; //没有实例化
//System.out.println(HungrySingleton.name); //有实例化
HungrySingleton instance = HungrySingleton.getInstance(); //有实例化
}
}
//饿汉式单例 线程安全
class HungrySingleton{
public static String name = "zhangjilin";
//先执行静态代码块
static {
System.out.println("HungrySingleton init");
}
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return instance;
}
}
(3)静态内部类单例
package Thread;
public class InnerClassSingletonTest{
public static void main(String[] args) {
InnerClassSingleton instance = InnerClassSingleton.getInstance();
}
}
//静态内部类 线程安全
class InnerClassSingleton{
//静态内部类
private static class SingletonHolder{
private static InnerClassSingleton instance = new InnerClassSingleton();
}
private InnerClassSingleton() {
}
public static InnerClassSingleton getInstance() {
return SingletonHolder.instance;
}
}
测试:
instance在何时被初始化 ???
package Thread;
public class InnerClassSingletonTest{
public static void main(String[] args) {
System.out.println(InnerClassSingleton.name);
System.out.println("===========");
//在调用getInstance()方法时:会触发初始化
System.out.println(InnerClassSingleton.getInstance());
}
}
//静态内部类 线程安全
class InnerClassSingleton{
public static String name = "zhangjilin";
static {
System.out.println("InnerClassSingleton init");
}
//静态内部类
private static class SingletonHolder{
static {
System.out.println("SingletonHolder init");
}
private static InnerClassSingleton instance = new InnerClassSingleton();
}
private InnerClassSingleton() {
}
public static InnerClassSingleton getInstance() {
return SingletonHolder.instance;
}
@Override
public String toString() {
return "InnerClassSingleton{}";
}
}
(4) 枚举单例