Java设计模式【更新中...】

n8n实战:动态报表生成与企业微信自动化推送 本文详细介绍了如何利用n8n实现动态报表生成与企业微信自动化推送的全流程。通过配置n8n Form触发器、智能报表生成核心逻辑以及企业微信Webhook推送,帮助企业大幅提升数据收集与报表推送效率,实现从数据录入到报表推送的全自动化处理。 阅读详情

目录

设计模式介绍

1、设计模式的六大原则

2、设计模式分类

一、单例模式【创建型模式】

1、饿汉方式(立即加载)

2、懒汉方式(延迟加载)

二、工厂方法模式【创建型模式】

1、简单工厂(严格来说简单工厂不算设计模式,因为不符合开闭原则)

2、工厂方法模式

三、抽象工厂模式【创建型模式】

四、原型模式【创建型模式】

五、适配器模式【结构型模式】

1、对象适配器

代理模式【结构型模式】

装饰器模式【结构型模式】

观察者模式【行为型模式】

责任链模式【行为型模式】 

代码实现

责任链模式的优缺点

策略模式【行为型模式】 

策略模式代码实例

建造者模式【创建型模式】


设计模式介绍

核心概念:设计模式是什么?设计模式是思想,是一种设计思想。只要核心思想不变,同一种思想可以有多种代码实现方案,并非是死板的某一种形式,它没有固定的实现代码

1、设计模式的六大原则

总原则:开闭原则(Open Close Principle)

开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,而是要扩展原有代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类等,后面的具体设计中我们会提到这点。

(1)单一职责原则

不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,如若不然,就应该把类拆分。

(2)里氏替换原则(Liskov Substitution Principle)

里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。—— From Baidu 百科

历史替换原则中,子类对父类的方法尽量不要重写和重载。因为父类代表了定义好的结构,通过这个规范的接口与外界交互,子类不应该随便破坏它。

(3)依赖倒转原则(Dependence Inversion Principle)

这个是开闭原则的基础,具体内容:面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。

(4)接口隔离原则(Interface Segregation Principle)

这个原则的意思是:每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。

(5)迪米特法则(最少知道原则)(Demeter Principle)

就是说:一个类对自己依赖的类知道的越少越好。也就是说无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。

最少知道原则的另一个表达方式是:只与直接的朋友通信。类之间只要有耦合关系,就叫朋友关系。耦合分为依赖、关联、聚合、组合等。我们称出现为成员变量、方法参数、方法返回值中的类为直接朋友。局部变量、临时变量则不是直接的朋友。我们要求陌生的类不要作为局部变量出现在类中。

(6)合成复用原则(Composite Reuse Principle)

原则是尽量首先使用合成/聚合的方式,而不是使用继承。

2、设计模式分类

1、创建型模式(在创建对象的过程中尽量隐藏创建细节,不直接使用new)

  • 单例模式(Singleton Pattern)
  • 工厂模式(Factory Pattern)
  • 抽象工厂模式(Abstract Factory Pattern)
  • 建造者模式(Builder Pattern)
  • 原型模式(Prototype Pattern)

2、结构型模式(主要关注类和对象的继承、组合)

  • 适配器模式(Adapter Pattern)
  • 桥接模式(Bridge Pattern)
  • 过滤器模式(Filter、Criteria Pattern)
  • 组合模式(Composite Pattern)
  • 装饰器模式(Decorator Pattern)
  • 外观模式(Facade Pattern)
  • 享元模式(Flyweight Pattern)
  • 代理模式(Proxy Pattern)

3、行为型模式(关注对象之间的通信)

  • 责任链模式(Chain of Responsibility Pattern)
  • 命令模式(Command Pattern)
  • 解释器模式(Interpreter Pattern)
  • 迭代器模式(Iterator Pattern)
  • 中介者模式(Mediator Pattern)
  • 备忘录模式(Memento Pattern)
  • 观察者模式(Observer Pattern)
  • 状态模式(State Pattern)
  • 空对象模式(Null Object Pattern)
  • 策略模式(Strategy Pattern)
  • 模板模式(Template Pattern)
  • 访问者模式(Visitor Pattern)

一、单例模式【创建型模式】

这一模式的目的是使得类的一个对象成为系统中的唯一实例

优点:

  1. 在内存中只有一个实例,减少内存开销
  2. 避免资源多重占用
  3. 设置全局访问点,严格控制访问

JAVA中单例模式有两种构建方式

  • 饿汉方式(立即加载):指全局的单例实例在类装载时构建
  • 懒汉方式(延迟加载):指全局的单例实例在第一次被使用时构建

注意要点:私有构造,这样才能避免该类被外部程序再次创建(被new),从而达到单例

实现方式

1、饿汉方式(立即加载)

// 饿汉式单例
public class Singleton1 {
    // 私有构造
    private Singleton1() {}
    private final static Singleton1 single = new Singleton1();
    // 静态工厂方法
    public static Singleton1 getInstance() {
        return single;
    }
}

饿汉式单例在类加载初始化时就创建好一个静态的对象供外部使用,除非系统重启,这个对象不会改变,所以本身就是线程安全的。

Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。

2、懒汉方式(延迟加载)

// 懒汉式单例
public class Singleton2 {
    // 私有构造
    private Singleton2() {}
    private static Singleton2 single = null;
    public static Singleton2 getInstance() {
        if(single == null){
            single = new Singleton2();
        }
        return single;
    }
}

该示例虽然用延迟加载方式实现了懒汉式单例,但在多线程环境下会产生多个single对象,如何改造请看以下方式:

使用synchronized同步锁

public class Singleton3 {
    // 私有构造
    private Singleton3() {}
    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;
    }
}

在方法上加synchronized同步锁或是用同步代码块对类加同步锁,此种方式虽然解决了多个实例对象问题,但是该方式运行效率却很低下,下一个线程想要获取对象,就必须等待上一个线程释放锁之后,才可以继续运行。 

二、工厂方法模式【创建型模式】

优点:

  • 用户只需关心产品对应的工厂,无需关心创建细节
  • 加入新产品符合开闭原则,提高了扩展性

缺点:

  • 类的个数容易过多,增加复杂度
  • 增加了系统的抽象性和理解难度

应用场景

  • 创建需要大量重复的代码
  • 应该用层不需要依赖于产品类如何被创建、实现等细节

工厂模式的分类及特点

  1. 简单工厂:需要修改原有代码
  2. 工厂方法模式:改善简单工厂的缺点,不会修改原有代码,只需新增
  3. 抽象工厂模式:

1、简单工厂(严格来说简单工厂不算设计模式,因为不符合开闭原则)

只有一个工厂,每增加一个新需求,就需要修改这个工厂并在其中添加新的代码(判断)。重点是它需要修改原有代码。

所谓的简单工厂,不用管是什么产品,我们将所有产品的生产线一股脑的都放在一个工厂里,这样工厂便可以根据用户的要求来生产各种产品。

定义一些被生产的基本类

public abstract class Phone{
	public abstract void call();
}

class HuaWei extends Phone{
	public void call() {
		System.out.println("hua wei");
	}
}

class XiaoMi extends Phone{
	public void call() {
		System.out.println("xiao mi");
	}
}

 根据给工厂传入值的不同成产出不同的对象

//工厂类
public class Factory{
    public static Phone creator(String which){
        if ("huawei".equalsIgnoreCase(which))
            return new HuaWei();
        if ("xiaomi".equalsIgnoreCase(which))
            return new XiaoMi();
        retrun null;
    }
}

//测试类
public class DTest {
	public static void main(String[] args) {
        Phone phone=Factory.creator("huawei");
        if(null==phone){return;}
        phone.call();
	}
}

2、工厂方法模式

定义一个创建对象的接口,让实现这个接口的类决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行

  • 抽象工厂不负责生产,生产的工作放在具体的子类工厂里面
  • 一旦有新的需求就添加对应的子类工厂,而不用改变任何原有代码,这样的方式使得原来的产品生产线不受新产品的影响实现了解耦,符合了设计模式中的开闭原则(对扩展开放,对修改关闭)

1、定义一些被生产的基本类 

//产品接口
public interface Phone {
	public void call();
}

//具体产品
public class HuaWei implements Phone{
	public void call() {
		System.out.println("hua wei");
	}
}
public class XiaoMi implements Phone{
	public void call() {
		System.out.println("xiao mi");
	}
}

2、定义总工厂(不上产具体对象)和一些对应的子工厂 (生产对象)

//总工厂(工厂抽象类),不生产具体对象
public abstract class PhoneFactory {
	public abstract Phone getPhone();

}

//子工厂,负责生产对象
class HuaWeiFactory extends PhoneFactory{
	public Phone getPhone() {
		return new HuaWei();
	}
}
class XiaoMiFactory extends PhoneFactory{
	public Phone getPhone() {
		return new XiaoMi();
	}
}

//随时有新的需求,我们可以建新的子工厂
......

3、测试类

随时有新的需求,我们可以创建新的工厂继续继承总工厂为父类。不用改变其他原有代码,只是进行添加。

(这就是所说的开闭原则,可扩展,不修改)

public class DTest{
	public static void main(String[] args) {
        PhoneFactory phoneFactory=new HuaWeiFactory();
        Phone phone=phoneFactory.getPhone();
        if(null==phone){return;}
        phone.call();
	}
}

三、抽象工厂模式【创建型模式】

抽象工厂模式和工厂模式的区别:

1、这是一个场景应用复杂度的区别

2、这两种设计模式主要的区别在于产品,

工厂模式是用来创建同一个产品的不同类型

(e.g:早餐店里卖便宜或贵的包子)

但是抽象工厂模式是用来创建不同类的产品

(e.g:早餐店里有便宜的档口卖便宜的包子和便宜的粥;还有贵的档口卖贵的包子和贵的粥;还有其他档口的组合方式)

3、一个工厂可以产生多个产品,而每个产品又可以被多个工厂生产

4、一般来说,产品种类单一(一对多),适合用工厂模式;

如果有多个种类,各种类型时(多对多),通过抽象工厂模式来进行创建是很合适的。

为创建一组相关或者是相互依赖的对象提供一个接口,而不需要指定他们的具体实现类。 
例如: 
Q3和Q7有不同的轮胎、发动机、制动系统。虽然生产的零件不同,型号不同。但是根本上都有共同的约束,就是轮胎、发动机、制动系统。设计如下:

  1. 需要一个抽象工厂,里面有三个接口分别为生产轮胎、发动机、制动系统,抽象类
  2. 需要三个抽象产品分别为轮胎、发动机、制动系统,抽象接口
  3. 需要实现上面的三个抽象接口,定义出每个接口不通的对象,比如:普通轮胎和越野轮胎
  4. 需要两个具体类继承自上面的抽象类,实现具体的工厂,比如:生产Q3的工厂和生产Q7的工厂
  5. 在客户端new出对应的具体工厂并调用对应的生产方法

区别

工厂方法模式: 只有一个抽象产品类,具体工厂类只能创建一个具体产品类的实例 
抽象工厂模式: 有多个抽象产品类 ,具体工厂类能创建多个具体产品类的实例

 1、创建零件组

public interface IBrake {
	 /**
     *制动系统 
     */
    void brake();
}
public class NormalBrake implements IBrake {
	public void brake() {
		System.out.println("普通制动");
	}
}
public class SeniorBrake implements IBrake {
	public void brake() {
		System.out.println("高级制动");
	}
}
//---------------------------------------------------
public interface IEngine {
	  /**
     *发动机 
     */
    void engine();
}
public class NormalEngine implements IEngine {
	public void engine() {
		System.out.println("普通发动机");
	}
}
public class SeniorEngine implements IEngine {
	public void engine() {
		System.out.println("高级发动机");
	}
}
//---------------------------------------------------
public interface ITire {
	 /**
     * 轮胎 
     */
    void tire();
}
public class NormalTire implements ITire {
	public void tire() {
		System.out.println("普通轮胎");
	}
}
public class SeniorTire implements ITire {
	@Override
	public void tire() {
		System.out.println("高级轮胎");
	}
}

2、创建抽象工厂(重点在于此)

public abstract class CarFactory {
	 /**
     * 生产轮胎
     * @return 轮胎
     * */
    public abstract ITire createTire();
    /**
     * 生产发动机
     * @return 发动机
     * */
    public abstract IEngine createEngine();
    /**
     * 生产制动系统
     * @return 制动系统
     * */
    public abstract IBrake createBrake();
}

 3、创建你对应型号汽车的组装工厂(继承抽象工厂,实现对应的方法)

  • 用上面的零件组装出你这个工厂设定的汽车配置
  • 一个工厂只组装一个型号的汽车,如果要别的型号,再建一个工厂进行生产
public class Q3Factory extends CarFactory {
	@Override
	public ITire createTire() {
		// TODO Auto-generated method stub
		return new NormalTire();
	}
	@Override
	public IEngine createEngine() {
		// TODO Auto-generated method stub
		return new SeniorEngine();
	}
	@Override
	public IBrake createBrake() {
		// TODO Auto-generated method stub
		return new NormalBrake();
	}
}

4、测试

public class Test {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		CarFactory q3=new Q3Factory();
		q3.createBrake().brake();
		q3.createEngine().engine();
		q3.createTire().tire();
	}
}

 

疑问:为什么叫抽象工厂模式?仅仅是因为里面是抽象类还是说这是抽象的概念?那可以将抽象类换成接口吗?

个人理解:  抽象工厂模式大多是为了处理复杂度较高的多个产品实例,但是在这种情况下是否会出现与个别没有那么复杂的实例共存情况?比如汽车轮胎有很多种,但是发动机只有一种。那么我们能不能直接在抽象类中使用普通方法直接取到这个发动机对象呢?这样其他的产品还是用抽象方法获取,这样就减少了个别对象的复杂度。这种情况下接口就必须也单独实现每个方法,会增加代码量(这是我自己的猜想,未经证实,所以大家有正确答案请留言回复我,我将更新这一问题)

四、原型模式【创建型模式】

使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象

也就是说,创建一个类似于模板的原型,一直存储不动,一旦需要新的对象,我们就克隆这个原型,我们操作修改都是修改这个被克隆出来的对象,而不影响我们的原型模板。

举个栗子:我们可以思考一下动漫中的影分身。

原型模式分三个角色:抽象原型类,具体原型类,客户类

抽象原型类(prototype):它是声明克隆方法的接口,是所有具体原型类的公共父类,它可以是接口,抽象类甚至是一个具体的实现类。

具体原型类(concretePrototype):它实现了抽象原型类中声明的克隆方法,在克隆方法中返回一个自己的克隆对象。

客户类(Client):在客户类中,使用原型对象只需要通过工厂方式创建或者直接NEW(实例化一个)原型对象,然后通过原型对象的克隆方法就能获得多个相同的对象。由于客户端是针对抽象原型对象编程的所以还可以可以很方便的换成不同类型的原型对象!

浅克隆于深克隆:在原型模式中有两个概念我们需要了解一下,就是浅克隆和深克隆的概念。按照我的理解,浅克隆只是复制了基础属性,列如八大基本类型,然而引用类型实际上没有复制,只是将对应的引用给复制了!复制地址。

1、浅克隆

在浅克隆中,如果原型对象的成员变量是值类型(八大基本类型,byte,short,int,long,char,double,float,boolean).那么就直接复制,如果是复杂的类型,(枚举,String,对象)就只复制对应的内存地址。

在换个说法,就是复杂类型的成员变量(String,枚举,啥的)用的是一个。修改了克隆对象的原型对象也会变。他们是共用的。而值类型不是共用的!

2、深克隆

深克隆,我就不用多说了吧,就是什么都是单独的!全部复制,然后各自独立。你修改克隆对象对于原型对象没有丝毫影响,完全的影分身!

五、适配器模式【结构型模式】

核心思想:将一个类的接口转换成客户希望的另一个接口。adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作

适配器模式的定义:将某个类的接口转换为接口客户所需的类型。换句话说,适配器模式解决的问题是,使得原本由于接口不兼容而不能一起工作、不能统一管理的那些类可以在一起工作、可以进行统一管理。主要作用就是兼容

主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式

现实世界到代码的转换 电源插座代码示例

1、对象适配器

此适配器 实现了目标接口,并且拥有一个Adaptee对象 作为属性

港版插座面板

package adapter_pattern;

/**
 * 目标角色 Target 接口
 * 香港地区使用的插座面板,提供输出电流的功能
 */
public interface HongKongPanel {

    void offerHongKongElectricity();

}
package adapter_pattern;

/**
 * 目标角色 Target 某个具体的港版插座面板 实现类
 * 香港地区使用的插座面板,提供输出电流的功能
 */
public class HongKongPanelimpl implements HongKongPanel {

    @Override
    public void offerHongKongElectricity() {
        System.out.println("港版面板 提供电流");
    }
}

大陆地区插座面板

package adapter_pattern;

/**
 * 被适配角色 Adaptee 接口
 * 大陆地区使用的插座面板,提供输出电流的功能
 */
public interface ChinaMainlandPanel {

    void offerChinaMainlandElectricity();
}
package adapter_pattern;

/**
 * 被适配角色 Adaptee 某种具体类型的插座面板 实现类
 * 大陆地区使用的插座面板,提供输出电流的功能
 */
public class ChinaMainlandPanelimpl implements ChinaMainlandPanel {

    @Override
    public void offerChinaMainlandElectricity() {
        System.out.println("国标面板 提供电流");
    }
}

港版插头

package adapter_pattern;

/**
 * 客户角色 Client 港版插头
 */
public class ClientHongKongSocket {
    /**
     * 接受港版插座面板作为参数
     * 港版插头,插入到港版插座面板
     *
     * @param hongKongPanel
     */
    public void plugIn(HongKongPanel hongKongPanel) {
        System.out.println("港版插头 插入");
        hongKongPanel.offerHongKongElectricity();
    }
}

插头适配器

package adapter_pattern;

/**
 * 适配器角色 Adapter
 * 实现目标角色 TargetHongkongPanelInterface
 * 组合使用被适配角色 AdapteeChinaMainlandPanelInterface
 * 将对目标角色的方法调用转换为被适配角色的方法调用
 */
public class Adapter implements HongKongPanel {

    private ChinaMainlandPanel chinaMainlandPanel;

    public Adapter(ChinaMainlandPanel chinaMainlandPanel) {
        this.chinaMainlandPanel = chinaMainlandPanel;
    }

    /**
     * 适配器重写的这个方法,目的是进行转换
     */
    @Override
    public void offerHongKongElectricity() {
        System.out.println("适配器开始转换功能");
        chinaMainlandPanel.offerChinaMainlandElectricity();
    }
}

使用方法

package adapter_pattern;

/**
 * 适配器模式
 * 核心思想【对象功能的兼容】
 * 将一个类的接口转换成客户希望的另一个接口。adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
 */
public class Demo {

    /**
     * 测试主程序,港版插头 插入到适配器上
     * 适配器插入到大陆面板上
     */
    public static void main(String[] args) {

        //港版插头
        ClientHongKongSocket socket = new ClientHongKongSocket();

        System.out.println("\n======================【非适配器模式】港版插头 只能插入 港版面板======================");
        //港版面板
        HongKongPanel hongKongPanel = new HongKongPanelimpl();
        //港版插头 原先只能插到 港版面板
        socket.plugIn(hongKongPanel);

        System.out.println("\n======================【适配器模式】港版插头 可以插入 国际面板======================");
        //大陆面板
        ChinaMainlandPanel chinaMainlandPanel = new ChinaMainlandPanelimpl();
        //适配器(内部做了转换)
        Adapter adapter = new Adapter(chinaMainlandPanel);
        //港版插头 插到 适配器上
        socket.plugIn(adapter);
    }
}

测试结果输出日志

======================【非适配器模式】港版插头 只能插入 港版面板======================
港版插头 插入
港版面板 提供电流

======================【适配器模式】港版插头 可以插入 国际面板======================
港版插头 插入
适配器开始转换功能
国标面板 提供电流

适配器 实现了目标接口,并且拥有一个Adaptee对象 作为属性,很显然就是对象适配器

此案例内容来自:设计模式之适配器模式 adapter 适配器模式分类概念角色详解 类适配器 对象适配器 接口适配器 双向适配器 - 云+社区 - 腾讯云

代理模式【结构型模式】

核心思想:代理模式强调“代理执行",主要目的在控制对象的访问上。被代理对象不对外暴露,不可以被外部直接访问或者操作【虽然代理模式可能会包含功能增强,但是很明显,这里的man不再是之前那个man而且"你也不能直接操作man"】

通常会在⼀个代理类中创建⼀个被代理类的对象而非外部传入。当然你说你非要在外部 new 一个被代理对象再通过构造或其他方式传进来,咱也不是说不可以是吧!!!还是那句话,设计模式是思想。

装饰器模式【结构型模式】

核心思想:主要目的在于增加对象的行为,关注于在⼀个对象上动态的添加⽅法。装饰者模式强调的是在不修改原本对象的前提下,使原本的对象"功能增强"

这就是和代理模式的代码不同之处,代理模式一定是自身持有这个对象,不需要从外部传入。而装饰模式的一定是从外部传入,并且可以没有顺序,按照代码的实际需求随意挑换顺序,就如你吃火锅先放白菜还是先放丸子都可以

代理模式和装饰器模式的区别

  • 装饰器模式通常的做法是将原始对象作为⼀个参数传给装饰者的构造器【用户是允许直接操作原始对象】;⽽代理模式通常在⼀个代理类中创建⼀个被代理类的对象【被代理对象是不可以被用户直接访问或者操作】
  • 装饰器模式关注于在⼀个对象上动态的添加⽅法;然而代理模式关注于控制对对象的访问。(两者都是结构型设计模式)
  • 1、代理模式强调"代理执行"(虽然可能会包含功能增强,但是很明显,这里的man不再是之前那个man而且"你也不能直接操作man")
    2、装饰者模式强调的是在不修改原本对象的前提下,使原本的对象"功能增强"
装饰器模式代理模式

主要目的在于增加对象的行为,关注于在⼀个对象上动态的添加⽅法

主要目的在控制对象的访问,关注于控制对对象的访问
通常的做法是将原始对象作为⼀个参数传给装饰者的构造器【用户是允许直接操作原始对象】通常在⼀个代理类中创建⼀个被代理类的对象【被代理对象是不可以被用户直接访问或者操作】
装饰者模式强调的是在不修改原本对象的前提下,使原本的对象"功能增强"代理模式强调"代理执行"(虽然可能会包含功能增强,但是很明显,这里的man不再是之前那个man而且"你也不能直接操作man")

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。

类结构如下

1、定义一个图形绘画接口

package decorator_pattern;

/**
 * 图形绘画接口
 */
public interface Shape {
    void draw();
}

2、创建两个真正绘画图形的实现类,来实现绘画方法(圆形、矩形)

package decorator_pattern;

/**
 * 圆形
 */
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println(String.format("Circle类-》draw()圆形绘图开始【对象信息:%s】", this));
    }
}
package decorator_pattern;

/**
 * 矩形
 */
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println(String.format("Rectangle类-》draw()矩形绘图开始【对象信息:%s】", this));
    }
}

3、创建一个抽象类装饰器【基类】,同样实现了Shape接口

重点在于构造器这里是使用的是传入的参数

这里的draw()绘画方法可实现也可不实现

不实现会由后面继承的类进行实现

实现了会由后面继承的类重写

package decorator_pattern.decorator;

import decorator_pattern.Shape;

/**
 * 图形装饰器抽象类【基类】
 */
public abstract class ShapeDecorator implements Shape {

    protected Shape decoratedShape;

    public ShapeDecorator(Shape decoratedShape) {
        this.decoratedShape = decoratedShape;
    }

    /**
     * 这个方法有可能会被子类重写覆盖
     */
    @Override
    public void draw() {
        System.out.println(String.format("图形装饰器抽象类【基类】:draw()【对象信息:%s】", decoratedShape));
        decoratedShape.draw();
    }
}

4、这里创建了两个真正的装饰器类,继承抽象类装饰器【基类】,重写draw()方法

  1. 重点在于构造器这里是使用的是传入的参数
  2. 重写draw()方法,里面使用的是构造传入的对象,然后又调用了自己的独有装饰方法
package decorator_pattern.decorator;

import decorator_pattern.Shape;

/**
 * 红色边框装饰器
 */
public class RedBorderDecorator extends ShapeDecorator {

    public RedBorderDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    /**
     * 重写绘画方法
     */
    @Override
    public void draw() {
        decoratedShape.draw();
        System.out.println(String.format("RedShapeDecorator类-》draw()【对象信息:%s】", decoratedShape));
        setRedBorder(decoratedShape);
    }

    /**
     * 自己私有的装饰方法:加红色边框
     * @param decoratedShape
     */
    private void setRedBorder(Shape decoratedShape) {
        System.out.println(String.format("RedShapeDecorator类-》setRedBorder()设置边框颜色:Border Color: Red【对象信息:%s】", decoratedShape));
    }
}
package decorator_pattern.decorator;

import decorator_pattern.Shape;

/**
 * 蓝色背景装饰器
 */
public class BlueBackdropDecorator extends ShapeDecorator {

    public BlueBackdropDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    /**
     * 重写绘画方法
     */
    @Override
    public void draw() {
        decoratedShape.draw();
        System.out.println(String.format("BlueBackdropDecorator类-》draw()【对象信息:%s】", decoratedShape));
        setBlueBackdrop(decoratedShape);
    }

    /**
     * 自己私有的装饰方法:加蓝色背景
     *
     * @param decoratedShape
     */
    private void setBlueBackdrop(Shape decoratedShape) {
        System.out.println(String.format("BlueBackdropDecorator类-》setBlueBackdrop()设置背景颜色:Backdrop Color: Blue【对象信息:%s】", decoratedShape));
    }
}

 5、使用方法

package decorator_pattern;

import decorator_pattern.decorator.BlueBackdropDecorator;
import decorator_pattern.decorator.RedBorderDecorator;
import decorator_pattern.decorator.ShapeDecorator;

/**
 * 装饰器模式
 * 核心思想【对象功能的增强】
 * 主要目的在于增加对象的行为,关注于在一个对象上动态的添加方法。装饰者模式强调的是在不修改原本对象的前提下,使原本的对象"功能增强"
 */
public class Demo {

    public static void main(String[] args) {

        System.out.println("==================画圆形【直调,非装饰器模式】==================");
        Shape circleShape = new Circle();
        circleShape.draw();

        System.out.println("\n==================画圆形:装饰了红色边框【装饰器模式】==================");
        Circle circle = new Circle();
        System.out.println(String.format("main方法创建 new Circle() 圆形对象【对象信息:%s】", circle));
        ShapeDecorator circleDecorator = new RedBorderDecorator(circle);
        circleDecorator.draw();

        System.out.println("\n==================画矩形:装饰了红色边框 and 蓝色背景【装饰器模式】==================");
        Rectangle rectangle = new Rectangle();
        System.out.println(String.format("main方法创建 new Rectangle() 矩形对象【对象信息:%s】", rectangle));
        ShapeDecorator rectangleDecorator = new RedBorderDecorator(new BlueBackdropDecorator(rectangle));
        rectangleDecorator.draw();
    }
}

测试结果输出日志:

通过日志可以看出装饰器模式使用的对象都是同一个

这就是装饰器模式和代理模式的最大区别:

  • 装饰器模式使用的是对象自己本身,并对自己进行扩展
  • 代理模式使用的是代理对象,而非原对象
==================画圆形【直调,非装饰器模式】==================
Circle类-》draw()圆形绘图开始【对象信息:decorator_pattern.Circle@4b67cf4d】

==================画圆形:装饰了红色边框【装饰器模式】==================
main方法创建 new Circle() 圆形对象【对象信息:decorator_pattern.Circle@7ea987ac】
Circle类-》draw()圆形绘图开始【对象信息:decorator_pattern.Circle@7ea987ac】
RedShapeDecorator类-》draw()【对象信息:decorator_pattern.Circle@7ea987ac】
RedShapeDecorator类-》setRedBorder()设置边框颜色:Border Color: Red【对象信息:decorator_pattern.Circle@7ea987ac】

==================画矩形:装饰了红色边框 and 蓝色背景【装饰器模式】==================
main方法创建 new Rectangle() 矩形对象【对象信息:decorator_pattern.Rectangle@12a3a380】
Rectangle类-》draw()矩形绘图开始【对象信息:decorator_pattern.Rectangle@12a3a380】
BlueBackdropDecorator类-》draw()【对象信息:decorator_pattern.Rectangle@12a3a380】
BlueBackdropDecorator类-》setBlueBackdrop()设置背景颜色:Backdrop Color: Blue【对象信息:decorator_pattern.Rectangle@12a3a380】
RedShapeDecorator类-》draw()【对象信息:decorator_pattern.decorator.BlueBackdropDecorator@29453f44】
RedShapeDecorator类-》setRedBorder()设置边框颜色:Border Color: Red【对象信息:decorator_pattern.decorator.BlueBackdropDecorator@29453f44】

观察者模式【行为型模式】

责任链模式【行为型模式】 

责任链模式 (Chain of Responsibility Pattern) 是将链中每一个节点看作是一个对象,每个节点处理的请求均不同,且内部自动维护—个下—节点对象。

当—个清求从链式的首端发出时,会沿看链的路径依次传递给每—个节点对象,直至有对象处理这个清求为止。属于行为型模式。

  • Client(客户端):实例化一个处理器的链,在第一个链对象中调用handleRequest 方法。
  • Handle(处理器):抽象类,提供给实际处理器继承然后实现handleRequst方法,处理请求
  • ConcreteHandler(具体处理器):继承了handler的类,同时实现handleRequst方法,负责处理业务逻辑类,不同业务模块有不同的ConcreteHandler。

代码实现

假设现在去一家公司面试,第一次去一面,第二次去二面,第三次去直接过了。那这个模拟面试代码怎么写呢?

1、首先我们还是定义一个抽象Handler处理器,同时添加一个抽象处理方法 handleRequest,后面我只需要编写具体的处理器来继承Handler类

/**
 * 抽象处理者角色
 */
public abstract class Handler {

    protected Handler nextHandler;

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    //处理请求的方法
    public abstract void handleRequest(Integer times);
}

2、其次构建第一次面试Handler,内部实现handleRequest方法,判断一下是否是当前处理应该处理的业务逻辑,不是则向下传递。

/**
 * 具体处理者角色1:首次面试
 */
public class FirstInterview extends Handler {

    @Override
    public void handleRequest(Integer times) {
        // 条件判断是否是属于当前Handler的处理范围之内,不是则向下传递Handler处理器
        if (times == 1) {
            // 假设这里是处理的业务逻辑代码
            System.out.println("第一次面试" + times);
        } else {
            nextHandler.handleRequest(times);
        }
    }
}

 3、同样的第二次的SecondInterview和FirstInterview代码基本是一致的,我就不给大家贴出来了,直接看最后一个 

/**
 * 具体处理者角色3:第三次面试
 */
public class ThreeInterview extends Handler {
    @Override
    public void handleRequest(Integer times) {
        if (times == 3 ) {
            System.out.println("第三次面试" + times + ",恭喜面试通过,HR会跟你联系!!!");
        } else {
            System.out.println("没有人处理该请求!");
        }
    }


    public static void main(String[] args) {
        //组装责任链
        Handler first = new FirstInterview();
        Handler second = new SecondInterview();
        Handler three = new ThreeInterview();
        first.setNextHandler(second);
        second.setNextHandler(three);

        //提交请求
        // 第一次面试
        first.handleRequest(1);
        System.out.println();
        // 第二次面试
        first.handleRequest(2);
        System.out.println();
        // 第三次面试
        first.handleRequest(3);
        System.out.println();
    }
}

这个结果可以很明显的看出,根据我们传参,不同的Handler根据自己的职责处理着自己的业务,这就是责任链。

 

责任链模式的优缺点

优点:

  1. ​将请求与处理解耦;
  2. ​请求处理者(节点对象)只需关注自己感兴趣的请求进行处理即可,对于不感兴趣的请求,直接转发给下一级节点对象;
  3. ​具备链式传递处理请求功能,请求发送者无需知晓链路结构,只需等待请求处理结果;
  4. ​链路结构灵活,可以通过改变链路结构动态地新增或删减责任;
  5. 易于扩展新的请求处理类(节点),符合开闭原则。

缺点:

  1. ​责任链太长或者处理时间过长,会影响整体性能
  2. 如果节点对象存在循环引用时,会造成死循环,导致系统崩溃;
     

策略模式【行为型模式】 

策略模式( Strategy Pattern )又叫也叫政策模式( Policy Pattern) ,它是将定义的算法家族、分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户。属于行为型模式。

策略模式可以解决在有多种算法相似的情况下,使用if…else 或swith…case所带来的复杂性和臃肿性。

应用场景:

策略模式在生活场景中应用也非常多。

比如一个人的交税比率与他的工资有关,不同的工资水平对应不同的税率。再比如我们在互联网移动支付的大背景下,每次下单后付款前,需要选择支付方式。

在日常业务开发中,策略模式适用于以下场景:
1、针对同一类型问题,有多种处理方式,每一种都能独立解决问题;
2、算法需要自由切换的场景;
3、需要屏蔽算法规则的场景。

从类图中我们可以看到, 有三个参与角色:

  • 上下文角色(Context):用来操作策略的上下文环境,屏蔽高层模块(客户端)对策略,算法的直接访问,封装可能存在的变化;
  • 抽象策略角色(Strategy):规定策略或算法的行为;
  • 具体策略角色(ConcreteStrategy):具体的策略或算法实现;

策略模式代码实例

优惠策略会有很多种可能如 : 领取优惠券抵扣、返现促销、拼团优惠。下面我们用代码来模拟,

1、首先我们创建—个促销策略的抽象
PromotionStrategy :

/**
 * 促销策略抽象 
 */
public interface IPromotionStrategy {
    void doPromotion();
}

2、然后分别创建真正的策略执行类

优惠券抵扣策略 CouponStrategy 类

public class CouponStrategy implements IPromotionStrategy {
    public void doPromotion() {
        System.out.println("使用优惠券抵扣");
    }
}

返现促销策略 CashbackStrategy 类

public class CashbackStrategy implements IPromotionStrategy {
    public void doPromotion() {
        System.out.println("返现,直接打款到支付宝账号");
    }
}

拼团优惠策略 GroupbuyStrategy 类 

public class GroupbuyStrategy implements IPromotionStrategy {
    public void doPromotion() {
        System.out.println("5人成团,可以优惠");
    }
}

无优惠策略 EmptyStrategy 类 

public class EmptyStrategy implements IPromotionStrategy {
    public void doPromotion() {
        System.out.println("无优惠");
    }
}

3、然后创建促销活动方案 PromotionActivity 类 :

public class PromotionActivity {
    private IPromotionStrategy strategy;

    public PromotionActivity(IPromotionStrategy strategy) {
        this.strategy = strategy;
    }

    public void execute(){
        strategy.doPromotion();
    }
}

4、编写客户端测试类 :

public class Test {
    public static void main(String[] args) {
        PromotionActivity activity618 = new PromotionActivity(new CouponStrategy());
        PromotionActivity activityllll = new PromotionActivity(new CashbackStrategy());
        activity618.execute();
        activityllll.execute();
    }
}

运行效果如下:

使用优惠券抵扣
返现,直接打款到支付宝账号

此时,小伙伴们会发现,如果把上面这段则试代码放到实际的业务场景其实并不实用。因为我们做活动时候往往是要根据不同的需求对促销策略进行动态选择的,并不会一次性执行多种优惠。所以以,我们的代码通常会这样写 :

public class Test {
    public static void main(String[] args) {
        PromotionActivity promotionActivity = null;
        String promotionKey = "COUPON";
        if (StringUtils.equals(promotionKey, "COUPON")) {
            promotionActivity = new PromotionActivity(new CouponStrategy());
        } else if (StringUtils.equals(promotionKey, "CASHBACK")) {
            promotionActivity = new PromotionActivity(new CashbackStrategy());
        }
        promotionActivity.execute();
    }
}

这样改造之后,满足了业务需求,客户可根据自己的需求选择不同的优惠策略了。
 

建造者模式【创建型模式】

【音视频基础】一篇搞懂视频的各种封装格式 在现代多媒体处理中,视频封装格式扮演着至关重要的角色。不同的封装格式决定了视频文件的存储方式、兼容性以及功能特性。无论是观看高清视频、编辑电影剪辑,还是在互联网上流式传输内容,理解各种视频封装格式的基础知识都是必不可少的。在这篇文章中,我们将详细介绍常见的视频封装格式,探讨为什么需要这些格式,以及它们各自的功能和区别,帮助你在选择和使用视频格式时做出更明智的决定。WEBM理解各种视频封装格式的功能和区别对于选择合适的格式至关重要。 阅读详情

相关推荐

XCKU060光纤卡学习资料保存:基于kintex UltraScale XCKU060的双路QSFP+光纤PCIe 卡

基于kintex UltraScale XCKU060的双路QSFP+光纤PCIe 卡 一、板卡概述 本板卡系我司自主研发,基于XilinxUltraScaleKintex系列FPGAXCKU060-FFVA1156-2-I架构,支持PCIEGen3x8模式的高速信号处理板卡,搭配两路40GQSFP+接口,两组64-bitDDR4,每组容量8Gbyte,可稳定运行在2400MT/s。板卡具有自控上电顺序,BP...

3075

Java 中的 23 种设计模式详解

项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

微笑听雨 7万+

流式数据湖存储技术,Apache Paimon是什么?

是一项流式数据湖存储技术,可以为用户提供高吞吐、低延迟的数据摄入、流式订阅以及实时查询能力。Paimon 采用开放的数据格式和技术理念,可以与 Apache Flink / Spark / Trino 等诸多业界主流计算引擎进行对接,共同推进 Streaming Lakehouse 架构的普及和发展。

一个写湿的程序猿 2万+

「设计模式」抽象工厂模式

抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式的主要优点是隔离了具体类的生成,使得客户并不需要知道什么被创建,而且每次可以通过具体工厂类创建一个产品族中的多个对象,增加或者替换产品族比较方便,增加新的具体工厂和产品族很方便;主要缺点在于增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。

frozenpenguin的博客 2712

国家基因组科学数据中心(NGDC)---组学原始数据如何上传GSA

在发表文章之前我们需要将测序的原始数据上传到一个公共库,并在文中提供accession number,实现数据的公开共享,这是国际惯例。以前我们上传数据时只能上传到美国国立生物技术信息中心(NCBI)、欧洲生物信息学研究所(EBI)、日本核酸数据库(DDBJ),现在中国科学院北京基因组研究所(国家生物信息中心)国家基因组科学数据中心 (CNCB-NGDC)—中国的 "NCBI" 已经建立并日渐完善。组学原始数据归档库(GSA)是组学原始数据汇交、存储、管理与共享系统,是国内首个被国际期刊认可的组学数据发布平

sisichen 1万+

解锁Jetbrains AI助手:中国开发者实战配置与效率跃迁指南

本文为中国开发者提供了一份详细的Jetbrains AI助手实战配置指南。针对服务地域限制,核心解决方案是通过修改Jetbrains账户区域信息并配置网络代理,实现插件的稳定启用。文章进一步分享了AI助手在解读遗留代码、生成中文提交信息、智能问答等场景下的具体应用,旨在帮助开发者深度集成这一工具,实现编码生产力的显著提升。

weixin_28832121的博客 576

设计模式之工厂模式

工厂模式的分类 简单工厂模式(Simple Factory)–>if…else…在工厂类里判断实例化那个对象 工厂方法模式(Factory Method) 抽象工厂模式(Abstract Factory) 简单工厂模式: 客户端实例化对象的时候不再使用new Object()形式,可以根据用户的选择条件来实例化相关的类。对于客户端来说,去除了具体的类的依赖。只需要给出具体实例的描述给工...

从入门到入狱 418

Wordpress实战之第二章安装wordpress 软件需要的软件

使用下载并安装phpstudy面版工具 wget -O install.sh?https://notdocker.xp.cn/install.sh?&& sudo bash install.sh 2.安装成功如下 ==============运行状态========================= webpanel stop phpstudy running =================...

安全参透之旅 612

Java中23种设计模式

Java中23种设计模式,包括简单介绍,适用场景以及优缺点等

呜呜老司机的博客家园 9万+

g2o&PCL 四阶多项式拟合

g2o&PCL 四阶多项式拟合

dayuhaitang1的博客 140

各大厂薪资对比爬虫:Python采集OfferShow爆料数据

print(f"⚠️ API返回错误码: {data.get('code')}, msg: {data.get('msg')}")ax.set_title('各大厂薪资对比 (基于OfferShow爆料数据)', fontsize=16, fontweight='bold')stats.columns = ['人数', '平均年薪', '年薪中位数', '年薪标准差', '平均月薪', '平均月数']print(analyzer.get_position_stats('字节跳动').head(10))

2201_76125261的博客 604

一文讲完Java常用设计模式(全23种)

设计模式是软件开发中非常有用的工具,可以提高代码的可重用性和可维护性,同时也可以提高开发人员的工作效率。 设计模式有几种类型,包括创建型、结构型和行为型模式。 创建型模式用于以灵活和高效的方式创建对象。包括Singleton模式、工厂模式和抽象工厂模式等。 结构型模式用于组合类和对象以形成更大的结构。包括适配器模式、桥接模式和装饰器模式等。 行为型模式用于处理类或对象之间的通信和控制流。包括观察者模式、策略模式和模板方法模式。

不积跬步无以至千里,不积小流无以成江海。一个喜欢学习分享的程序员 4万+

18、深入解析航空飞行数据中的秘密:从数据清理到高级分析

本文详细解析了如何使用R语言处理和分析航空飞行数据,从基础的数据清理到复杂的回归分析和机器学习模型构建。文章涵盖了探索性数据分析、天气数据的整合、地理信息可视化、时间序列预测以及航班延误的优化策略等内容,展示了如何通过数据挖掘技术提高航空运营效率和乘客满意度,并探讨了数据质量评估与隐私保护的重要性。

convnet3designer的博客 107

Java设计模式 Design Pattern(长期更新)

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33682790的博客 199

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

大话设计模式 java_designpattern: 基于大话设计模式的java实现,由于本书只够入门,因此另外增加案例辅助理解,欢迎大家完善案例库(持续更新中)...

design pattern 参考《大话设计模式》(持续更新中)目录在支持md格式文件的软件中使用由于此书案例案例较简单,仅够入门,因此需要更多案例来不断加深对设计模式的理解,欢迎大家将工作中遇到的设计模式以案例、地址,甚至一句话来帮助大家共同学习。大家可以在各个设计模式的包下新建自己包来增加,共勉之!JDK并发包中AQS类就是一个模板方法应用 java.util.concurrent.locks...

weixin_32778881的博客 283

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

探索设计模式的艺术:JackChan1999的DesignPattern项目

探索设计模式的艺术:JackChan1999的DesignPattern项目 在编程的世界中,设计模式是解决问题的利器,是经验与智慧的结晶。今天我们要介绍的开源项目【DesignPattern】,是由开发者JackChan1999精心编写的,旨在帮助程序员理解和应用各种设计模式。 项目简介 这个项目是一个全面的设计模式参考库,包含了GOF的23种经典设计模式,以及一些现代编程中的新型模式。每一种模...

gitblog_00018的博客 494

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Java设计模式汇总,持续更新中

一直想系统的学习设计模式,但是由于各种原因,shi

GROWTH 866

【墙外的IT世界】Java-design-pattern 一个有意思的社区推荐

推荐一个不错的AI教程:https://www.captainbed.net/blog-vincent/ 本篇不生产“design pattern”代码,只推荐一个“真香”的repository、还有作者,哦对,还有他的gitter聊天室。 1.分享内容 伴随java语言更新而不断更新的‘Java-design-pattern’论坛。 git仓库地址:...

暂七师师长常乃超 1302

Java设计模式梳理(持续更新)

概览 Java的设计模式大体上分为三大类,共23种: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。 行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 设计模式遵循...

makersy的博客 277

java设计模式(持续更新中)

单例模式确保一个类只有一个实例,并提供一个全局访问点。单例模式可以分为两种:饿汉式和。

m0_75165868的博客 1094

java 23种设计模式详细讲解-持续更新

如果想要更加详细的Java中的23种设计模式视频资源,请点击链接:Java中的23种设计模式视频资源下载 原文链接:java设计模式详细讲解-持续更新 综述 1、什么是设计模式: 设计模式一种解决方案或者工具,是前人总结了大量项目经验总结出的一套有用的经验和方法。 2、目的: 设计模式的目的是使软件工程在降低维护性,增加可扩展性,降低程序的复杂度(O|N) 3、总结...

u013611978的博客 244

java中设计模式的使用(持续更新中)

编写软件过程中,程序员面临着来自耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战,设计模式是为了让程序(软件),具有更好的代码重用性(相同功能的代码,不用多次编写)可读性(编程规范性,便于其他程序员的阅读和理解)可扩展性(当需要增加新的功能时,非常的方便,也叫可维护性)可靠性(当我们增加新的功能后,对原来的功能没用影响)使程序呈现高内聚,低耦合的特性设计模式的七大原则:单一职责原则对类来说,及一个类应该只负责一项职责。如类A负责两个不同的职责:职责1,职责2。

现在的我强的可怕 1327

Java必会设计模式【持续更新中】

First Head 设计模式1、策咯模式 1、策咯模式 在面试字节跳动的时候,面试官就让我用代码实现一下策略模式,说实话,当时我是很慌张的。在面试深信服的时候面试官也问了一下设计模式的单例模式,那时候我还不是很懂设计模式,然后我就把《First Head设计模式》给啃完了,但是就是简单过了一遍。这次面试字节跳动的时候又来,干…(省略内心1000字的问候)但是还是要好好写。 首先我们要知道策略模式是干了一件什么事情? 策咯模式定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于

weixin_43878297的博客 493

Java 各种设计模式 持续更新

一、生产者和消费者模式 关于Object类中的wait和notify方法。(生产者和消费者模式!) 第一:wait和notify方法不是线程对象的方法,是java中任何一个java对象 都有的方法,因为这两个方式是Object类中自带的。 wait方法和notify方法不是通过线程对象调用, 不是这样的:t.wait(),也不是这样的:t.notify()..不对。 第二:wait()方法作用? Object o = new Object(); o.wait(); 表示: 让

jklmf1的博客 243

Java设计模式 [持续更新]

Java设计模式,主要用Java实现

心向阳光的天域的博客 178

自学java设计模式(持续更新)

基于白嫖B站尚硅谷视频:尚硅谷Java设计模式(图解+框架源码剖析) 目录1 写在前面2 七大原则2.1 单一职责原则2.1.1 基本介绍2.1.2 应用实例2.2 接口隔离原则2.3 依赖倒转(倒置)原则2.4 里氏替换原则2.5 开闭原则2.6 迪米特法则2.7 合成复用原则三级目录 1 写在前面 由Erich Gamma等人在1990年代由建筑设计领域引入到计算机科学领域; 七大原则; 23种设计模式; 高内聚,低耦合; 设计模式设计的七大原则; 2 七大原则 2.1 单一职责原则 2.1.1 基

你佳哥 944
上一篇: 重写equals就必须重写hashCode的原理分析
下一篇: 对多态的理解(附经典练习题)
Marvin-Fox
博客等级 码龄11年 190粉丝 100原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值