一致性 黑马 没有 课程视频,
只能先看设计模式了,
先把快的看完,
一致性的比较零散,最后看,
设计模式,jvm,spring,springmvc,
接下来看这四个,速战速决,
设计模式这个东西,大学的时候,图书馆借书,java23种设计模式,拿回宿舍,跟着一个一个敲代码,
然后就没了,
现在算是复习吧,深入应用,学以致用,
也留下一个学习痕迹,
用了设计模式,反而 代码量变多,
4.设计模式,分类
创建型模式, 就是 负责 对象的 创建, 目的 是 把 对象的 创建 和使用 解耦,
就是 对象的 创建 这块代码 有重用性, 如果要改, 只需要修改一个地方,
这个没啥啊,实际工作经常用, 不就是函数封装么,还有代码重用,
五种 创建型模式,
单例最熟悉, 之前 juc 还讲到, 两次判断确认啥的,保证懒汉线程安全
还有很久以前就去 看啥 知道 这个 懒汉线程安全啥的, 还有王道好像也讲了,
其实这个东西,就是一个广度, 知道了, 知道咋回事, 不用记忆, 都是有现成代码,
懒汉的目的是 削峰填谷, 懒汉加线程安全是 多线程 临界情况 的观察考量,
之后的,工厂,抽象工厂,上次看过, 后者是前者的 缺点补充
最后的原型,建造者, 就有点忘记了,要看看了,
结构型模式
代理模式, 这个 好像 juc 也有讲,但是记不清了,像 事务注解失效, 好像要搞个代理啥的,
proxy 吧
适配器 adaptor?
装饰, 那个 java 的 多线程类 就有一堆是 装饰的? 都加了 sync 关键字装饰,是装饰模式么,
享元,这个好像也有点印象,模模糊糊,是juc 里边那种 共享资源 有关的东西么,
结构型,这个视频里说的很一般,
行为模式,
方法、策略,耳熟能详
职责链,观察者、迭代器、、、如雷贯耳、、
java23种设计模式
Java设计模式有很多种,通常被分为三大类:创建型模式、结构型模式、行为型模式。常见的设计模式有23种,它们是根据Gang of Four (GoF)(《设计模式:可复用面向对象软件的基础》)一书中的定义列举的。下面是这23种设计模式的分类和简介:
1. 创建型模式(Creational Patterns)
创建型模式主要关注对象的创建方式,目的是提高创建对象的灵活性和可复用性。
-
单例模式(Singleton Pattern)
- 确保一个类只有一个实例,并提供全局访问点。常用于配置类、日志类等。
-
工厂方法模式(Factory Method Pattern)
- 定义一个用于创建对象的接口,子类决定实例化哪个类。它允许子类延迟实例化对象。
-
抽象工厂模式(Abstract Factory Pattern)
- 提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定具体类。
-
建造者模式(Builder Pattern)
- 将一个复杂对象的构建过程分解成多个简单的步骤,从而可以使用不同的表示方式来构建对象。
-
原型模式(Prototype Pattern)
- 通过复制已有的实例来创建新的实例,而不是通过类的构造函数创建。
2. 结构型模式(Structural Patterns)
结构型模式关注如何组织和组合类或对象,以形成更大的结构。
-
适配器模式(Adapter Pattern)
- 将一个类的接口转换成客户端期望的另一个接口,使得不兼容的接口可以一起工作。
-
桥接模式(Bridge Pattern)
- 通过将抽象部分与实现部分分离,使得它们可以独立变化。它将接口和实现分离开来,避免了它们之间的紧耦合。
-
组合模式(Composite Pattern)
- 将对象组合成树形结构,以表示“部分-整体”的层次结构。客户可以一致地对待单个对象和组合对象。
-
装饰器模式(Decorator Pattern)
- 动态地给一个对象添加额外的职责,而不改变其结构。它是通过将对象包装在另一个对象中来实现的。
-
外观模式(Facade Pattern)
- 为子系统中的一组接口提供一个统一的高层接口,使得子系统更易使用。
-
享元模式(Flyweight Pattern)
- 使用共享对象来减少内存的使用,特别是当有大量相似对象时。通过共享对象的内部状态来避免重复创建。
-
代理模式(Proxy Pattern)
- 为其他对象提供一种代理以控制对这个对象的访问。代理对象可以是虚拟代理、远程代理、保护代理等。
3. 行为型模式(Behavioral Patterns)
行为型模式关注对象之间的交互和责任分配,确保对象之间的通信不会过于复杂。
-
责任链模式(Chain of Responsibility Pattern)
- 通过多个处理对象形成一条链,每个处理对象都有机会处理请求,避免请求的发送者与接收者之间的耦合。
-
命令模式(Command Pattern)
- 将请求封装成对象,从而使你可以用不同的请求对客户进行参数化;支持日志功能、撤销操作等。
-
解释器模式(Interpreter Pattern)
- 给定一个语言,定义一个文法,并通过解释器来解释句子。常用于DSL(领域特定语言)的实现。
-
迭代器模式(Iterator Pattern)
- 提供一种方法顺序访问一个集合对象中的各个元素,而不暴露该集合的内部表示。
-
中介者模式(Mediator Pattern)
- 用一个中介对象来封装一系列对象的交互。中介者使得各对象之间的耦合松散,减少了对象间的直接依赖。
-
备忘录模式(Memento Pattern)
- 在不暴露对象实现细节的情况下,保存对象的状态,并在以后恢复该状态。常用于撤销操作。
-
观察者模式(Observer Pattern)
- 定义对象间的一对多依赖关系,当一个对象的状态改变时,所有依赖于它的对象都会收到通知并自动更新。
-
状态模式(State Pattern)
- 允许一个对象在其内部状态改变时改变其行为。对象看起来好像修改了它的类。
-
策略模式(Strategy Pattern)
- 定义一系列算法,并将每个算法封装起来,使它们可以互换。策略模式使得算法可以独立于使用它的客户端变化。
-
模板方法模式(Template Method Pattern)
- 定义一个算法的框架,将某些步骤的实现延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下重定义算法的某些特定步骤。
-
访问者模式(Visitor Pattern)
- 允许你在不改变各元素类的前提下定义作用于这些元素的新操作。它将操作封装在访问者对象中,而不在元素类中实现。
总结
这23种设计模式提供了很多用于构建灵活、可维护、可扩展的面向对象系统的方案。它们涵盖了从对象的创建、结构的组织到行为的分配等各个方面。掌握这些设计模式可以帮助开发者更高效地解决开发中常见的复杂问题。
很快就能学完,23种,
结构模式
结构型设计模式(Structural Patterns)主要关注如何将类或对象组合成更大的结构,并保持良好的灵活性和可扩展性。结构型模式通过简化复杂的系统结构或解耦系统组件,增强了系统的可维护性和可复用性。它们一般通过合成(组合)已有对象来实现结构上的简化。
常见的结构型设计模式有以下几种:
1. 适配器模式(Adapter Pattern)
目的:将一个类的接口转换成客户端希望的另一个接口,使得不兼容的接口能够一起工作。
应用场景:
- 需要使用现有的类,但它的接口与系统的需求不兼容。
- 为第三方库、接口或类提供兼容层。
结构:
- Target(目标接口):客户端希望使用的接口。
- Adapter(适配器):将源类的接口转换成目标接口。
- Adaptee(被适配者):需要被适配的已有类。
例子: 假设有一个旧系统,使用的是 OldSystem 类,新的系统要求一个 NewSystem 接口。适配器可以充当转换器,将 OldSystem 的接口转成 NewSystem 所需的接口。
// 旧系统类
class OldSystem {
public void oldMethod() {
System.out.println("Using old method");
}
}
// 新系统接口
interface NewSystem {
void newMethod();
}
// 适配器类
class Adapter implements NewSystem {
private OldSystem oldSystem;
public Adapter(OldSystem oldSystem) {
this.oldSystem = oldSystem;
}
@Override
public void newMethod() {
oldSystem.oldMethod(); // 转调用旧方法
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
OldSystem oldSystem = new OldSystem();
NewSystem adapter = new Adapter(oldSystem);
adapter.newMethod();
}
}
2. 桥接模式(Bridge Pattern)
目的:将抽象部分与实现部分分离,使得它们可以独立变化。
应用场景:
- 需要在多个维度上进行扩展,而这些维度之间需要独立变化。
- 抽象部分(接口)和实现部分(具体类)是可变化的。
结构:
- Abstraction(抽象类):定义高层次的接口。
- RefinedAbstraction(扩充抽象类):实现或扩展抽象类的行为。
- Implementor(实现类):定义实现部分的接口。
- ConcreteImplementor(具体实现类):实现实现类接口的具体方法。
例子: 假设需要同时支持多种形状(如圆形和方形)和多种颜色(如红色和蓝色),可以使用桥接模式将形状和颜色独立扩展。
// 实现类
interface Color {
void fill();
}
// 具体实现类
class Red implements Color {
@Override
public void fill() {
System.out.println("Filling with red color");
}
}
class Blue implements Color {
@Override
public void fill() {
System.out.println("Filling with blue color");
}
}
// 抽象类
abstract class Shape {
protected Color color;
public Shape(Color color) {
this.color = color;
}
abstract void draw();
}
// 具体抽象类
class Circle extends Shape {
public Circle(Color color) {
super(color);
}
@Override
void draw() {
System.out.print("Drawing Circle. ");
color.fill();
}
}
class Square extends Shape {
public Square(Color color) {
super(color);
}
@Override
void draw() {
System.out.print("Drawing Square. ");
color.fill();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Shape redCircle = new Circle(new Red());
Shape blueSquare = new Square(new Blue());
redCircle.draw();
blueSquare.draw();
}
}
3. 组合模式(Composite Pattern)
目的:将对象组合成树形结构表示“部分-整体”层次结构。客户端可以一致地对待单个对象和组合对象。
应用场景:
- 需要处理树形结构的数据。
- 组合对象与单个对象需要具有统一的处理方式。
结构:
- Component(组件接口):定义所有对象的共同接口。
- Leaf(叶子节点):具体的基本对象,不能再被组合。
- Composite(组合节点):包含子节点的对象,可以包含叶子节点或其他组合节点。
例子: 假设需要在一个图形编辑系统中管理复杂的图形元素(如圆形、矩形等),组合模式可以将这些元素统一组织成一个树形结构。
// 组件接口
interface Graphic {
void draw();
}
// 叶子节点
class Circle implements Graphic {
@Override
public void draw() {
System.out.println("Drawing Circle");
}
}
class Rectangle implements Graphic {
@Override
public void draw() {
System.out.println("Drawing Rectangle");
}
}
// 组合节点
class CompositeGraphic implements Graphic {
private List<Graphic> graphics = new ArrayList<>();
public void add(Graphic graphic) {
graphics.add(graphic);
}
public void remove(Graphic graphic) {
graphics.remove(graphic);
}
@Override
public void draw() {
for (Graphic graphic : graphics) {
graphic.draw();
}
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Circle circle1 = new Circle();
Rectangle rectangle1 = new Rectangle();
CompositeGraphic compositeGraphic = new CompositeGraphic();
compositeGraphic.add(circle1);
compositeGraphic.add(rectangle1);
compositeGraphic.draw();
}
}
4. 装饰器模式(Decorator Pattern)
目的:动态地给一个对象添加额外的职责,而不改变其结构。
应用场景:
- 需要扩展类的功能,而不改变类的代码。
- 需要在运行时添加额外的功能。
结构:
- Component(组件接口):定义所有对象的共同接口。
- ConcreteComponent(具体组件):提供默认行为的类。
- Decorator(装饰器类):包装组件对象,并提供增强功能。
例子: 假设有一个基本的 Coffee 类,你可以使用装饰器模式添加额外的配料(如牛奶、糖等)。
// 组件接口
interface Coffee {
double cost();
}
// 具体组件
class SimpleCoffee implements Coffee {
@Override
public double cost() {
return 5;
}
}
// 装饰器类
abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
public abstract double cost();
}
// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double cost() {
return coffee.cost() + 1;
}
}
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double cost() {
return coffee.cost() + 0.5;
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
System.out.println("Cost of Simple Coffee: " + coffee.cost());
Coffee milkCoffee = new MilkDecorator(coffee);
System.out.println("Cost of Coffee with Milk: " + milkCoffee.cost());
Coffee milkSugarCoffee = new SugarDecorator(milkCoffee);
System.out.println("Cost of Coffee with Milk and Sugar: " + milkSugarCoffee.cost());
}
}
5. 外观模式(Facade Pattern)
目的:为子系统中的一组接口提供一个统一的高层接口,使得子系统更易使用。
应用场景:
- 需要简化复杂的系统接口,提供一个更容易使用的接口。
- 用于创建复杂系统的外部接口。
结构:
- Facade(外观类):为子系统提供简化的接口。
- Subsystem(子系统类):复杂的系统类,实际完成具体任务。
例子: 假设一个家庭影院系统,外观模式可以将多个子系统的操作简化为一个简单的调用接口。
外观模式(Facade Pattern)
外观模式(Facade Pattern)是一种结构型设计模式,目的是为子系统中的一组接口提供一个统一的高层接口,使得客户端可以通过这个高层接口与子系统进行交互,从而避免直接与复杂的子系统接口进行交互。外观模式的关键在于简化接口,隐藏复杂性,提高系统的易用性和可维护性。
主要目的:
- 简化接口:外观模式通过提供一个统一的接口,简化了客户端与系统的交互。
- 解耦:客户端不需要了解复杂子系统的内部结构和实现细节,从而实现系统和客户端的解耦。
- 提高可维护性:通过将子系统的复杂性封装在外观类中,系统的维护和扩展变得更加容易。
适用场景:
- 需要为复杂的子系统提供一个简单的接口。
- 客户端代码不希望暴露子系统的复杂性和细节。
- 系统中有多个子系统,且客户端需要与这些子系统交互,但希望减少与每个子系统交互的复杂性。
结构:
- Facade(外观类):提供统一的高层接口,简化子系统的操作。
- Subsystem(子系统类):子系统中实际执行操作的类,通常比较复杂,外部不需要直接与它们交互。
示例代码:
假设我们有一个家庭影院系统,包含多个子系统:音响放大器(Amplifier)、DVD播放器(DVDPlayer)和投影仪(Projector)。我们可以使用外观模式来简化客户端对这些子系统的使用。
// 子系统类:音响放大器
class Amplifier {
public void on() {
System.out.println("Amplifier on");
}
public void off() {
System.out.println("Amplifier off");
}
public void setVolume(int level) {
System.out.println("Amplifier volume set to " + level);
}
}
// 子系统类:DVD播放器
class DVDPlayer {
public void on() {
System.out.println("DVD Player on");
}
public void off() {
System.out.println("DVD Player off");
}
public void play(String movie) {
System.out.println("Playing movie: " + movie);
}
public void stop() {
System.out.println("Stopping movie");
}
}
// 子系统类:投影仪
class Projector {
public void on() {
System.out.println("Projector on");
}
public void off() {
System.out.println("Projector off");
}
public void focus() {
System.out.println("Projector focused");
}
}
// 外观类:家庭影院系统
class HomeTheaterFacade {
private Amplifier amplifier;
private DVDPlayer dvdPlayer;
private Projector projector;
public HomeTheaterFacade(Amplifier amplifier, DVDPlayer dvdPlayer, Projector projector) {
this.amplifier = amplifier;
this.dvdPlayer = dvdPlayer;
this.projector = projector;
}
public void watchMovie(String movie) {
System.out.println("Get ready to watch a movie...");
projector.on();
projector.focus();
amplifier.on();
amplifier.setVolume(5);
dvdPlayer.on();
dvdPlayer.play(movie);
}
public void endMovie() {
System.out.println("Shutting down movie...");
dvdPlayer.stop();
dvdPlayer.off();
amplifier.off();
projector.off();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
// 创建子系统对象
Amplifier amplifier = new Amplifier();
DVDPlayer dvdPlayer = new DVDPlayer();
Projector projector = new Projector();
// 创建外观对象
HomeTheaterFacade homeTheater = new HomeTheaterFacade(amplifier, dvdPlayer, projector);
// 使用外观模式简化操作
homeTheater.watchMovie("Inception");
System.out.println("\nMovie finished");
homeTheater.endMovie();
}
}
解释:
- 子系统类(
Amplifier、DVDPlayer、Projector):这些类代表了家庭影院中的不同设备,每个类负责其自身的操作(例如打开设备、调整音量、播放电影等)。 - 外观类(
HomeTheaterFacade):外观类简化了客户端对多个子系统的操作。它封装了多个子系统的复杂操作,通过提供一个统一的接口来简化客户端的交互。 - 客户端:客户端只需要与外观类进行交互,而不需要关心子系统的内部细节。
输出:
Get ready to watch a movie...
Projector on
Projector focused
Amplifier on
Amplifier volume set to 5
DVD Player on
Playing movie: Inception
Movie finished
Stopping movie
DVD Player off
Amplifier off
Projector off
总结:
-
优点:
- 简化客户端代码:客户端只需要与外观类交互,而不需要关心每个子系统的细节。
- 解耦:通过外观模式,客户端与复杂的子系统解耦,避免直接依赖子系统中的多个类。
- 更易维护:通过集中管理子系统的操作,系统的维护变得更加容易。如果需要更改某个子系统的行为,只需要修改外观类或子系统类,不影响其他部分。
-
缺点:
- 可能增加类的数量:引入外观类可能会增加系统中的类的数量。
- 可能过度简化:如果外观类处理的功能过于简单,可能会让一些客户端错失利用更复杂功能的机会。
总的来说,外观模式非常适合于大型系统中,尤其是那些有多个复杂子系统并且需要为客户端提供简化接口的场景。
5.设计模式,类图
这个很好理解
比如 java 有那个 集合框架,就是各种类图
还有 每个表 都会有一个实体类,
表跟表的关系,订单表,产品表, 用户表, 库存表,等等, 表和类图长得差不多
设计模式、类图和数据库表与实体类的关系在很多方面都有类似之处。我们可以通过类图来理解如何组织代码和设计系统,以及如何在数据库中通过表与表之间的关系来管理数据。接下来,我将详细解释如何将设计模式和数据库模型联系起来,并通过类图来阐述这个概念。
1. 类图和实体类
在面向对象的编程中,类图用于描述类之间的关系。每个类(例如 Java 中的类)通常会与数据库中的一张表对应,这些类的属性对应表中的字段,类的对象则对应数据库表中的一行记录。这个映射关系就是所谓的“实体类”。
举个例子:
假设有一个简单的电商系统,包含用户表、订单表和产品表。对应的类图可能长这样:
-
User 类(用户类)
- 属性:
userId、userName、email、password - 方法:
getUserDetails()、updateUserInfo()
- 属性:
-
Order 类(订单类)
- 属性:
orderId、userId、orderDate、totalAmount - 方法:
createOrder()、getOrderDetails()
- 属性:
-
Product 类(产品类)
- 属性:
productId、productName、price、quantity - 方法:
getProductDetails()、updateStock()
- 属性:
这些类的类图示例如下:
+----------------+ +----------------+ +----------------+
| User | | Order | | Product |
+----------------+ +----------------+ +----------------+
| - userId |<------| - orderId | | - productId |
| - userName | | - userId | | - productName |
| - email | | - orderDate | | - price |
| - password | | - totalAmount | | - quantity |
+----------------+ +----------------+ +----------------+
^ | | |
| +----------------------+---------------------+
|
+----------------+
| OrderDetails |
+----------------+
| - orderId |
| - productId |
| - quantity |
+----------------+
解释:
- User 类:代表用户信息,每个用户对应数据库中的一条记录。
- Order 类:代表订单,每个订单会包含一个用户 ID,说明该订单是由哪个用户创建的。
- Product 类:代表产品信息,每个产品在库存中都有相应记录。
- OrderDetails 类:代表订单详情,是一个多对多的关系表,连接了订单和产品。
2. 表与表之间的关系
在数据库中,表与表之间的关系可以通过外键来建立。例如:
- 用户表和订单表之间通常是一对多的关系,因为一个用户可以有多个订单。
- 订单表和产品表之间则是多对多的关系,一个订单可以包含多个产品,一个产品也可以出现在多个订单中,因此通常会通过一个中间表(如
OrderDetails)来维护这种关系。
3. 设计模式与类图
设计模式是一种通用的解决方案,用于解决软件设计中的常见问题。例如,单例模式、工厂模式、观察者模式等,都会通过类图的方式来表达。
举个例子:工厂模式
工厂模式用于创建对象,它定义了一个接口用于创建对象,但由子类决定实例化哪个类。工厂方法的类图通常会包含一个工厂接口类和多个具体工厂类。
+------------------+
| Product |
+------------------+
| +operation() |
+------------------+
^
|
+------------------+ +------------------+
| ConcreteProductA | | ConcreteProductB |
+------------------+ +------------------+
| +operation() | | +operation() |
+------------------+ +------------------+
^
|
+------------------+
| Creator |
+------------------+
| +factoryMethod() |
+------------------+
^
|
+------------------+
| ConcreteCreatorA |
+------------------+
| +factoryMethod() |
+------------------+
解释:
- Product 是产品的接口,具体产品(如
ConcreteProductA和ConcreteProductB)会实现该接口。 - Creator 是创建产品的抽象类或接口,具体工厂(如
ConcreteCreatorA)会实现创建不同产品的逻辑。
在这个例子中,我们可以通过类图明确看到工厂模式的结构如何通过继承和多态性实现产品的创建。
总结
- 类图:通过类和对象之间的关系(继承、关联、依赖等)来描述系统结构。每个表可以对应一个实体类,类的属性对应表的字段,类之间的关系(如一对多、多对多)也可以通过类图来表示。
- 数据库表和实体类:实体类是数据库表的面向对象表现,类图帮助我们直观地了解实体类及其之间的关系。
- 设计模式:设计模式为特定问题提供了通用的解决方案。每种设计模式都有其特定的类图结构,帮助我们理解如何在设计中解决常见的挑战。
通过类图和设计模式的结合,可以让我们在开发系统时更好地组织代码和数据结构,确保系统的可维护性和扩展性。
6.设计模式,类图 表示法
类图看着像 idea 里的 structure 视图
视频真的很垃圾,谁的 员工类 会有一个 work 方法? 你搞笑呢
一个简单的 Employee 类里如果有一个 work 方法,感觉确实有点不太合理。通常来说,Employee 类应该是描述员工的基本信息,比如姓名、职位、工龄等,而 work 这种方法更像是行为方法,应该放在一些可以具体执行任务的类中,比如 Manager 或者 Developer 类,而不是所有员工都有同样的 work 方法。
如果要做得更合乎设计原则,可以考虑以下几点:
1. 职责单一原则(SRP)
- 一个类应该只有一个明确的职责。
Employee类的职责是描述员工的属性,如果要有work方法,可能会打破这个职责。如果有多种类型的工作行为,可以通过接口或者抽象类来区分,比如IWorkable接口,让不同类型的员工类去实现各自的work方法。
2. 多态性
- 如果所有员工都有
work方法,可以通过多态来实现不同类型员工的不同工作方式。
- 这样,每个
Employee的子类可以根据自己的职责来实现work方法,避免Employee类变得过于庞大。
3. 避免不必要的方法
- 如果所有员工的行为都可以通过其他属性来管理(比如
status、hoursWorked等),可能根本不需要定义一个work方法,而是通过其他属性来表达工作状态。这会使设计更加简洁。
结论
类设计不够清晰或合理,往往是因为没有很好地理解类的职责和方法的合理分配。如果你遇到过这样的设计,可能是作者没有仔细考虑类的职责划分或者设计模式。设计时要遵循一些基本原则,比如单一职责、开放封闭原则等,这样类才能更具可扩展性和维护性。
员工类就是员工表的实体类,咋会有work 方法, 实体类只有 setter 和getter , 用 lombok 就搞定了
如果将 Employee 类作为一个简单的实体类,通常情况下它只是用来封装数据,比如员工的姓名、工号、职位等基本信息,那么是没有必要添加类似 work 这种方法的。实体类主要是为了存储和访问数据,通常会有属性的 getter 和 setter 方法,或者通过 Lombok 来简化这些冗长的代码。
在 Java 中,实体类通常没有太多的行为,而是用于持有数据。Lombok 是一个非常方便的工具,可以自动生成 getter、setter、toString、equals 和 hashCode 等常用方法,让代码变得更简洁、易于维护。
使用 Lombok 简化实体类
假设我们有一个 Employee 实体类,它可能包含如下属性:
import lombok.Data;
@Data
public class Employee {
private String name;
private String employeeId;
private String position;
private double salary;
// Lombok 会自动为所有字段生成 getter、setter、toString、equals 和 hashCode 方法
}
在这个例子中,@Data 注解会自动生成所有常用的 getter 和 setter 方法,以及 toString、equals 和 hashCode 方法。这样,你的代码就可以保持非常简洁。
为什么不应该在实体类里放 work 方法?
-
实体类职责单一:实体类主要的职责是持有数据,而不是执行操作。
work方法更像是一个行为,应该放在代表具体业务的服务类或者操作类中。例如,如果你有一个EmployeeService类,可能会在这里有assignWork或者manageWork等方法来处理工作相关的逻辑。 -
解耦和灵活性:如果
work方法加在Employee类里,你的实体类就开始承担过多的责任,违反了单一职责原则(SRP)。如果未来需要改变工作行为(比如员工需要做不同类型的工作),你可能需要修改实体类,而这通常会导致不必要的耦合和维护成本。
结论
"实体类只有 setter 和 getter" 这点非常正确,实体类不应该包含复杂的行为方法,而应该专注于数据存储。如果需要行为相关的逻辑,应该考虑将其放在服务类或其他业务逻辑层中。Lombok 确实可以让实体类变得更简洁,减少冗余代码,避免直接操作 getter 和 setter 的烦恼。
简而言之,实体类最好保持纯粹,只做数据存储,行为方法可以交给其他专门的类去处理。
你说 “有些类设计不够清晰或合理,往往是因为” , 你这句话里的 有些 和往往 , 这两个词, 组合在一起用,不合适吧?
在这句话中,"有些" 和 "往往" 组合使用确实有些不太合适。理由是“有些”表示的是一种相对较小的范围或特定的群体,而“往往”则强调的是一种普遍性或经常性的情况,这两个词在逻辑上略显矛盾。
如果要使句子更加清晰和准确,可以考虑这样修改:
- "有些类设计不够清晰或合理,是因为..."
这里强调的是一部分类,而不是普遍现象。
或者:
- "类设计不够清晰或合理,往往是因为..."
这样则更侧重于普遍的情况,即很多类可能都有设计不清晰或不合理的问题。
这两种修改都能避免“有些”和“往往”的语义冲突,表达也会更加清晰。




类图完全没有作用,我在实际工作中,完全用不到
“类图完全没有作用”是很多软件开发人员在面对实际项目时可能会有的感受。类图(Class Diagram)是面向对象设计中的一个重要工具,它帮助开发人员理清系统的结构,展示类与类之间的关系。理论上,它在系统设计阶段可以为后续的代码实现提供结构性的指导。但是,在实际开发中,类图的价值和作用有时可能不如预期。
下面我会讨论一些可能的原因,以及如何理解和利用类图:
1. 类图与实际开发的脱节
- 抽象程度过高:类图通常是抽象的,它只展示了类之间的关系和基本的属性、方法。这对于实际开发中的具体实现和细节可能过于简化,开发人员可能觉得它不够具体,甚至不容易直接用来指导代码编写。
- 快速迭代与灵活性:许多现代开发方法(比如敏捷开发、快速原型开发等)强调快速迭代和灵活变动。在这种模式下,过于依赖类图进行设计可能会显得有些僵化,因为需求和代码结构可能会快速变化,而类图却需要时间来更新。
2. 类图的作用不明显
- 实际代码与设计的偏差:在一些项目中,类图可能并没有很好地反映实际代码结构。开发人员可能在实现过程中根据需要进行重构,类图的设计就显得不那么有用。类图更适合在需求分析和初期设计阶段使用,但在持续开发过程中,实际的代码结构可能与最初的类图有很大出入。
- 没有与团队沟通结合:类图如果没有经过团队成员的详细讨论和理解,可能会变得“形式化”。例如,设计师和开发人员对类图的理解不同,导致它没有起到预期的作用。
3. 类图的局限性
- 无法表达行为:类图主要关注的是静态结构(即类及其关系),但实际开发中,业务逻辑的复杂性往往体现在行为层面(方法的实现、数据流动等)。类图无法很好地展示这些动态行为,反而可能会让开发人员感到它的用处不大。
- 与其他设计图的关系:在一些复杂的系统设计中,类图往往是其他图表(如时序图、活动图等)的基础。但如果缺乏对其他图表的综合使用,单独依赖类图可能会显得孤立无援。
4. 当类图确实有用的情境
尽管如此,类图在某些场合下仍然可以发挥重要作用,尤其是在以下几种情况:
- 大型系统的结构规划:类图可以帮助团队成员理解系统中各个模块、子系统之间的关系,特别是在团队成员较多或项目比较复杂时,类图可以作为一个有效的沟通工具。
- 接口设计和文档化:类图可以清晰地列出类的属性和方法,便于后期接口的设计和文档化,尤其是在面向接口编程时,它帮助定义公共接口和类之间的协作。
- 面向对象设计的思维工具:对于一些面向对象的设计模式和架构原则,类图有助于强化开发者对这些原则的理解,比如单一职责原则、开闭原则、继承、聚合等概念。
5. 如何使类图更加实用
- 与团队沟通:类图应该是团队协作的一部分,设计时要和开发人员、测试人员、项目经理等进行讨论,确保它真实反映系统设计需求。
- 结合其他图表使用:单独依赖类图可能会觉得它的用处有限,但如果结合其他图表(如时序图、用例图、活动图等)一起使用,可以让设计更加全面、动态和易于理解。
- 简化类图:对于一些较为复杂的系统,可以简化类图,只展示关键的类和重要的关系,避免过多的细节干扰开发人员的实际工作。
- 根据项目需要调整:如果你发现类图不适用,可以尝试在开发过程中调整设计方式,不必过度拘泥于它。对于一些敏捷开发的小项目,可以采用更轻量化的设计方法,如 CRC 卡、用户故事等,避免过度设计。
总结
类图作为面向对象设计的一部分,确实在一些开发环境中可能感觉不太有用,尤其是在快速变化的项目中。如果你在工作中发现类图的作用不大,可以尝试使用其他工具和方法,或者仅在项目的初期进行简单的类图设计。最重要的是,根据实际需求调整设计方式,不同的项目、团队和技术栈,可能需要不同的设计和沟通工具。
7.类图,关联关系
类跟类之间的关系
比如 mes 项目的 生产模块, 就有很多表, 表和表的关系, 外键字段啥的,
继承,接口实现类啥的, 类嵌套, 子类,啥的,
没啥好说的,过,
10.设计原则,开闭原则概述
很快就把设计模式干完,然后是 jvm , 然后是 spring 原理, springmvc 原理
干,干, 干,
这个视频也是水,完全的念稿子,我上我也行,
开闭原则,
实际工作,就是比如一个 业务功能要改, 一个 按钮 的 功能效果要改,
找到这个按钮的 实现方法, 然后 搞一个新的,而不是改旧的代码,然后调用新的封装方法,
这样就是开闭原则了,



设计模式的六大原则
1、开闭原则(Open Close Principle)
开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
2、里氏代换原则(Liskov Substitution Principle)
里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
3、依赖倒转原则(Dependence Inversion Principle)
这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。
4、接口隔离原则(Interface Segregation Principle)
这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。
5、迪米特法则,又称最少知道原则(Demeter Principle)
最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
6、合成复用原则(Composite Reuse Principle)
合成复用原则是指:尽量使用合成/聚合的方式,而不是使用继承。
6501

被折叠的 条评论
为什么被折叠?



