草庐IT

设计模式——行为型设计模式

不吃紫菜 2023-03-28 原文

行为型设计模式

针对对象之间的交互

解释器模式

java中用的很。JVM编译的时候就是对我们写的代码进行了解释操作;数据库SQL语句亦是如此

解释器:对语言进行解释,根据不同语义来做不同的事情。

举例:双栈计算器

public class 双栈实现计算器 {
    //设置两栈
    private static Deque<Character> opr = new LinkedList<>();
    private static Deque<Double> number = new LinkedList<>();

    public static void main(String[] args) {
        //接收一串字符串并转字符数组
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        char [] arrC = str.toCharArray();

        for (int i = 0; i < arrC.length;) {
            char c = arrC[i];
            //是+-/*字符时
            if (isChar(c)){
                ///如果栈内有字符,则需要判断优先级,入栈字符小于等于栈内字符则需要先计算栈内字符
                Character peek = opr.peek();    //细节!!! 这里必须先取
                while (peek!=null && isLowIn(c,peek)){
                    cal();
                    peek=opr.peek();       //细节!!这里也必须更新peek
                }
                //入栈
                opr.push(c);
                i++;
            }
            //字符是数字时
            else {
                double sum=0;   //接收整数和
                double sum2=0;  //接收小数和
                int times = 1;  //记录当前小数位数
                boolean flag=false; //是否开启小数检测模式

                //判断下一个是不是+-*/,不是的话就继续判断直到非数字
                while (i<=arrC.length-1 && !isChar(arrC[i])){       //细节:括号内两者顺序不能改变
                    //遇到小数的情况
                    if (arrC[i]=='.'){
                        flag=true;
                    }else {
                        //小数情况
                        if (flag){
                            double val=arrC[i]-'0';
                            for (int j = 0; j < times; j++) {   //细节!用times缩小值
                                val/=10.0;
                            }
                            times++;
                            sum2+=val;
                        }
                        //正数情况
                        else {
                            sum=sum*10+arrC[i]-'0';     //获取多位数字的关键!!!
                        }
                    }
                    i++;
                }
                number.push(sum+sum2);
            }
        }
        //字符都获取完了后栈内还有数字和字符的话,就计算完栈内的数据并输出最终结果
        while (!opr.isEmpty()) cal();
        System.out.println(number.peek());
    }

    //判断是否为字符
    public static boolean isChar(char c) {
        return c=='+'||c=='-'||c=='*'||c=='/';
    }

    //判断优先级是否是栈外字符小于等于栈内字符
    public static boolean isLowIn(char out,char in){
        return (out=='+'||out=='-')||(in=='*'||in=='/');
    }

    public static void cal(){
        //从栈内取出两个数组和一个字符
        double a = number.pop();
        double b = number.pop();
        char c = opr.poll();

        //根据字符c进行不同的运算
        switch (c){
            case '+':
                number.push(a+b);
                break;
            case '-':
                number.push(b-a);
                break;
            case '*':
                number.push(b*a);
                break;
            case '/':
                number.push(b/a);
                break;
            default:
                System.out.println("字符输入有误");
        }
    }

}

模板方法模式

在执行一类业务时前面有很多步骤都是相同时,就可以写一个模板抽象类,留出一个方法去给子类定义业务最后的操作。

该模式在源码中大量的被应用。这样写会给后期维护提供非常清晰的思路

举例:去医院看病,挂号和看医生是固定模式,但后面要不要开处方药和拿药是不一定的

//模板抽象类
/**
 * 抽象诊断方法,因为现在只知道挂号和看医生是固定模式,剩下的开处方和拿药都是不确定的
 */
public abstract class AbstractDiagnosis {

    public void test(){
        System.out.println("今天头好晕,不想起床,开摆,先跟公司请个假");
        System.out.println("去医院看病了~");
        System.out.println("1 >> 先挂号");
        System.out.println("2 >> 等待叫号");
        //由于现在不知道该开什么处方,所以只能先定义一下行为,然后具体由子类实现
      	//大致的流程先定义好就行
        this.prescribe();
        this.medicine();  //开药同理
    }

    public abstract void prescribe();   //开处方操作根据具体病症决定了

    public abstract void medicine();   //拿药也是根据具体的处方去拿
}

//实现具体业务的子类
/**
 * 感冒相关的具体实现子类
 */
public class ColdDiagnosis extends AbstractDiagnosis{
    @Override
    public void prescribe() {
        System.out.println("3 >> 一眼丁真,鉴定为假,你这不是感冒,纯粹是想摆烂");
    }

    @Override
    public void medicine() {
        System.out.println("4 >> 开点头孢回去吃吧");
    }
}

//主方法
public static void main(String[] args) {
    AbstractDiagnosis diagnosis = new ColdDiagnosis();
    diagnosis.test();
}

责任链模式

就像闯关,一层接一层的往下进行。可以理解为报销的时候需要一层一层审批

比如JavaWeb中学习的Filter过滤器,正是采用的责任链模式,通过将请求一级一级不断向下传递,来对我们所需要的请求进行过滤和处理。

举例:这里就使用责任链模式来模拟一个简单的面试过程,面试也是一面二面三面这样走的流程,这里先设计一下责任链上的各个处理器

//设计模板抽象方法,并在此基础上写层层往下的责任链
public abstract class Handler {

    protected Handler successor;    //这里我们就设计责任链以单链表形式存在,这里存放后继节点

    public Handler connect(Handler successor){     //拼接后续节点
        this.successor = successor;
        return successor;  //这里返回后继节点,方便我们一会链式调用
    }

    public void handle(){
        this.doHandle();   //由不同的子类实现具体处理过程
        Optional
                .ofNullable(successor)	//设置可以为null
                .ifPresent(Handler::handle);    //责任链上如果还有后继节点,就继续向下传递
    }

    public abstract void doHandle();   //结合上节课学习的模板方法,交给子类实现
}

//一面子类
public class FirstHandler extends Handler{   //用于一面的处理器
    @Override
    public void doHandle() {
        System.out.println("============= 白马程序员一面 ==========");
        System.out.println("1. 谈谈你对static关键字的理解?");
        System.out.println("2. 内部类可以调用外部的数据吗?如果是静态的呢?");
        System.out.println("3. hashCode()方法是所有的类都有吗?默认返回的是什么呢?");
        System.out.println("以上问题会的,可以依次打在评论区");
    }
}

//二面子类
public class SecondHandler extends Handler{  //二面
    @Override
    public void doHandle() {
        System.out.println("============= 白马程序员二面 ==========");
        System.out.println("1. 如果我们自己创建一个java.lang包并且编写一个String类,能否实现覆盖JDK默认的?");
        System.out.println("2. HashMap的负载因子有什么作用?变化规律是什么?");
        System.out.println("3. 线程池的运作机制是什么?");
        System.out.println("4. ReentrantLock公平锁和非公平锁的区别是什么?");
        System.out.println("以上问题会的,可以依次打在评论区");
    }
}

//三面子类
public class ThirdHandler extends Handler{
    @Override
    public void doHandle() {
        System.out.println("============= 白马程序员三面 ==========");
        System.out.println("1. synchronized关键字了解吗?如何使用?底层是如何实现的?");
        System.out.println("2. IO和NIO的区别在哪里?NIO三大核心组件?");
        System.out.println("3. TCP握手和挥手流程?少一次握手可以吗?为什么?");
        System.out.println("4. 操作系统中PCB是做什么的?运行机制是什么?");
        System.out.println("以上问题会的,可以依次打在评论区");
    }
}

//主方法
public static void main(String[] args) {
    Handler handler = new FirstHandler();  //一面首当其冲
    handler
            .connect(new SecondHandler())   //继续连接二面和三面
            .connect(new ThirdHandler());
    handler.handle();   //开始面试
} 

命令模式

命令模式,此时会有三个顶层行为:遥控器、命令、接收器。

话不多说,直接搬例。小米家具就是典型的命令模式。只需要在手机(遥控器)上通过红外线、蓝牙等按下一些命令,家中的家具(接收器)就会执行命令。

举例:设置三个顶层的 接口/抽象类 ,遥控器、命令、接收器

//遥控器
public class Controller {   //遥控器只需要把我们的指令发出去就行了
    public static void call(Command command){
        command.execute();
    }
}

//命令
public abstract class Command {   //指令抽象,不同的电器有指令

    private final Receiver receiver;

    protected Command(Receiver receiver){   //指定此命令对应的电器(接受者)
        this.receiver = receiver;
    }

    public void execute() {
        receiver.action();   //执行命令,实际上就是让接收者开始干活
    }
}

//接收器
public interface Receiver {
    void action();   //具体行为,这里就写一个算了
}

//具体接收器
public class AirConditioner implements Receiver{
    @Override
    public void action() {
        System.out.println("空调已开启,呼呼呼");
    }
}

//具体命令
public class OpenCommand extends Command {
    public OpenCommand(AirConditioner airConditioner) {
        super(airConditioner);
    }
}

//可以创建具体控制器(手机),也可以不创建直接遥控,因为控制器一般只有一个。所以这里就不创建了

//主方法
public static void main(String[] args) {
    AirConditioner airConditioner = new AirConditioner();   //先创建一个空调
    Controller.call(new OpenCommand(airConditioner));   //直接通过遥控器来发送空调开启命令
}

迭代器模式

每个集合类都有相应的迭代器。很少自定义,大都是用jdk定义好的迭代器

迭代器最直接的例子就是foreach语法糖。

public static void main(String[] args) {
    List<String> list = Arrays.asList("AAA", "BBB", "CCC");
    for (String s : list) {   //使用foreach语法糖进行迭代,依次获取每一个元素
        System.out.println(s);   //打印一下
    }
}

上述代码编译后的样子:

public static void main(String[] args) {
    List<String> list = Arrays.asList("AAA", "BBB", "CCC");
    Iterator var2 = list.iterator();   //实际上这里本质是通过List生成的迭代器来遍历我们每个元素的

    while(var2.hasNext()) {   //判断是否还有元素可以迭代,没有就false
        String s = (String)var2.next();   //通过next方法得到下一个元素,每调用一次,迭代器会向后移动一位
        System.out.println(s);    //打印一下
    }
}

由此可知迭代器原理:使用迭代器对List进行遍历时,实际上就像一个指向列表头部的指针,我们通过不断向后移动指针来依次获取所指向的元素:

拓展:自定义迭代器。

(由于每个迭代器需要根据不同的集合类特点来设计,所以自定义迭代器前需要自定义一个集合类)

//自定义集合类
public class ArrayCollection<T> {    //首先设计一个简单的数组集合,一会我们就迭代此集合内的元素

    private final T[] array;   //底层使用一个数组来存放数据

    private ArrayCollection(T[] array){   //private掉,自己用
        this.array = array;
    }

    public static <T> ArrayCollection<T> of(T[] array){   //开个静态方法直接吧数组转换成ArrayCollection,其实和直接new一样,但是这样写好看一点
        return new ArrayCollection<>(array);
    }
}

//自定义迭代器
public class ArrayCollection<T> implements Iterable<T>{   //实现Iterable接口表示此类是支持迭代的

    ...

    @Override
    public Iterator<T> iterator() {    //需要实现iterator方法,此方法会返回一个迭代器,用于迭代我们集合中的元素
        return new ArrayIterator();
    }

    public class ArrayIterator implements Iterator<T> {   //这里实现一个,注意别用静态,需要使用对象中存放的数组
        private int cur = 0;   //这里我们通过一个指针表示当前的迭代位置

        @Override
        public boolean hasNext() {     //判断是否还有下一个元素
            return cur < array.length;   //如果指针大于或等于数组最大长度,就不能再继续了
        }

        @Override
        public T next() {   //返回当前指针位置的元素并向后移动一位
            return array[cur++];   //正常返回对应位置的元素,并将指针自增
        }
    }
}

//主方法
public static void main(String[] args) {
    String[] arr = new String[]{"AAA", "BBB", "CCC", "DDD"};
    ArrayCollection<String> collection = ArrayCollection.of(arr);
    for (String s : collection) {    //可以直接使用foreach语法糖,当然最后还是会变成迭代器调用
        System.out.println(s);
    }
}

//编译主方法后的样子
public static void main(String[] args) {
    String[] arr = new String[]{"AAA", "BBB", "CCC", "DDD"};
    ArrayCollection<String> collection = ArrayCollection.of(arr);
    Iterator var3 = collection.iterator();   //首先获取迭代器,实际上就是调用我们实现的iterator方法

    while(var3.hasNext()) {
        String s = (String)var3.next();   //直接使用next()方法不断向下获取
        System.out.println(s);
    }
}

中介者模式

将多对多的复杂关系,变成一对多的简单明了关系

话不多说,直接上例子。中介,第一个想到的就是房子的中介。当一堆人需要出租房屋、另一堆人又需要租房,如果没有中介,那再好的房子很难遇上租客也租不出去,此时就需要一个中介将双方的需要进行匹配从而实现房子出租的目的。

不找中介:很乱,还不一定能够遇上需求相同的对方

找中介:中介将双方整理好,进行需求匹配

举例:中介、出租者、租房者

//中介
public class Mediator {   //房产中介
    private final Map<String, User> userMap = new HashMap<>();   //在出售的房子需要存储一下

    public void register(String address, User user){   //出售房屋的人,需要告诉中介他的房屋在哪里
        userMap.put(address, user);
    }

    public User find(String address){   //通过此方法来看看有没有对应的房源
        return userMap.get(address);
    }
}

//出租者和租房者(这里偷懒就写在一起了)
public class User {   //用户可以是出售房屋的一方,也可以是寻找房屋的一方
    String name;
    String tel;

    public User(String name, String tel) {
        this.name = name;
        this.tel = tel;
    }
  
    public User find(String address, Mediator mediator){   //找房子的话,需要一个中介和你具体想找的地方
        return mediator.find(address);
    }

    @Override
    public String toString() {
        return name+" (电话:"+tel+")";
    }
}

//主方法
public static void main(String[] args) {
    User user0 = new User("刘女士", "10086");   //出租者
    User user1 = new User("李先生", "10010");   //租房者
    Mediator mediator = new Mediator();   //我是中介

    mediator.register("广州市天河区白马程序员", user0);   //出租人先把房子给中介挂上去

    User user = user1.find("广州市天河区非马程序员", mediator);  //租房者向指定中介找房子
    if(user == null) System.out.println("没有找到对应的房源");
    System.out.println(user);   //成功找到对应房源
}

备忘录模式

我也称其为时光回溯模式。比较少用,大都是底层代码才用

这个备忘录不是我们平时用于记录容易忘记的ddl,而是保存曾经某个时刻的状态,后面有需要就恢复到该时刻的状态

举例:保存对象的状态

//对象实体
public class Student {
    private String currentWork;   //当前正在做的事情
    private int percentage;   //当前的工作完成百分比

    public void work(String currentWork) {
        this.currentWork = currentWork;
        this.percentage = new Random().nextInt(100);
    }

    @Override
    public String toString() {
        return "我现在正在做:"+currentWork+" (进度:"+percentage+"%)";
    }
    
    public State save(){
        return new State(currentWork, percentage);
    }

    public void restore(State state){
        this.currentWork = state.currentWork;
        this.percentage = state.percentage;
    }
}

//状态保存类
public class State {
    final String currentWork;
    final int percentage;

    State(String currentWork, int percentage) {   //仅开放给同一个包下的Student类使用
        this.currentWork = currentWork;
        this.percentage = percentage;
    }
}

//主方法
public static void main(String[] args) {
    Student student = new Student();
    student.work("学Java");   //开始学Java
    System.out.println(student);

    State savedState = student.save();   //保存一下当前的状态

    student.work("打电动");   //刚打开B站播放视频,学一半开始摆烂了
    System.out.println(student);

    student.restore(savedState);   //后悔浪费时间,回到上一个保存的状态
    System.out.println(student);   //回到学Java的状态
}

观察者模式

观察者模式可以实现监听器机制,当对象发生改变时,观察者能够立即察觉到并进行一些联动操作。很少用,大都是直接用监听器

举例:自定义观察者

//观察者接口
public interface Observer {   //观察者接口
    void update();   //当对象有更新时,会回调此方法
}

//支持观察者的实体
public class Subject {
    private final Set<Observer> observerSet = new HashSet<>();

    public void observe(Observer observer) {   //添加观察者
        observerSet.add(observer);
    }

    public void modify() {   //模拟对象进行修改
        observerSet.forEach(Observer::update);   //当对象发生修改时,会通知所有的观察者,并进行方法回调
    }
}

//主方法
public static void main(String[] args) {
    Subject subject = new Subject();
    subject.observe(() -> System.out.println("我是一号观察者!"));
    subject.observe(() -> System.out.println("我是二号观察者!"));
    subject.modify();
}

JDK也提供了是实现观察者模式的相关接口:

//继承接口表示支持观察者
import java.util.Observable;    //java.util包下提供的观察者抽象类

public class Subject extends Observable {   //继承此抽象类表示支持观察者

    public void modify(){
        System.out.println("对对象进行修改!");
        this.setChanged();    //当对对象修改后,需要setChanged来设定为已修改状态
        this.notifyObservers(new Date());   //使用notifyObservers方法来通知所有的观察者
      	//注意只有已修改状态下通知观察者才会有效,并且可以给观察者传递参数,这里传递了一个时间对象
    }
}

//主方法
public static void main(String[] args) {
    Subject subject = new Subject();
    subject.addObserver((o, arg) -> System.out.println("监听到变化,并得到参数:"+arg));  
  	//注意这里的Observer是java.util包下提供的
    subject.modify();   //进行修改操作
}

状态模式

根据不同的状态执行不同的行为

水在不同的温度状态会随之改变,程序也可以达到某种状态后就执行不同的行为

//枚举状态
public enum State {   //状态直接使用枚举定义
    NORMAL, LAZY
}

//实体类
public class Student {

    private State state;   //使用一个成员来存储状态

    public void setState(State state) {
        this.state = state;
    }

    public void study(){  
        switch (state) {   //根据不同的状态,学习方法会有不同的结果
            case LAZY:
                System.out.println("只要我不努力,老板就别想过上想要的生活,开摆!");
                break;
            case NORMAL:
                System.out.println("拼搏百天,我要上清华大学!");
                break;
        }
	}
}

//主方法
public static void main(String[] args) {
    Student student = new Student();
    student.setState(State.NORMAL);   //先正常模式
    student.study();

    student.setState(State.LAZY);   //开启摆烂模式
    student.study();
}

策略模式

和状态模式代码一样。但状态模式思想是:状态是先天的设定,就像水不同温度状态不同。而策略模式思想是:策略需要根据不同情况制定的。

举例:简单的数组排列

//策略接口(模板方法模式)
public interface Strategy {   //策略接口,不同的策略实现也不同

    Strategy SINGLE = Arrays::sort;   //单线程排序方案
    Strategy PARALLEL = Arrays::parallelSort;   //并行排序方案
    
    void sort(int[] array);
}

//排序类
public class Sorter {

    private Strategy strategy;   //策略

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public void sort(int[] array){
        strategy.sort(array);
    }
}

//主方法
public static void main(String[] args) {
    Sorter sorter = new Sorter();
    sorter.setStrategy(Strategy.PARALLEL);    //指定为并行排序方案
    
    sorter.sort(new int[]{9, 2, 4, 5, 1, 0, 3, 7});
}

访问者模式

一件事情,一个访问接口。访问者实现该接口,但不同访问者关心的事情着重点不同

举例:假如你获奖了还是国家级一等奖

//奖实体类
public class Prize {   //奖
    String name;   //比赛名称
    String level;    //等级

    public Prize(String name, String level) {
        this.name = name;
        this.level = level;
    }

    public String getName() {
        return name;
    }

    public String getLevel() {
        return level;
    }
}

//访问者接口
public interface Visitor {
    void visit(Prize prize);   //visit方法来访问我们的奖项
}

//不同访问者
public class Teacher implements Visitor {   //指导老师作为一个访问者
    @Override
    public void visit(Prize prize) {   //它只关心你得了什么奖以及是几等奖,这也关乎老师的荣誉
        System.out.println("你得奖是什么奖?"+prize.name);
        System.out.println("你得了几等奖?"+prize.level);
    }
}

public class Boss implements Visitor{    //你的公司老板作为一个访问者
    @Override
    public void visit(Prize prize) {   //你的老板只关心这些能不能为公司带来什么效益,奖本身并不重要
        System.out.println("你的奖项大么,能够为公司带来什么效益么?");
        System.out.println("还不如老老实实加班给我多干干,别去搞这些没用的");
    }
}

//主方法
public static void main(String[] args) {
    Prize prize = new Prize("ACM国际大学生程序设计竞赛","一等价");
	Teacher teacher = new Teacher();
    Boss boss = new Boss();
    teacher.visit(prize);
    boss.visit(prize);

}

有关设计模式——行为型设计模式的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  4. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  5. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  6. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  7. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  8. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  9. ruby - Ruby gsub 替换中的行为不一致? - 2

    两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio

  10. ruby-on-rails - Ruby 中意外的大小写行为 - 2

    我在一段非常简单的代码(如我所想)中得到了一个错误的值:org=4caseorgwhenorg=4val='H'endputsval=>nil请不要生气,我希望我错过了一些非常明显的东西,但我真的想不通。谢谢。 最佳答案 这是典型的Ruby错误。case有两种被调用的方法,一种是你传递一个东西作为分支的基础,另一种是你不传递的东西。如果您确实在case中指定了一个表达式语句然后评估所有其他条件并与===进行比较.在这种情况下org评估为false和org===false显然不是真的。所有其他情况也是如此,它们要么是真的,要么是假的。

随机推荐