如果按代码量算工资,也许应该这样写!

来源:juejin.cn/post/7263760831052906552

  • 前言

  • 正文

    • 实现更多的接口

    • 重写 equals 和 hashcode 方法

    • 增加配置项和参数

    • 增加监听回调

    • 构建通用工具类

    • 添加新的异常类型

    • 实现更多设计模式

    • 扩展注释和文档

  • 结语


如果按代码量算工资,也许应该这样写!

前言

假如有一天我们要按代码量来算工资,那怎样才能写出一手漂亮的代码,同时兼顾代码行数和实际意义呢?

要在增加代码量的同时提高代码质量和可维护性,能否做到呢?

答案当然是可以,这可难不倒我们这种摸鱼高手。

耐心看完,你一定有所收获。

e8354d10c1460cb864a171701ec4280f.png

正文

实现更多的接口

给每一个方法都实现各种“无关痛痒”的接口,比如SerializableCloneable等,真正做到不影响使用的同时增加了相当数量的代码。

为了这些代码量,其中带来的性能损耗当然是可以忽略的。

public class ExampleClass implements Serializable, Comparable<ExampleClass>, Cloneable, AutoCloseable {

  @Override
  public int compareTo(ExampleClass other) {
    // 比较逻辑
    return 0;
  }

  // 实现 Serializable 接口的方法
  private void writeObject(ObjectOutputStream out) throws IOException {
    // 序列化逻辑
  }

  private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    // 反序列化逻辑
  }

  // 实现 Cloneable 接口的方法
  @Override
  public ExampleClass clone() throws CloneNotSupportedException {
    // 复制对象逻辑
    return (ExampleClass) super.clone();
  }

  // 实现 AutoCloseable 接口的方法
  @Override
  public void close() throws Exception {
    // 关闭资源逻辑
  }

}

除了示例中的SerializableComparableCloneableAutoCloseable,还有Iterable

重写 equals 和 hashcode 方法

重写 equalshashCode 方法绝对是上上策,不仅增加了代码量,还为了让对象在相等性判断和散列存储时能更完美的工作,确保代码在处理对象相等性时更准确、更符合业务逻辑。

public class ExampleClass {
  private String name;
  private int age;

  // 重写 equals 方法
  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }

    if (obj == null || getClass() != obj.getClass()) {
      return false;
    }

    ExampleClass other = (ExampleClass) obj;
    return this.age == other.age && Objects.equals(this.name, other.name);
  }

  // 重写 hashCode 方法
  @Override
  public int hashCode() {
    return Objects.hash(name, age);
  }
}

c8d19e610313051e465b1c5cc6728387.gif

增加配置项和参数

不要管能不能用上,梭哈就完了,问就是为了健壮性和拓展性。

public class AppConfig {
  private int maxConnections;
  private String serverUrl;
  private boolean enableFeatureX;

  // 新增配置项
  private String emailTemplate;
  private int maxRetries;
  private boolean enableFeatureY;

  // 写上构造函数和getter/setter
}

增加监听回调

给业务代码增加监听回调,比如执行前、执行中、执行后等各种Event,这里举个完整的例子。

比如创建个 EventListener ,负责监听特定类型的事件,事件源则是产生事件的对象。通过EventListener 在代码中增加执行前、执行中和执行后的事件。

首先,我们定义一个简单的事件类 Event

public class Event {
  private String name;

  public Event(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }
}

然后,我们定义一个监听器接口 EventListener

public interface EventListener {
  void onEventStart(Event event);

  void onEventInProgress(Event event);

  void onEventEnd(Event event);
}

接下来,我们定义一个事件源类 EventSource,在执行某个业务方法时,触发事件通知:

public class EventSource {
  private List<EventListener> listeners = new ArrayList<>();

  public void addEventListener(EventListener listener) {
    listeners.add(listener);
  }

  public void removeEventListener(EventListener listener) {
    listeners.remove(listener);
  }

  public void businessMethod() {
    Event event = new Event("BusinessEvent");

    // 通知监听器:执行前事件
    for (EventListener listener : listeners) {
      listener.onEventStart(event);
    }

    // 模拟执行业务逻辑
    System.out.println("Executing business method...");

    // 通知监听器:执行中事件
    for (EventListener listener : listeners) {
      listener.onEventInProgress(event);
    }

    // 模拟执行业务逻辑
    System.out.println("Continuing business method...");

    // 通知监听器:执行后事件
    for (EventListener listener : listeners) {
      listener.onEventEnd(event);
    }
  }
}

现在,我们可以实现具体的监听器类,比如 BusinessEventListener,并在其中定义事件处理逻辑:

public class BusinessEventListener implements EventListener {
  @Override
  public void onEventStart(Event event) {
    System.out.println("Event Start: " + event.getName());
  }

  @Override
  public void onEventInProgress(Event event) {
    System.out.println("Event In Progress: " + event.getName());
  }

  @Override
  public void onEventEnd(Event event) {
    System.out.println("Event End: " + event.getName());
  }
}

最后,我们写个main函数来演示监听事件:

public class Main {
  public static void main(String[] args) {
    EventSource eventSource = new EventSource();
    eventSource.addEventListener(new BusinessEventListener());

    // 执行业务代码,并触发事件通知
    eventSource.businessMethod();

    // 移除监听器
    eventSource.removeEventListener(businessEventListener);
  }
}

如此这般那般,代码量猛增,还顺带实现了业务代码的流程监听。当然这只是最简陋的实现,真实环境肯定要比这个复杂的多。

构建通用工具类

同样的,甭管用不用的上,定义更多的方法,都是为了健壮性。

比如下面这个StringUtils,可以从ApacheCommons、SpringBoot的StringUtil或HuTool的StrUtil中拷贝更多的代码过来,美其名曰内部工具类。

public class StringUtils {
  public static boolean isEmpty(String str) {
    return str == null || str.trim().isEmpty();
  }

  public static boolean isBlank(String str) {
    return str == null || str.trim().isEmpty();
  }

  // 新增方法:将字符串反转
  public static String reverse(String str) {
    if (str == null) {
      return null;
    }
    return new StringBuilder(str).reverse().toString();
  }

  // 新增方法:判断字符串是否为整数
  public static boolean isInteger(String str) {
    try {
      Integer.parseInt(str);
      return true;
    } catch (NumberFormatException e) {
      return false;
    }
  }
}

添加新的异常类型

添加更多异常类型,对不同的业务抛出不同的异常,每种异常都要单独去处理

public class CustomException extends RuntimeException {
  // 构造函数
  public CustomException(String message) {
    super(message);
  }

  // 新增异常类型
  public static class NotFoundException extends CustomException {
    public NotFoundException(String message) {
      super(message);
    }
  }

  public static class ValidationException extends CustomException {
    public ValidationException(String message) {
      super(message);
    }
  }
}
// 示例:添加不同类型的异常处理
public class ExceptionHandling {
  public void process(int value) {
    try {
      if (value < 0) {
        throw new IllegalArgumentException("Value cannot be negative");
      } else if (value == 0) {
        throw new ArithmeticException("Value cannot be zero");
      } else {
        // 正常处理逻辑
      }
    } catch (IllegalArgumentException e) {
      // 异常处理逻辑
    } catch (ArithmeticException e) {
      // 异常处理逻辑
    }
  }
}

实现更多设计模式

在项目中运用更多设计模式,也不失为一种合理的方式,比如单例模式、工厂模式、策略模式、适配器模式等各种常用的设计模式。

比如下面这个单例,大大节省了内存空间,虽然它存在线程不安全等问题。

public class SingletonPattern {
  // 单例模式
  private static SingletonPattern instance;

  private SingletonPattern() {
    // 私有构造函数
  }

  public static SingletonPattern getInstance() {
    if (instance == null) {
      instance = new SingletonPattern();
    }
    return instance;
  }

}

还有下面这个策略模式,能避免过多的if-else条件判断,降低代码的耦合性,代码的扩展和维护也变得更加容易。

// 策略接口
interface Strategy {
  void doOperation(int num1, int num2);
}

// 具体策略实现类
class AdditionStrategy implements Strategy {
  @Override
  public void doOperation(int num1, int num2) {
    int result = num1 + num2;
    System.out.println("Addition result: " + result);
  }
}

class SubtractionStrategy implements Strategy {
  @Override
  public void doOperation(int num1, int num2) {
    int result = num1 - num2;
    System.out.println("Subtraction result: " + result);
  }
}

// 上下文类
class Context {
  private Strategy strategy;

  public Context(Strategy strategy) {
    this.strategy = strategy;
  }

  public void executeStrategy(int num1, int num2) {
    strategy.doOperation(num1, num2);
  }
}

// 测试类
public class StrategyPattern {
  public static void main(String[] args) {
    int num1 = 10;
    int num2 = 5;

    // 使用加法策略
    Context context = new Context(new AdditionStrategy());
    context.executeStrategy(num1, num2);

    // 使用减法策略
    context = new Context(new SubtractionStrategy());
    context.executeStrategy(num1, num2);
  }
}

对比下面这段条件判断,高下立判。

public class Calculator {
  public static void main(String[] args) {
    int num1 = 10;
    int num2 = 5;
    String operation = "addition"; // 可以根据业务需求动态设置运算方式

    if (operation.equals("addition")) {
      int result = num1 + num2;
      System.out.println("Addition result: " + result);
    } else if (operation.equals("subtraction")) {
      int result = num1 - num2;
      System.out.println("Subtraction result: " + result);
    } else if (operation.equals("multiplication")) {
      int result = num1 * num2;
      System.out.println("Multiplication result: " + result);
    } else if (operation.equals("division")) {
      int result = num1 / num2;
      System.out.println("Division result: " + result);
    } else {
      System.out.println("Invalid operation");
    }
  }
}

扩展注释和文档

如果要增加代码量,写更多更全面的注释也不失为一种方式。

/**
 * 这是一个示例类,用于展示增加代码数量的技巧和示例。
 * 该类包含一个示例变量 value 和示例构造函数 ExampleClass(int value)。
 * 通过示例方法 getValue() 和 setValue(int newValue),可以获取和设置 value 的值。
 * 这些方法用于展示如何增加代码数量,但实际上并未实现实际的业务逻辑。
 */
public class ExampleClass {

  // 示例变量
  private int value;

  /**
   * 构造函数
   */
  public ExampleClass(int value) {
    this.value = value;
  }

  /**
   * 获取示例变量 value 的值。
   * @return 示范变量 value 的值
   */
  public int getValue() {
    return value;
  }

  /**
   * 设置示例变量 value 的值。
   * @param newValue 新的值,用于设置 value 的值。
   */
  public void setValue(int newValue) {
    this.value = newValue;
  }
}

结语

哪怕是以代码量算工资,咱也得写出高质量的代码,合理合法合情的赚票子。

fbaac1b8081b2d73fb864dcb774cbc0c.png

推荐阅读:

被 GPT-4 Plus 账号价格劝退了!

世界的真实格局分析,地球人类社会底层运行原理

不是你需要中台,而是一名合格的架构师(附各大厂中台建设PPT)

企业IT技术架构规划方案

论数字化转型——转什么,如何转?

华为干部与人才发展手册(附PPT)

【中台实践】华为大数据中台架构分享.pdf

华为的数字化转型方法论

华为如何实施数字化转型(附PPT)

华为大数据解决方案(PPT)

1bc05b8c94f3f220a2b6296bcd2e5979.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的职工工作统计系统的代码,使用了链表来存储职工信息: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> // 职工结构体 typedef struct Employee { char name[20]; // 姓名 int work_hours; // 工作时长 int salary; // 工资 struct Employee *next; // 指向下一个职工的指针 } Employee; // 添加职工函数 void add_employee(Employee **head) { Employee *new_employee = (Employee *)malloc(sizeof(Employee)); printf("请输入职工姓名:"); scanf("%s", new_employee->name); printf("请输入职工工作时长:"); scanf("%d", &new_employee->work_hours); new_employee->salary = new_employee->work_hours * 100; // 简单计工资 new_employee->next = *head; // 新职工指向原头节点 *head = new_employee; // 新职工成为新的头节点 } // 显示所有职工信息函数 void show_employees(Employee *head) { printf("所有职工信息如下:\n"); Employee *current_employee = head; while (current_employee != NULL) { printf("姓名:%s\t工作时长:%d小时\t工资:%d元\n", current_employee->name, current_employee->work_hours, current_employee->salary); current_employee = current_employee->next; // 移动到下一个职工节点 } } // 统计工资总额函数 int calculate_total_salary(Employee *head) { int total_salary = 0; Employee *current_employee = head; while (current_employee != NULL) { total_salary += current_employee->salary; current_employee = current_employee->next; // 移动到下一个职工节点 } return total_salary; } int main() { Employee *head = NULL; // 头节点初始化为 NULL int choice; do { printf("\n请选择操作:\n"); printf("1. 添加职工信息\n"); printf("2. 显示所有职工信息\n"); printf("3. 统计工资总额\n"); printf("4. 退出程序\n"); scanf("%d", &choice); switch (choice) { case 1: add_employee(&head); break; case 2: show_employees(head); break; case 3: printf("工资总额为:%d元\n", calculate_total_salary(head)); break; case 4: printf("程序已退出。\n"); break; default: printf("无效的选择,请重新选择。\n"); } } while (choice != 4); // 释放内存 Employee *current_employee = head; while (current_employee != NULL) { Employee *next_employee = current_employee->next; free(current_employee); current_employee = next_employee; } return 0; } ``` 这个程序使用了一个 `Employee` 结构体来存储每个职工的信息,包括姓名、工作时长和工资。链表的头节点 `head` 初始化为 `NULL`,每次添加新职工时,新节点会成为新的头节点,而原来的头节点则成为新节点的下一个节点。在显示所有职工信息、统计工资总额等操作中,程序会遍历整个链表来访问每个职工节点的信息。当程序退出时,需要释放链表中所有的节点内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值