php学什么可以做网站,公司免费网站域名,自己做的网站如何发布,建设一个企业网站一、Java 中有几种设计模式#xff1f;
Java 中一般认为有 23 种设计模式
分为三大类#xff1a;
1. 创建型模式 5 种 ① 工厂方法模式 ② 抽象工厂模式 ③ 单例模式 ④ 建造者模式 ⑤ 原型模式 2. 结构型模式 7 种 ① 适配器模式 ② 装饰器模式 ③ 代理模式 ④ 外观模式 …一、Java 中有几种设计模式
Java 中一般认为有 23 种设计模式
分为三大类
1. 创建型模式 5 种 ① 工厂方法模式 ② 抽象工厂模式 ③ 单例模式 ④ 建造者模式 ⑤ 原型模式 2. 结构型模式 7 种 ① 适配器模式 ② 装饰器模式 ③ 代理模式 ④ 外观模式 ⑤ 桥接模式 ⑥ 组合模式 ⑦ 享元模式 3. 行为型模式 11 种 ① 策略模式 ② 模板方法模式 ③ 观察者模式 ④ 迭代子模式 ⑤ 责任链模式 ⑥ 命令模式 ⑦ 备忘录模式 ⑧ 状态模式 ⑨ 访问者模式 ⑩ 中介者模式 ⑪ 解释器模式 二、什么是单例设计模式
1. 单例模式定义 单例模式确保某个类只有一个实例而 且自行实例化并向整个系统提供这个实 例 在计算机系统中线程池、缓存、日志 对象、对话框、打印机、显卡的驱动程 序对象常被设计成单例选择单例模式 就是为了避免不一致状态 2. 单例模式的特点 ① 单例类只能有一个实例 ② 单例类必须自己创建自己的唯一实例 ③ 单例类必须给所有其他对象提供这一 实例 ④ 单例模式保证了全局对象的唯一性 比如系统启动读取配置文件就需要单 例保证配置的一致性 3. 单例的四大原则 ① 构造器私有化 ② 以静态方法或者枚举返回实例 ③ 确保实例只有一个尤其是多线程 环境 ④ 确保反序列化时不会重新构建对象 4. 实现单例模式的方式
(1) 饿汉式 (立即加载) 饿汉式单例在类加载初始化时就创建好 一个静态的对象供外部使用除非系统 重启这个对象不会改变所以本身就 是线程安全的 Singleton 通过将构造方法限定为 private 避免了类在外部被实例化在同一个虚拟 机范围内Singleton 的唯一实例只能通 过 getInstance() 方法访问 (事实上通过 Java 反射机制是能够实例化构造方法为 private 的类的会使 Java 单例实现失效 /*** 饿汉式立即加载*/
public class Singleton1 {/*** 私有构造*/private Singleton1() {System.out.println(构造函数Singleton1);}/*** 初始值为实例对象*/private static Singleton1 single new Singleton1();/*** 静态工厂方法* return 单例对象*/public static Singleton1 getInstance() {System.out.println(getInstance);return single;}public static void main(String[] args){System.out.println(初始化);Singleton1 instance Singleton1.getInstance();}
}(2) 懒汉式 (延迟加载) 该示例虽然用延迟加载方式实现了懒汉 式单例但在多线程环境下会产生多个 Singleton 对象 /*** 懒汉式延迟加载*/
public class Singleton2 {/*** 私有构造*/private Singleton2() {System.out.println(构造函数Singleton2);}/*** 初始值为null*/private static Singleton2 single null;/*** 静态工厂方法* return 单例对象*/public static Singleton2 getInstance() {if(single null){System.out.println(getInstance);single new Singleton2();}return single;}public static void main(String[] args){System.out.println(初始化);Singleton2 instance Singleton2.getInstance();}
}
(3) 同步锁 (解决线程安全问题) 在方法上加 synchronized 同步锁或是 用同步代码块对类加同步锁此种方 式虽然解决了多个实例对象问题但 是该方式运行效率却很低下下一个 线程想要获取对象就必须等待上一 个线程释放锁之后才可以继续运行 /**** 同步锁解决线程安全问题*/
public class Singleton3 {/*** 私有构造*/private Singleton3() {}/*** 初始值为null*/private static Singleton3 single null;public static Singleton3 getInstance() {// 等同于 synchronized public static Singleton3 getInstance()synchronized(Singleton3.class){// 注意里面的判断是一定要加的否则出现线程安全问题if(single null){single new Singleton3();}}return single;}
}
(4) 双重检查锁 (提高同步锁的效率) 使用双重检查锁进一步做了优化可 以避免整个方法被锁只对需要锁的 代码部分加锁可以提高执行效率 /*** 双重检查锁提高同步锁的效率*/
public class Singleton4 {/*** 私有构造*/private Singleton4() {}/*** 初始值为null*/private static Singleton4 single null;/*** 双重检查锁* return 单例对象*/public static Singleton4 getInstance() {if (single null) {synchronized (Singleton4.class) {if (single null) {single new Singleton4();}}}return single;}
}
(5) 静态内部类 引入了一个内部静态类 (static class)静 态内部类只有在调用时才会加载它保证 了 Singleton 实例的延迟初始化又保证 了实例的唯一性 它把 singleton 的实例化操作放到一个静 态内部类中在第一次调用 getInstance() 方法时JVM 才会去加载 InnerObject 类 同时初始化 singleton 实例所以能让 getInstance() 方法线程安全 特点即能延迟加载也能保证线程安全 静态内部类虽然保证了单例在多线程并发 下的线程安全性但是在遇到序列化对象 时默认的方式运行得到的结果就是多例 的 /**** 静态内部类延迟加载线程安全*/
public class Singleton5 {/*** 私有构造*/private Singleton5() {}/*** 静态内部类*/private static class InnerObject{private static Singleton5 single new Singleton5();}public static Singleton5 getInstance() {return InnerObject.single;}
}
(6) 内部枚举类实现 (防止反射攻击) 事实上通过 Java 反射机制是能够实例 化构造方法为 private 的类的这也就是 我们现在需要引入的枚举单例模式 public class SingletonFactory {/*** 内部枚举类*/private enum EnumSingleton{Singleton;private Singleton6 singleton;//枚举类的构造方法在类加载是被实例化private EnumSingleton(){singleton new Singleton6();}public Singleton6 getInstance(){return singleton;}}public static Singleton6 getInstance() {return EnumSingleton.Singleton.getInstance();}
}class Singleton6 {public Singleton6(){}
}
三、什么是工厂设计模式 工厂设计模式就是用来生产对象的在 java 中万物皆对象这些对象都需要 创建如果创建的时候直接 new 该对象 就会对该对象耦合严重假如我们要更 换对象所有 new 对象的地方都需要修 改一遍这显然违背了软件设计的开闭 原则如果我们使用工厂来生产对象 我们就只和工厂打交道就可以了彻底 和对象解耦如果要更换对象直接在 工厂里更换该对象即可达到了与对象 解耦的目的所以说工厂模式最大的 优点就是解耦 1. 简单工厂 (Simple Factory)
定义 一个工厂方法依据传入的参数生成对 应的产品对象 角色 ① 抽象产品 ② 具体产品 ③ 具体工厂 ④ 产品使用者 使用说明 先将产品类抽象出来比如苹果和梨都属 于水果抽象出来一个水果类 Fruit苹果和 梨就是具体的产品类然后创建一个水果工 厂分别用来创建苹果和梨 代码如下
// 水果接口
public interface Fruit {void whatIm();
}// 苹果类
public class Apple implements Fruit {Overridepublic void whatIm() {System.out.println(苹果);}
}// 梨类
public class Pear implements Fruit {Overridepublic void whatIm() {System.out.println(梨);}
}//水果工厂public class FruitFactory {public Fruit createFruit(String type) {if (type.equals(apple)) {//生产苹果return new Apple();} else if (type.equals(pear)) {//生产梨return new Pear();}return null;}
}// 使用工厂生产产品
public class FruitApp {public static void main(String[] args) {FruitFactory mFactory new FruitFactory();Apple apple (Apple) mFactory.createFruit(apple);//获得苹果Pear pear (Pear) mFactory.createFruit(pear);//获得梨apple.whatIm();pear.whatIm();}
} 以上的这种方式每当添加一种水果就必 然要修改工厂类违反了开闭原则 所以简单工厂只适合于产品对象较少且产 品固定的需求对于产品变化无常的需求来 说显然不合适 2. 工厂方法 (Factory Method)
定义 将工厂提取成一个接口或抽象类具体生 产什么产品由子类决定 角色 ① 抽象产品 ② 具体产品 ③ 抽象工厂 ④ 具体工厂 使用说明 和上例中一样产品类抽象出来这次我们 把工厂类也抽象出来生产什么样的产品由 子类来决定 代码如下
// 水果接口、苹果类和梨类代码和上例一样// 抽象工厂接口
public interface FruitFactory {Fruit createFruit();//生产水果
}// 苹果工厂
public class AppleFactory implements FruitFactory {Overridepublic Apple createFruit() {return new Apple();}
}// 梨工厂
public class PearFactory implements FruitFactory {Overridepublic Pear createFruit() {return new Pear();}
}// 使用工厂生产产品
public class FruitApp {public static void main(String[] args){AppleFactory appleFactory new AppleFactory();PearFactory pearFactory new PearFactory();Apple apple appleFactory.createFruit();//获得苹果Pear pear pearFactory.createFruit();//获得梨apple.whatIm();pear.whatIm();}
} 以上这种方式虽然解耦了也遵循了开闭 原则但是如果我需要的产品很多的话需 要创建非常多的工厂所以这种方式的缺点 也很明显 3. 抽象工厂 (Abstract Factory)
定义 为创建一组相关或者是相互依赖的对象提供 的一个接口而不需要指定它们的具体类 角色 ① 抽象产品 ② 具体产品 ③ 抽象工厂 ④ 具体工厂 使用说明 抽象工厂和工厂方法的模式基本一样区别 在于工厂方法是生产一个具体的产品而 抽象工厂可以用来生产一组相同有相对关 系的产品 用抽象工厂来实现
// cpu接口和实现类
public interface Cpu {void run();class Cpu650 implements Cpu {Overridepublic void run() {System.out.println(650 也厉害);}}class Cpu825 implements Cpu {Overridepublic void run() {System.out.println(825 更强劲);}}
}// 屏幕接口和实现类
public interface Screen {void size();class Screen5 implements Screen {Overridepublic void size() {System.out.println( 5寸);}}class Screen6 implements Screen {Overridepublic void size() {System.out.println(6寸);}}
}// 抽象工厂接口
public interface PhoneFactory {Cpu getCpu();//使用的cpuScreen getScreen();//使用的屏幕
}// 小米手机工厂
public class XiaoMiFactory implements PhoneFactory {Overridepublic Cpu.Cpu825 getCpu() {return new Cpu.Cpu825();//高性能处理器}Overridepublic Screen.Screen6 getScreen() {return new Screen.Screen6();//6寸大屏}
}//红米手机工厂
public class HongMiFactory implements PhoneFactory {Overridepublic Cpu.Cpu650 getCpu() {return new Cpu.Cpu650();//高效处理器}Overridepublic Screen.Screen5 getScreen() {return new Screen.Screen5();//小屏手机}
}// 使用工厂生产产品
public class PhoneApp {public static void main(String[] args){HongMiFactory hongMiFactory new HongMiFactory();XiaoMiFactory xiaoMiFactory new XiaoMiFactory();Cpu.Cpu650 cpu650 hongMiFactory.getCpu();Cpu.Cpu825 cpu825 xiaoMiFactory.getCpu();cpu650.run();cpu825.run();Screen.Screen5 screen5 hongMiFactory.getScreen();Screen.Screen6 screen6 xiaoMiFactory.getScreen();screen5.size();screen6.size();}
} 以上例子可以看出抽象工厂可以解决一 系列的产品生产的需求对于大批量多 系列的产品用抽象工厂可以更好地管理 和扩展 4. 三种工厂方式总结 ① 对于简单工厂和工厂方法来说两者的 使用方式实际上是一样的如果对于产 品的分类和名称是确定的数量是相对 固定的推荐使用简单工厂模式 ② 抽象工厂用来解决相对复杂的问题适用于 一系列、大批量的对象生产