前端常用设计模式快速入门

vue快速入门 Vue 是一套用于构建用户界面的渐进式JavaScript框架,简化dom操作。基于MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自动传递给 View,即所谓的数据双向绑定.简单可以总结:VUE是一套前端框架,免除了原生JavaScript中的DOM操作,简化书写VUE基于MVVM(Model-View_ViewModel)思想,实现数据双向绑定。 阅读详情

前言

最近在系统的整理一下JavaScript的设计模式,发现把所有的模式按照生活场景结合起来去记,会加深记忆力且更扎实。所谓的设计模式更愿意称之为习惯性写法而形成的不同代码习惯模式,以下内容为本人基于B站相关内容学习及个人了解所写

模式一:构造器模式

首先理解什么是构造器,构造器‌(Constructor)本质上是一个特殊函数,用于创建和初始化对象实例,当通过 new Constructor创建和初始化对象的时候,称该函数为构造器,如果不new,直接使用,则与一般函数没有差别。以下模式为通过new Constructor实现,因此称为构造器模式。

日常场景结合:假设工厂里面有很多员工,我们需要将其进行分类,我们用Person进行标识,每一位员工都可以称呼为Person,因此,实现构造器模式函数如下

function Person(name, age) {
          this.name = name;
          this.age = age;
          this.sayName = function() {
            console.log("My name is " + this.name);
          }
      }
      // 使用构造器创建对象
      // 创建两个 Person 实例
      var person1 = new Person("Alice", 30);
      var person2 = new Person("Bob", 25);
      console.log(person1, person2)
      person1.sayName()
      person2.sayName()

模式二:原型模式

由于构造器模式每次new一个实例,公共方法sayName也需要单独创建一个新的内存去存储,构造函数的原型prototype是唯一的,因此,有了原型模式提取出公共方法进行优化。

      // 构造器模式示例
      function Person(name, age) {
          this.name = name;
          this.age = age;
          // 提取到prototype中,避免每次创建实例时都创建一遍方法
          // this.sayName = function() {
          //   console.log("My name is " + this.name);
          // }
      }
      Person.prototype.sayName = function() {
          console.log("My name is " + this.name);
      }
      // 使用构造器创建对象
      // 创建两个 Person 实例
      var person1 = new Person("Alice", 30);
      var person2 = new Person("Bob", 25);
      console.log(person1, person2)
      person1.sayName();
      person2.sayName();

es6 class构造器和原型写法,constructor,sayName都挂载在Person.prototype下

class Person {
      constructor(name, age, job) {
        this.name = name;
        this.age = age;
        this.job = job;
      }
      sayName() {
        console.log("My name is " + this.name);
      }
    }
    var employee = new Person("Nicholas", 29, "Software Engineer");
    console.log(employee);
    employee.sayName();

应用:

多个重复样式tab切换

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>原型模式距离</title>
  <style>
    .container1,
    .container2 {
      width: 100%;
      height: 300px;
      overflow: hidden;
      margin-top: 20px;
    }

    .box li {
      float: left;
      margin: 0;
      padding: 0;
      list-style: none;
      height: 300px;
      background-color: lightslategray;
      display: none;
    }

    .box li.active {
      background-color: orange;
      display: block;
      width: 100%;
    }

    .header {
      margin: 0;
      padding: 0;
      list-style: none;
      overflow: hidden;
    }

    .header li {
      float: left;
      list-style: none;
      padding: 10px 20px;
      cursor: pointer;
    }

    .header li.active {
      background-color: orange;
      color: white;
    }
  </style>
</head>

<body>
  <div class="container1">
    <ul class="header">
      <li class="active">1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
    </ul>
    <ul class="box">
      <li class="active">111</li>
      <li>222</li>
      <li>333</li>
      <li>444</li>
      <li>555</li>
    </ul>
  </div>
  <div class="container2">
    <ul class="header">
      <li class="active">1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
    </ul>
    <ul class="box">
      <li class="active">111</li>
      <li>222</li>
      <li>333</li>
      <li>444</li>
      <li>555</li>
    </ul>
  </div>
  <script>

    function Tabs(container, eventType) {
      this.container = document.querySelector(container);
      this.headerItems = this.container.querySelectorAll('.header li');
      this.boxItems = this.container.querySelectorAll('.box li');
      this.eventType = eventType || 'click';
      this.change();
    }
    Tabs.prototype.change = function () {
      this.headerItems.forEach((item, index) => {
        item.addEventListener(this.eventType, () => {
          this.headerItems.forEach((header) => header.classList.remove('active'))
          this.boxItems.forEach((box) => box.classList.remove('active'))
          this.headerItems[index].classList.add('active')
          this.boxItems[index].classList.add('active')
        }, false)
      })
    }
    new Tabs('.container1', 'click');
    new Tabs('.container2', 'mouseover');
  </script>
</body>

</html>
// es6写法
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>原型模式距离</title>
  <style>
    .container1,
    .container2 {
      width: 100%;
      height: 300px;
      overflow: hidden;
      margin-top: 20px;
    }

    .box li {
      float: left;
      margin: 0;
      padding: 0;
      list-style: none;
      height: 300px;
      background-color: lightslategray;
      display: none;
    }

    .box li.active {
      background-color: orange;
      display: block;
      width: 100%;
    }

    .header {
      margin: 0;
      padding: 0;
      list-style: none;
      overflow: hidden;
    }

    .header li {
      float: left;
      list-style: none;
      padding: 10px 20px;
      cursor: pointer;
    }

    .header li.active {
      background-color: orange;
      color: white;
    }
  </style>
</head>

<body>
  <div class="container1">
    <ul class="header">
      <li class="active">1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
    </ul>
    <ul class="box">
      <li class="active">111</li>
      <li>222</li>
      <li>333</li>
      <li>444</li>
      <li>555</li>
    </ul>
  </div>
  <div class="container2">
    <ul class="header">
      <li class="active">1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
    </ul>
    <ul class="box">
      <li class="active">111</li>
      <li>222</li>
      <li>333</li>
      <li>444</li>
      <li>555</li>
    </ul>
  </div>
  <script>

    class Tabs {
      constructor(container, eventType) {
        this.container = document.querySelector(container);
        this.headerItems = this.container.querySelectorAll('.header li');
        this.boxItems = this.container.querySelectorAll('.box li');
        this.eventType = eventType || 'click';
        this.change();
      }
      change() {
        this.headerItems.forEach((item, index) => {
          item.addEventListener(this.eventType, () => {
            this.headerItems.forEach((header) => header.classList.remove('active'))
            this.boxItems.forEach((box) => box.classList.remove('active'))
            this.headerItems[index].classList.add('active')
            this.boxItems[index].classList.add('active')
          }, false)
        })
      }
    }
    new Tabs('.container1', 'click');
    new Tabs('.container2', 'mouseover');
  </script>
</body>

</html>

模式三:工厂模式

概念:由一个工厂对象决定创建某一种产品对象类的实例。简单理解为一个函数里面传入特定选择参数,返回根据条件判断后的某个对象的具体实例。下面的例子,根据用户角色返回对应角色的菜单权限,总的侧边栏工厂函数中返回每个用户对应的角色与对应的页面权限

  <!DOCTYPE html>
  <html lang="en">

  <head>
    <meta charset="UTF-8">
    <title>工厂模式</title>
  </head>

  <body>
    <h1>工厂模式</h1>
    <script>
      // 工厂模式示例
      function User(name, page) {
        this.name = name;
        this.page = page;
      }
      function FactoryUser(role) {
        switch (role) {
          case 'admin':
            return new User('admin', ["home", "manage", "detail"]);
          case 'customer':
            return new User('customer', ["home", "detail"]);
          default:
            throw new Error('Unknown role: ' + role);
        }
      }
      var adminUser = FactoryUser('admin');
      var customer = FactoryUser('customer');
      console.log(adminUser);
      console.log(customer);
    </script>
  </body>
  </html>
// es6写法
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>工厂模式</title>
</head>

<body>
  <h1>工厂模式</h1>
  <script>
    // 工厂模式示例
    class User {
      constructor(name, page) {
        this.name = name;
        this.page = page;
      }
      static FactoryUser(role) {
        switch (role) {
          case 'admin':
            return new User('admin', ["home", "manage", "detail"]);
            break;
          case 'customer':
            return new User('customer', ["home", "detail"]);
            break;
          default:
            throw new Error('Unknown role: ' + role);
        }
      }
    }
    var adminUser = User.FactoryUser('admin');
    var customer = User.FactoryUser('customer');
    console.log(adminUser);
    console.log(customer);
  </script>
</body>

</html>

模式四:抽象工厂模式

抽象工厂对比上面的工厂模式区别在于,工厂模式返回具体的实例,即new Constructor(),而抽象工厂函数,在抽象工厂函数中返回的是类(构造函数),具体实例需要new调用去实现,以下基于上面的例子进行扩展,假设现在用户进入了对应页面后,对进入的页面也有一些展示区别和操作方法的区别,因此我们需要基于上面的函数进行扩展如下

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>抽象工厂模式</title>
</head>

<body>
  <h1>抽象工厂模式</h1>
  <script>
    // 工厂模式示例
    class User {
      constructor(name, role, page) {
        this.name = name;
        this.role = role;
        this.page = page;
      }
      dataShow() {
        throw new Error('抽象方法在各个扩展中实现')
      }
    }
    class SuperAdmin extends User {
      constructor(name) {
        super(name, 'admin', ["home", "manage", "detail"]);
      }
      dataShow() {
        console.log('管理员页面展示');
      }
      addUser() {
        console.log('添加用户');
      }
    }
    class Customer extends User {
      constructor(name) {
        super(name, 'customer', ["home", "detail"]);
      }
      dataShow() {
        console.log('客户页面展示');
      }
    }

    function getAbstractFactoryUser(role) {
      switch (role) {
        case 'admin':
          return SuperAdmin;
        case 'customer':
          return Customer;
        default:
          throw new Error('Unknown role: ' + role);
      }
    }
    let adminUser = getAbstractFactoryUser('admin');
    let customer = getAbstractFactoryUser('customer');
    let user1 = new adminUser('张三');
    let user2 = new customer('李四');
    console.log(user1);
    console.log(user2);
  </script>
</body>

</html>

模式五:单例模式

保证一个类只有一个实例,主要解决一个全局使用的类频繁的创建和销毁,占用内存的问题。经典例子:模态弹框

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>单例模式</title>
</head>

<body>
  <h1>单例模式</h1>
  <script>
    // 单例模式示例
    const Singleton = (function(){
      var instance;
      function User(name, age){
        this.name = name;
        this.age = age;
      }
      return function(name, age){
        if(!instance){
          instance = new User(name, age);
        }
        return instance;
      }
    })()
    console.log(Singleton("Alice", 30)); 
    console.log(Singleton("Bob", 25));
    // 单例模式闭包机制使用的是第一次初始化的实例对象,输出两次都是同一个实例
  </script>
</body>

</html>
// es6写法
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>单例模式</title>
</head>

<body>
  <h1>单例模式</h1>
  <script>
    // 单例模式ES6示例
    class Singleton {
      constructor(name, age) {
        if (!Singleton.instance) {
          this.name = name;
          this.age = age;
          Singleton.instance = this;
        }
        return Singleton.instance;
      }
    }
    console.log(new Singleton('Alice', 30)  === new Singleton('Bob', 25)) // true
  </script>
</body>

</html>

应用:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>单例模式</title>
  <style>
    #modal{
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 200px;
      height: 200px;
      background-color: rgba(0,0,0,0.5);
    }
  </style>
</head>

<body>
  <h1>单例模式</h1>
  <button id="open">打开</button>
  <button id="close">关闭</button>
  <script>
    const Modal = (function(){
      let instance = null;
      return function(){
        if(!instance){
          instance = document.createElement('div');
          instance.id = 'modal';
          instance.innerHTML = '这是模态框'
          instance.style.display = 'none';
          document.body.appendChild(instance);
        }
        return instance;
      }
    })()
    document.getElementById('open').onclick = function(){
      const modal = Modal();
      modal.style.display = 'block';
    }
    document.getElementById('close').onclick = function(){
      const modal = Modal();
      modal.style.display = 'none';
    }
    
  </script>
</body>

</html>

模式六:代理模式

代理模式使用到的是es6的Proxy,Proxy是ES6引入的一个元编程特性,它允许你创建一个代理对象,用于拦截并自定义 JavaScript 对象的基本操作。通过代理对象,你可以拦截并重定义对象的基本操作,比如属性查找、赋值、枚举等。Proxy的核心思想是在目标对象和代码之间建立一个拦截层,使得可以对目标对象的操作进行拦截和监视。


<!--
target:要代理的目标对象。
handler:一个对象,定义了代理对象的行为,包括捕获器(handlers)等。
-->
let proxy = new Proxy(target, handler);

设计模式中的代理模式是指为其他对象提供一种代理以控制对这个对象的访问,以下为一个简易的vue3响应式代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>代理模式</title>
</head>

<body>
  <h1>代理模式</h1>
  <div id="box"></div>
  <script>
    const box = document.getElementById('box');
    const vueobj = {}
    const proxy = new Proxy(vueobj,{
      get(target, prop){
        return target[prop]
      },
      set(target, prop, value){
        if(prop === 'data'){
          box.innerHTML = value
        }
        target[prop] = value
      }
    })
    // 模拟vue数据变化
    proxy.data = 'Hello Proxy Pattern!'
    console.log(vueobj);
  </script>
</body>

</html>

模式七:观察者模式

观察者模式包含观察目标和观察者两个对象,一旦观察目标的状态发生改变,所有的观察者都会收到对应的通知。即当一个对象的状态发生改变时,所有依赖于它的对象都收到通知并触发更新函数,解决了主体对象与观察者直接功能的耦合

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>观察者模式</title>
</head>

<body>
  <h1>观察者模式</h1>
  <script>
    class Subject {
      constructor() {
        this.observers = []
      }
      add(observer) {
        this.observers.push(observer)
      }
      remove(observer) {
        this.observers = this.observers.filter(item => item !== observer)
      }
      notify() {
        this.observers.forEach(observer => {
          observer.update()
        });
      }
    }
    class Observer {
      constructor(name) {
        this.name = name
      }
      update() {
        console.log(this.name + ' 收到通知');
      }
    }
    // 主体
    const subject = new Subject()
    // 观察者
    const observer1 = new Observer('观察者1')
    const observer2 = new Observer('观察者2')
    // 添加观察者
    subject.add(observer1)
    subject.add(observer2)
    console.log(subject.notify());
  </script>
</body>

</html>

应用:

点击左侧页面组件菜单头部及右侧面包屑组件同步更新菜单,有其他实现方法,此场景仅为基于无vue框架等最原始的实现方式,以下例子左侧菜单栏为观察目标,观察者为右侧和头部面包对应标题

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>观察者模式</title>
  <style>
    body{
      padding: 0;
      margin: 0;
    }
    .box{
      width: 100%;
    }
    ul,li{
      padding: 0;
      margin: 0;
      list-style: none;
    }
    li{
      cursor: pointer;
    }
    li:hover{
      background-color: #ddd;
      color: #fff;
    }
    .header{
      width: 100%;
      height: 60px;
      background-color: #333;
      color: #fff;
    }
    .left{
      width: 200px;
      background-color: #f4f4f4;
      float: left;
      height: calc(100vh - 60px);
    }
    .right{
      flex: 1;
      background-color: #fff;
    }
  </style>
</head>

<body>
  <div class="box">
    <div class="header">

    </div>
    <div class="left">
      <ul>
        <li>首页</li>
        <li>新闻</li>
        <li>关于我们</li>
        <li>更多资讯</li>
      </ul>
    </div>
    <div class="right">
      <div class="bread"></div>
    </div>
  </div>
  <script>
    class Subject {
      constructor() {
        this.observers = []
      }
      add(observer) {
        this.observers.push(observer)
      }
      remove(observer) {
        this.observers = this.observers.filter(item => item !== observer)
      }
      notify(data) {
        this.observers.forEach(observer => {
          observer.update(data)
        });
      }
    }
    class Observer {
      constructor(name) {
        this.ele = document.querySelector(name)
      }
      update(data) {
        this.ele.innerHTML = data
      }
    }
    // 主体
    const subject = new Subject()
    // 观察者
    const observer1 = new Observer('.bread')
    const observer2 = new Observer('.header')
    // 添加观察者
    subject.add(observer1)
    subject.add(observer2)
    console.log(subject.notify());
    let oli = document.querySelectorAll('.left ul li')
    for(let i = 0; i < oli.length; i++) {
      oli[i].onclick = function() {
        console.log('点击了' + this.innerHTML);
        subject.notify(this.innerHTML)
      }
    }
    oli[0].click()
  </script>
</body>

</html>

缺点:无法对事件通知进行管控,如筛选通知的对象和具体事件,因此有了下面的发布订阅模式

模式八:发布订阅模式

下面图片左边为观察者模式,整体即为整个发布订阅者模式,发布订阅者模式中,观察者和目标要相互知道,发布者和订阅者不需要相互知道,通过第三方实现调度,属于经过解耦合的观察者模式,个人理解与观察者模式的区别在于多传入了参数进行一些数据和事件类型的筛选,相当于观察模式结合了策略模式进行筛选,可以实现指定的类型加入观察不像观察者模式一样写了固定的方法与输出。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>订阅发布者模式模式</title>
</head>

<body>
  <h1>订阅发布者模式模式</h1>
  <script>
    // publish发布
    // subscribe订阅
    const PubSub = {
      list: {},
      publish(type, data){
        if(!this.list[type]) return
        this.list[type].forEach(item => item(data))
      },
      subscribe(type,cb){
        if(!this.list[type]){
          this.list[type] = []
        }
        this.list[type].push(cb)
      },
      unSubscribe(type, cb){
        if(!this.list[type]) return
        this.list[type] = this.list[type].filter(item => item !== cb)
      }
    }

    function testA(data){
      console.log('testA', data);
    }
    function testB(data){
      console.log('testB', data);
    }
    PubSub.subscribe('testA', testA)
    PubSub.subscribe('testB', testB)
    console.log(PubSub.publish('testA', "aaaa"));
    console.log(PubSub.publish('testB', "bbbb"));
    // 取消订阅testA
    PubSub.unSubscribe('testA', testA)
    console.log(PubSub.publish('testA', "aaaa"));
    // 得到undefined
    // 重新订阅即可重新发布
  </script>
</body>

</html>

应用:

基于上面观察者模式去扩展应用发布订阅模式,修改后代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>观察者模式</title>
  <style>
    body{
      padding: 0;
      margin: 0;
    }
    .box{
      width: 100%;
    }
    ul,li{
      padding: 0;
      margin: 0;
      list-style: none;
    }
    li{
      cursor: pointer;
    }
    li:hover{
      background-color: #ddd;
      color: #fff;
    }
    .header{
      width: 100%;
      height: 60px;
      background-color: #333;
      color: #fff;
    }
    .left{
      width: 200px;
      background-color: #f4f4f4;
      float: left;
      height: calc(100vh - 60px);
    }
    .right{
      flex: 1;
      background-color: #fff;
    }
  </style>
</head>

<body>
  <div class="box">
    <div class="header">

    </div>
    <div class="left">
      <ul>
        <li>首页</li>
        <li>新闻</li>
        <li>关于我们</li>
        <li>更多资讯</li>
      </ul>
    </div>
    <div class="right">
      <div class="bread"></div>
    </div>
  </div>
  <script>
    // publish发布
    // subscribe订阅
    const PubSub = {
      list: {},
      publish(type, data){
        if(!this.list[type]) return
        this.list[type].forEach(item => item(data))
      },
      subscribe(type,cb){
        if(!this.list[type]){
          this.list[type] = []
        }
        this.list[type].push(cb)
      },
      unSubscribe(type, cb){
        if(!this.list[type]) return
        if(!cb){
          this.message[type] && (this.message[type].length=0);
        }else{
          this.list[type] = this.list[type].filter(item => item !== cb)
        }
        
      }
    }

    function testA(data){
      console.log('testA', data);
    }
    function testB(data){
      console.log('testB', data);
    }
    PubSub.subscribe("UpdateBread",function(data){
      document.querySelector('.bread').innerHTML = data
    })
    PubSub.subscribe("UpdateHeader",function(data){
      document.querySelector('.header').innerHTML = data
    })
    let oli = document.querySelectorAll('.left ul li')
    for(let i = 0; i < oli.length; i++) {

      oli[i].onclick = function() {
        PubSub.publish("UpdateBread", this.innerHTML)
        PubSub.publish("UpdateHeader", this.innerHTML)
      }
    }
    PubSub.publish("UpdateBread", oli[0].innerHTML)
        PubSub.publish("UpdateHeader", oli[0].innerHTML)
  </script>
</body>

</html>

以上就是前端常用的设计模式及其应用,尽量用容易理解的语言输出,后续继续完善更正,如有觉得不对的地方,也欢迎各位大神指出进行修正!

Java小白从入门到精通,Java零基础入门看这一篇就够了 作为刚刚接触java的小白,今天这篇文章的目的是帮助大家快速入门java,少走弯路 如何快速入门Java? 一、作为刚接触Java的新手,先了解Java的基础。 Java 基本语法、Java 平台应用、Java的核心概念:JVM、JDK、JRE以及Java面向对象思想,同时要会学到如何在系统中搭建Java开发环境,以及如何利用第三方工具进行Java程序的开发。 还有记住学习Java语言最重要的是两点: 学习步骤/方法 学习资源 找到适合自己的学习方式,找到适合自己现阶段的学习资料,学习的过程中最好记笔记,. 阅读详情

相关推荐

招行收款通SM2加密解密全流程解析:PHP开发者必看

本文详细解析了招商银行收款通服务中SM2加密解密的完整流程,特别针对PHP开发者提供了从密钥管理到签名验签的实战指南。涵盖国密算法基础、PHP环境配置、密钥安全存储及生产环境优化方案,帮助开发者快速实现高安全性的支付系统集成。

weixin_30632089的博客 651

你必须要会的4种Web前端设计模式

在软件工程领域,设计模式是为了解决特定问题而产生的一些可复用的方法、模板。每一种设计模式都针对性解决某一类场景的问题。设计模式被认为是开发者解决通用问题的最佳实践。 通常我们学习的设计模式,大多数与面向对象的语言相关,比如Java。市面上大部分关于设计模式的书籍也是基于面向对象来进行讲解的。但对于大部分平常写JavaScript的开发者来说,面向对象的设计模式基本上是用不着的,如果不仔细思考,会经常错误或过度使用设计模式,不仅增加了软件开发成本,还加重了后期维护的负担。作为以Javascript为主语..

ForeverCjl的专栏 5601

MFC停靠窗口实战:CDockablePane从创建到控件布局的完整指南(附残影问题排查)

本文提供了MFC中CDockablePane停靠窗口的完整实战指南,涵盖从自定义窗格类创建、主框架集成、内部控件布局到高级功能定制的全过程。针对开发中常见的“残影”视觉问题,文章深入剖析了其根源,并给出了系统性的排查步骤与解决方案,帮助开发者构建稳定、专业的可停靠用户界面。

sun99的博客 615

一文快速了解前端常见的设计模式

单例模式,发布订阅模式,计算属性,状态管理,闭包,路由模式

weixin_43162494的博客 880

PID温控实验平台搭建(二)——PID进阶知识介绍及源码分享

最近,我突发奇想去翻阅了一些我本科期间所做的一些小项目,发现都挺有意思的!希望通过我的讲解文章可以帮助你们少走一些弯路!今天,我要分享的是一个PID温控实验平台的搭建,这是一个系列文章,手把手地教你学习和认识PID算法,了解这种算法在温度控制中的应用。由于我知识有限,如果出现一些错误,希望大家可以帮助我指出来,我们一起学习进步!!!

qq_35953617的博客 8050

Android性能分析深度指南:Perfetto工具全面解析

本文深入探讨Android性能优化工具Perfetto的应用与实践。作为Google推出的新一代追踪系统,Perfetto整合了CPU调度、内存分配、电池状态等多维度分析功能,通过高性能数据处理和可视化界面帮助开发者定位性能瓶颈。文章系统介绍了Perfetto的架构原理、配置方法和核心功能,包括CPU性能分析、内存泄漏检测等关键技术。通过电商应用卡顿优化的实战案例,展示了如何利用数学建模(如帧时间公式$T_{\text{render}}\leq16.67\text{ms}$)指导性能调优。

郑伟强dev的专栏 145

Java设计模式快速入门之前端控制器模式

Java设计模式快速入门之前端控制器模式

xuzhiyongcsdnper 193

HTML炫酷烟花④(完整代码)

HTML语言实现炫酷烟花的完整代码。

AIGC 9万+

终于有人把如何快速入门前端开发讲明白了!

提到前端,大多数人都会想到薪资高。也正因为如此,很多人想要从事前端开发这个岗位,也由此衍生出来一个问题:为什么前端工程师供不应求,但还是有很多学前端的人找不到工作?其实行业不是缺前端工程师...

xmt1139057136的专栏 723

实战:RK3568 Android14 调试 MIPI DSI 液晶屏

LCD1_RST -> 对应原理图网络连接到 GPIO。LCD1_PWR_EN ->用于给屏幕 VCC 供电。LCD0_BL_EN / LCD0_BL_PWM -> MP3302 升压芯片驱动 LED 灯条。![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/100f2be7f763494da1032464e272e63b.png&pinctrl {/* 配置 LCD_RST 和 LCD_EN */

qq_33427070的博客 1551

即插即用系列(代码实践) | CVPR 2025 FDConv:频域动态卷积,打破密集预测任务的参数效率瓶颈

本文提取自 CVPR 2025 的最新底层算子革新论文《Frequency Dynamic Convolution for Dense Image Prediction》。近年来,动态卷积(Dynamic Convolution)通过融合多个并行卷积核极大地提升了模型性能,但研究表明:这些并行卷积核在频域上的响应高度相似,导致了极其严重的参数浪费,且缺乏对不同频率特征的自适应能力。本文复现了该网络的核心架构——FDConv(频率动态卷积)。该方案创造性地在傅里叶域(Fourier Domain)中学习固定参

分享顶会顶刊论文即插即用模块 113

struts2快速入门

一、概述: status2是一个基于MVC设计模式的WEB应用框架,本质上相当于servlet,在MVC设计模式中,status2作为控制器来建立模型与视图数据的交互。 status2和status1的体系结构发生了巨大变化,status2以WebWork为核心。采用拦截器的机制来处理用户的请求,这样使得业务逻辑控制器能够与servletAPI完全脱离开。相对于WebWork来说status2变化很小。 二、常见WEB层框架: status2 status1 WebWork SpringMVC 三、快速

weixin_40222311的博客 2040

9.27华为OD机试真题 新系统 - 均衡调度 (Java/Py/C/C++/Js/Go)

9.26华为OD机试真题 新系统 - 均衡调度 (Java/Py/C/C++/Js/Go)

算法大师! 521

为什么说前端一定要学好设计模式?

设计模式(Design Pattern)大家一定不陌生。通俗地讲,它是前辈们对代码开发经验的总结,让你写出可扩展、可读、可维护的高质量代码,还能让你在遇到相似的问题、场景时,快速找到更优的...

前端开发博客 9293

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Struts2快速入门,超简单详细的快速入门教程

一、Struct2的概述 1、什么是Struct2 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的

程序员猫爪 1万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

【直播回顾】技术大咖带你学前端:走近前端设计模式

本周白月光为我们带来了前端福音,4月8日晚上直播串讲了前端开发的相关知识,为了方便错过直播的小伙伴学习,本次直播是可以回放观看的~ 【直播回放】前端技术变革(一):前端设计模式演变 https://live.youkuaiyun.com/room/csdnstudent/ouSwHpSs 嘉宾:C站白月光——20年码龄的技术VC大咖 内容: 1.传统前端开发工作如何提效 2.前端设计模式的积累与演化 3.动态构建与静态编译 扫描下方二维码观看直播回放~ 你将收获:掌握新型前...

优快云高校俱乐部官方博客 1030

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

菜鸟干货!web前端如何快速入门?

同样是web前端工程师,我们通常会发现他们的薪资待遇截然不同,web更注重的在于技术。 通过web培训出来的工程师,通常是中高级。自学的web工程师也有可能达到这样的水平,但是前提是必须系统化进行学习。那么初级web前端应该懂什么呢? 首先,Web工程师要入门必须要了解前端、后端、后台的基本概念,同时要了解基本的html、css和javascript语法,最后根据设计师的设计图在不考虑兼容...

weixin_43955769的博客 518

前端有哪些必须掌握的设计模式?

设计模式(Design Pattern)大家一定不陌生。通俗地讲,它是前辈们对代码开发经验的总结,让你写出可扩展、可读、可维护的高质量代码,还能让你在遇到相似的问题、场景时,快速找到更优的...

web前端开发 235

如何快速入门Web前端行业 需要掌握哪些知识点

  如何快速入门Web前端行业?需要掌握哪些知识点?Web前端的薪资正在不断上涨中,Web前端2-3年工作经验的人年薪30万也不稀奇。各招聘网站对Web前端的招聘职位越来越多,招聘薪资和福利也是一涨再涨,学习Web前端成了很多年轻人的选择。   在学习之前,我们首先得知道,成为Web前端工程师,需要掌握哪些技能。一名优秀的Web前端工程师,需要JavaScript语言基础扎实,熟悉ES5、S6语法,了解TypeScript,具有良好的规范开发习惯;熟悉常用的设计模式,熟练使用Vue、Angular技术

qq_43444478的博客 150

强力推荐!web前端小白最常用的5个学习网站,让你快速入门!

放在最前面希望不会影响你的观看,文章很不错哦!       自己整理了一份2018最全面前端学习资料,从最基础的HTML+CSS+JS [炫酷特效,游戏,插件封装,设计模式]到移动端HTML5的项目实战的学习资料都有整理,送给每一位前端小伙伴, 有想学习web前端的,或是转行,或是大学生,还有工作中想提升自己能力的,正在学习的小伙伴欢迎加入学习。       加Q Q群:956940552(招...

weixin_43955769的博客 4144

前端开发中常用的几种设计模式

设计模式是什么? 首先设计模式和架构模式,还是开发模式完全是三种东西,从外到内理解: 开发模式: 常见的有四种开发模式,分别是敏捷开发、瀑布式开发、螺旋开发、迭代式开发,它是用于出于项目需求,在开发过程中秉承着一个什么样的原则进行开发,是需要考虑安全,还是偏向短期完成,或者是追求完美,它并不会直接约束我们如何写代码,而是代码应该秉持着完美,还是应该追求效率等等的原则进行开发。 架构模式: 确定好了开发模式,再来说架构模式,定义:一个架构模式描述软件系统里的基本的结构组织或纲要。架构模式提供一些呈先

shadowfall的博客 3330

web前端适合哪些人学习呢?如何才能快速入门前端?

  工作流程为从UI处得到原型图或者效果图,在项目(网站、微信公众号、小程序、WEBAPP)中还原图片效果,然后与后台进行各种数据交互。   目前的前端市场整体还是处于迅速发展期,市场对于前端的需求也一直比较大。   市场对于中高级的前端工程师需求更加迫切,所以就算入了前端的门,也需要不断的提升自己,无论你是学院派,还是培训派,还是自学派,都应该具有强烈的学习意识。   1、计算机相关专业出身   系统走过计算机的理论基础,比如计算机组成原理、操作系统原理、计算机网络、算法数据结构、设计模式,至

IT_studied的博客 211

软件方案常用设计模式介绍与交互 UI 前端手册

本文是一份面向产品经理、设计师和开发者的软件设计模式与前端交互规范手册。

b654381241的博客 243

VUE(一、VUE简介、快速入门

VUE是一套前端框架,免除了原生JavaScript中的DOM操作,简化书写VUE基于MVVM(Model-View_ViewModel)思想,实现数据双向绑定。

weixin_48841931的博客 11万+
上一篇: 新手如何搭建配置Android Studio并成功运行React Native项目(使用自带的虚拟机运行)
小简GoGo
博客等级 码龄10年 50粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值