常用的设计模式(单例,工厂,代理,策略,观察者)

单例模式(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("订阅了明天的报纸");
    }
}
/**
 * 不接到消息:今天的报纸到了
 * 期接到消息:今天的报纸到了
 * 不接到消息:订阅了明天的报纸
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值