📅  最后修改于: 2023-12-03 15:18:06.983000             🧑  作者: Mango
面向对象分析与设计(Object Oriented Analysis and Design,简称OOAD)是一种软件工程方法,旨在通过对象和类的概念来分析和设计系统。本文将介绍一些面向对象范例,帮助程序员更好地理解OOAD。
首先,我们来看一个图书管理系统的例子。该系统需要实现以下功能:
对于该系统,我们可以设计以下类:
public class User {
private String name;
private String password;
private List<Book> borrowedBooks;
public User(String name, String password) {
this.name = name;
this.password = password;
this.borrowedBooks = new ArrayList<>();
}
public String getName() {
return name;
}
public boolean checkPassword(String password) {
return this.password.equals(password);
}
public void borrowBook(Book book) {
borrowedBooks.add(book);
}
public void returnBook(Book book) {
borrowedBooks.remove(book);
}
public List<Book> getBorrowedBooks() {
return borrowedBooks;
}
}
public class Book {
private String title;
private String author;
private String isbn;
private boolean borrowed;
public Book(String title, String author, String isbn) {
this.title = title;
this.author = author;
this.isbn = isbn;
this.borrowed = false;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public String getIsbn() {
return isbn;
}
public boolean isBorrowed() {
return borrowed;
}
public void borrow() {
borrowed = true;
}
public void returnBook() {
borrowed = false;
}
}
public class Library {
private List<User> users;
private List<Book> books;
public Library() {
users = new ArrayList<>();
books = new ArrayList<>();
}
public void addUser(User user) {
users.add(user);
}
public void removeUser(User user) {
users.remove(user);
}
public User getUser(String name) {
for (User user : users) {
if (user.getName().equals(name)) {
return user;
}
}
return null;
}
public void addBook(Book book) {
books.add(book);
}
public void removeBook(Book book) {
books.remove(book);
}
public List<Book> search(String keyword) {
List<Book> result = new ArrayList<>();
for (Book book : books) {
if (book.getTitle().contains(keyword) ||
book.getAuthor().contains(keyword) ||
book.getIsbn().contains(keyword)) {
result.add(book);
}
}
return result;
}
public void lendBook(Book book, User user) {
if (!book.isBorrowed()) {
book.borrow();
user.borrowBook(book);
}
}
public void returnBook(Book book, User user) {
if (book.isBorrowed()) {
book.returnBook();
user.returnBook(book);
}
}
public List<Book> getBooks() {
return books;
}
public List<User> getUsers() {
return users;
}
}
我们再来看一个物理引擎的例子。该引擎需要支持以下功能:
对于该引擎,我们可以设计以下类:
public class Vector2D {
private double x;
private double y;
public Vector2D(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public double getLength() {
return Math.sqrt(x * x + y * y);
}
public Vector2D normalize() {
double length = getLength();
return new Vector2D(x / length, y / length);
}
public Vector2D add(Vector2D other) {
return new Vector2D(x + other.x, y + other.y);
}
public Vector2D subtract(Vector2D other) {
return new Vector2D(x - other.x, y - other.y);
}
public Vector2D multiply(double scalar) {
return new Vector2D(x * scalar, y * scalar);
}
public double dot(Vector2D other) {
return x * other.x + y * other.y;
}
public Vector2D project(Vector2D direction) {
double dot = dot(direction);
double length = direction.getLength();
return direction.multiply(dot / (length * length));
}
public Vector2D reflect(Vector2D normal) {
Vector2D incident = normalize();
Vector2D reflected = incident.subtract(normal.multiply(2 * incident.dot(normal)));
return reflected;
}
}
public class Particle {
private Vector2D position;
private Vector2D velocity;
private Vector2D acceleration;
private double mass;
public Particle(Vector2D position, Vector2D velocity, Vector2D acceleration, double mass) {
this.position = position;
this.velocity = velocity;
this.acceleration = acceleration;
this.mass = mass;
}
public Vector2D getPosition() {
return position;
}
public void setPosition(Vector2D position) {
this.position = position;
}
public Vector2D getVelocity() {
return velocity;
}
public void setVelocity(Vector2D velocity) {
this.velocity = velocity;
}
public Vector2D getAcceleration() {
return acceleration;
}
public void setAcceleration(Vector2D acceleration) {
this.acceleration = acceleration;
}
public double getMass() {
return mass;
}
public void setMass(double mass) {
this.mass = mass;
}
public void move(double dt) {
Vector2D delta = velocity.multiply(dt);
position = position.add(delta);
}
public void update(double dt) {
Vector2D deltaV = acceleration.multiply(dt);
velocity = velocity.add(deltaV);
Vector2D deltaP = velocity.multiply(dt);
position = position.add(deltaP);
}
public void applyForce(Vector2D force) {
Vector2D deltaA = force.multiply(1 / mass);
acceleration = acceleration.add(deltaA);
}
public void bounceOff(Particle other) {
Vector2D normal = other.getPosition().subtract(position).normalize();
Vector2D v1n = normal.project(velocity);
Vector2D v1t = velocity.subtract(v1n);
Vector2D v2n = normal.project(other.getVelocity());
Vector2D v2t = other.getVelocity().subtract(v2n);
Vector2D v1nNew = v2n;
Vector2D v2nNew = v1n;
Vector2D v1New = v1nNew.add(v1t);
Vector2D v2New = v2nNew.add(v2t);
velocity = v1New;
other.setVelocity(v2New);
}
}
public class Collision {
private Particle particle1;
private Particle particle2;
private double time;
public Collision(Particle particle1, Particle particle2, double time) {
this.particle1 = particle1;
this.particle2 = particle2;
this.time = time;
}
public Particle getParticle1() {
return particle1;
}
public Particle getParticle2() {
return particle2;
}
public double getTime() {
return time;
}
}
public class ParticleSystem {
private List<Particle> particles;
public ParticleSystem(List<Particle> particles) {
this.particles = particles;
}
public List<Particle> getParticles() {
return particles;
}
public void move(double dt) {
for (Particle particle : particles) {
particle.move(dt);
}
}
public List<Collision> detectCollisions() {
List<Collision> collisions = new ArrayList<>();
for (int i = 0; i < particles.size(); i++) {
Particle particle1 = particles.get(i);
for (int j = i + 1; j < particles.size(); j++) {
Particle particle2 = particles.get(j);
double time = predictCollisionTime(particle1, particle2);
if (time >= 0 && time <= 1) {
collisions.add(new Collision(particle1, particle2, time));
}
}
}
return collisions;
}
public void handleCollisions(List<Collision> collisions) {
for (Collision collision : collisions) {
Particle particle1 = collision.getParticle1();
Particle particle2 = collision.getParticle2();
double time = collision.getTime();
particle1.update(time);
particle2.update(time);
particle1.bounceOff(particle2);
}
}
public double predictCollisionTime(Particle particle1, Particle particle2) {
Vector2D deltaR = particle2.getPosition().subtract(particle1.getPosition());
Vector2D deltaV = particle2.getVelocity().subtract(particle1.getVelocity());
double sigma = particle1.getMass() + particle2.getMass();
double r = particle1.getRadius() + particle2.getRadius();
double a = deltaV.getLengthSquared();
double b = 2 * deltaR.dot(deltaV);
double c = deltaR.getLengthSquared() - r * r;
double delta = b * b - 4 * a * c;
if (delta >= 0) {
double time1 = (-b - Math.sqrt(delta)) / (2 * a);
double time2 = (-b + Math.sqrt(delta)) / (2 * a);
if (time1 >= 0 && time1 <= 1) {
return time1;
} else if (time2 >= 0 && time2 <= 1) {
return time2;
} else {
return -1;
}
} else {
return -1;
}
}
}
本文介绍了两个面向对象的范例,一个是图书管理系统,另一个是物理引擎。通过这些例子,我们可以看到面向对象的思想在实际开发中的应用。在设计类时,需要考虑类的属性和方法,并且要把类的职责分配清楚。只有设计出良好的类,才能写出易于维护、可复用的代码。