单例模式(Singleton Pattern)
单例模式能保证类在程序中只存在唯一一个实例
单例模式具体的实现方法主要有两种:饿汉模式和懒汉模式。
饿汉模式
饿汉模式就是说在类加载的同时,创建实例
/**
* 在加载类的同时也会创建实例,getHungrySingleton()这个静态方法可以获取到这个实例.
* 而该类将其构造方法的属性设为私有,说明在外界不能创建该实例,确保了该实例只有一份.
*/
public class HungrySingleton {
private static HungrySingleton hungrySingleton = new HungrySingleton();
// 私有化构造方法
private HungrySingleton(){}
public static HungrySingleton getHungrySingleton(){
return hungrySingleton;
}
}
class HungrySingletonTest{
public static void main(String[] args) {
// 获取单例的对象,只能通过HungrySingleton.getHungrySingleton()来获取HungrySingleton对象
HungrySingleton hungrySingleton1 = HungrySingleton.getHungrySingleton();
HungrySingleton hungrySingleton2 = HungrySingleton.getHungrySingleton();
System.out.println(hungrySingleton1.equals(hungrySingleton2));
}
}
// 结果是true
懒汉模式
懒汉模式就是说类加载的时候不创建实例,第一次使用的时候才创建实例
public class LazySingleton {
private static LazySingleton lazySingleton = null;
private LazySingleton(){}
// 只有在调用getLazySingleton方法时才会创建lazySingleton
public static LazySingleton getLazySingleton(){
if (lazySingleton == null) {
return lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
class LazySingletonTest{
public static void main(String[] args) {
LazySingleton lazySingleton1 = LazySingleton.getLazySingleton();
LazySingleton lazySingleton2 = LazySingleton.getLazySingleton();
System.out.println(lazySingleton1.equals(lazySingleton2));
}
}
// 结果是true
工厂模式(Factory Pattern)
工厂模式将目的将创建对象的具体过程屏蔽隔离起来,要什么就给什么不需要知道怎么给的
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
简单工厂模式(Simple Factory)
定义一个创建对象的接口,将对象的创建和本身的业务逻辑分离
通俗的来说有了工厂,用户不再需要去创建宝马车,由工厂进行创建,想要什么车,直接通过工厂创建就可以了。比如想要320i系列车,工厂就创建这个系列的车
产品:
public abstract class BMW {
public BMW() {
}
}
class BMW320 extends BMW{
public BMW320(){
System.out.println("制造BMW320");
}
}
class BMW330 extends BMW{
public BMW330(){
System.out.println("制造BMW330");
}
}
工厂:
// 工厂进行造车
public class Factory {
public BMW creatBMW(int type){
switch (type){
case 320:
return new BMW320();
case 330:
return new BMW330();
default:
return null;
}
}
}
用户:
// 用户去工厂买车
public class Consumer {
public static void main(String[] args) {
Factory factory = new Factory();
BMW bmw320 = factory.creatBMW(320);
BMW bmw330 = factory.creatBMW(330);
}
}
工厂方法模式(Factory Method)
将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,就是说此时用户越来越多,所需要的车的系列也更多,工厂就具体化,每个工厂生产一种系列的车
产品:
public abstract class BMW {
public BMW() {
}
}
class BMW320 extends BMW{
public BMW320(){
System.out.println("制造BMW320");
}
}
class BMW330 extends BMW{
public BMW330(){
System.out.println("制造BMW330");
}
}
工厂:
// 不同的工厂造不同系列的车
interface Factory{
BMW create();
}
class Factory320 implements Factory{
@Override
public BMW320 create() {
return new BMW320();
}
}
class Factory330 implements Factory{
@Override
public BMW330 create() {
return new BMW330();
}
}
用户:
public class Consumer {
public static void main(String[] args) {
Factory320 factory320 = new Factory320();
BMW320 bmw320 = factory320.create();
Factory330 factory330 = new Factory330();
BMW330 bmw330 = factory330.create();
}
}
抽象工厂模式(Abstract Factory)
创建相关对象的家族。当一个产品族中需要被设计在一起工作时,通过抽象工厂模式,能够保证客户端始终只使用同一个产品族中的对象,也就是说需要一个工厂能够提供多个产品对象,而不是单一的对象
产品:
// 发动机
public interface Engine {
}
class Engine01 implements Engine{
public Engine01(){
System.out.println("制造Engine01");
}
}
class Engine02 implements Engine{
public Engine02(){
System.out.println("制造Engine02");
}
}
// 空调
public interface AirCondition {
}
class AirCondition01 implements AirCondition{
public AirCondition01(){
System.out.println("制造AirCondition01");
}
}
class AirCondition02 implements AirCondition{
public AirCondition02(){
System.out.println("制造AirCondition02");
}
}
工厂:
// 不同的工厂造不同的多个东西
public interface Factory {
public Engine createEngine();
public AirCondition createAirCondition();
}
class Factory320 implements Factory{
@Override
public Engine createEngine() {
return new Engine01();
}
@Override
public AirCondition createAirCondition() {
return new AirCondition01();
}
}
class Factory330 implements Factory{
@Override
public Engine createEngine() {
return new Engine02();
}
@Override
public AirCondition createAirCondition() {
return new AirCondition02();
}
}
用户:
public class Consumer {
public static void main(String[] args) {
Factory320 factory320 = new Factory320();
factory320.createEngine();
factory320.createAirCondition();
Factory330 factory330 = new Factory330();
factory330.createEngine();
factory330.createAirCondition();
}
}
代理模式
给一个对象提供一种代理对象以控制对该对象的访问。
简单点理解:
目标对象:原对象,我们需要通过代理对象控制它的访问,扩展其功能。
代理对象:代理模式产生的对象,是原对象的替身,在原有基础上进行修改。
在不改变原对象代码的基础上对原对象的功能进行扩展
再简单点理解:
比如点外卖事件
你想吃麻辣烫,自己又不想去店里吃,所以你点外卖,此时的外卖小哥,可以看作为代理对象。而你又想在吃完麻辣烫后喝一杯珍珠奶茶,所以你又联系外卖小哥帮你去店里买一杯。这个过程可以理解为加的扩展功能。
静态代理:需要我们手写代理类
// 租房(提供的业务)
public interface Rent {
void rent();
}
// 房东
class Master implements Rent{
@Override
public void rent() {
System.out.println("master rent");
}
}
// 中介(要提供更多的业务,在中介添加)
class Proxy implements Rent{
private Master master;
// 手动编写代理
public Proxy(){}
public Proxy(Master master){
this.master = master;
}
@Override
public void rent() {
see();
master.rent();
buy();
}
public void see(){
System.out.println("see");
}
public void buy(){
System.out.println("buy");
}
}
// 测试
class ProxyTest{
public static void main(String[] args) {
Master master = new Master();
Proxy proxy = new Proxy(master);
proxy.rent();
}
}
// 结果是
// see
// master rent
// buy
动态代理:是在内存中生成代理对象的一种技术,
无需手写代理类
,也不会存在代码编译的过程。运用在内存中生产代理类的技术在JVM的运行区造一个代理对象,只需对需要修改的部分进行编辑。
public interface MathMethod {
void add();
void save();
void update();
void delete();
}
class MathMethodImpl implements MathMethod{
@Override
public void add() {
System.out.println("add");
}
@Override
public void save() {
System.out.println("save");
}
@Override
public void update() {
System.out.println("update");
}
@Override
public void delete() {
System.out.println("delete");
}
}
// 自动生成动态代理类模板
class ProxyInvocationHandler implements InvocationHandler {
//被代理接口
private Object target;
public void setTarget(Object target) {
this.target = target;
}
//得到代理类
public Object getProxy() {
return Proxy.newProxyInstance(getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
public void log(String s) {
System.out.println("[debug]:" + s);
}
//得到代理类
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(target, args);
return result;
}
}
// 测试
class ProxyTest{
public static void main(String[] args) {
ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
MathMethodImpl mathMethod = new MathMethodImpl();
// 设置代理的对象
proxyInvocationHandler.setTarget(mathMethod);
// 生成代理类
MathMethod proxy = (MathMethod)proxyInvocationHandler.getProxy();
proxy.add();
proxy.save();
proxy.update();
proxy.delete();
}
}
策略模式
将对象与行为分开,定义一系列的算法,行为之间可以替换,由用户进行选择(或者说由用户进行变化)
// 对象和行为分开来
public interface Strategy {
public double calcPrice(double price,int num);
}
// 一级原价
class One implements Strategy{
@Override
public double calcPrice(double price, int num) {
return price * num;
}
}
// 二级打九折
class Two implements Strategy{
@Override
public double calcPrice(double price, int num) {
return price * num * 0.9;
}
}
// 三级打八折
class Three implements Strategy{
@Override
public double calcPrice(double price, int num) {
return price * num * 0.8;
}
}
class StrategyTest{
private Strategy strategy;
public StrategyTest(Strategy strategy){
this.strategy = strategy;
}
public double getPrice(double price, int num){
return strategy.calcPrice(price,num);
}
}
class demo{
public static void main(String[] args) {
Strategy strategyOne = new One();
Strategy strategyTwo = new Two();
Strategy strategyThree = new Three();
StrategyTest strategyTestOne = new StrategyTest(strategyOne);
StrategyTest strategyTestTwo = new StrategyTest(strategyTwo);
StrategyTest strategyTestThree = new StrategyTest(strategyThree);
// 买一本100元的书
System.out.println("一级"+strategyTestOne.getPrice(100,1));
System.out.println("二级"+strategyTestTwo.getPrice(100,1));
System.out.println("三级"+strategyTestThree.getPrice(100,1));
}
}
/**
* 结果是
* 一级100.0
* 二级90.0
* 三级80.0
*/
观察者模式
观察者和被观察者。当被观察者状态发生改变时,它会通知所有的观察者对象,使他们能够及时做出响应,所以也被称作“发布-订阅模式”
/**
* 场景:报纸的订阅
*/
interface NewsPaper{
// 添加
void add(Observer observer);
// 删除
void delete(Observer observer);
// 更新
void update(String message);
}
class NewsPaperImpl implements NewsPaper{
List<Observer> list = new ArrayList<>();
@Override
public void add(Observer observer) {
list.add(observer);
}
@Override
public void delete(Observer observer) {
list.remove(observer);
}
@Override
public void update(String message) {
for (Observer observer : list) {
observer.update(message);
}
}
}
public interface Observer {
void update(String message);
}
class ObserverImpl implements Observer{
private String name;
@Override
public String toString() {
return "ObserverImpl{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name+"接到消息:"+message);
}
}
class demo{
public static void main(String[] args) {
NewsPaper newsPaper = new NewsPaperImpl();
ObserverImpl bu = new ObserverImpl();
bu.setName("不");
ObserverImpl qi = new ObserverImpl();
qi.setName("期");
// 添加订阅者
newsPaper.add(bu);
newsPaper.add(qi);
newsPaper.update("今天的报纸到了");
newsPaper.delete(qi);
newsPaper.update("订阅了明天的报纸");
}
}
/**
* 不接到消息:今天的报纸到了
* 期接到消息:今天的报纸到了
* 不接到消息:订阅了明天的报纸
*/