Java高级技术实验报告
实验3:结构型模式应用实验(2)
一、实验目的:
(1)了解7种结构型模式的定义、特点和工作原理。
(2)理解7种结构型模式的结构、实现和应用场景。
(3)学会应用7种结构型模式进行软件开发。
二、实验要求:
(1)体现相关设计模式的工作原理。
(2)尽量符合面向对象的七条设计原则。
(3)每个实例要有类图、源代码和运行结果。
三、实验内容:
1、假设客户在某系统使用中根据需要会使用不同的数据库进行数据存储。需要访问的数据库有Oracle、SQL Server、MySQL,使用桥接模式可以根据客户的需求动态切换不同的数据源。试编程模拟实现这个场景。
(1)类图
(2)实验结果
(3)实验代码
package com.shiyan1;
public class Client {
public static void main(String[] args) {
Database oracleDb = new OracleDatabase();
Database sqlServerDb = new SqlServerDatabase();
Database mySqlDb = new MySqlDatabase();
DataAccess oracleDataAccess = new OracleDataAccess(oracleDb);
DataAccess sqlServerDataAccess = new SqlServerDataAccess(sqlServerDb);
DataAccess mySqlDataAccess = new MySqlDataAccess(mySqlDb);
System.out.println("使用 Oracle database...");
oracleDataAccess.connect();
oracleDataAccess.query("SELECT * FROM Customers");
oracleDataAccess.disconnect();
System.out.println("*******************************************");
System.out.println("使用 SQL Server database...");
sqlServerDataAccess.connect();
sqlServerDataAccess.query("SELECT * FROM Orders");
sqlServerDataAccess.disconnect();
System.out.println("*******************************************");
System.out.println("使用 MySQL database...");
mySqlDataAccess.connect();
mySqlDataAccess.query("SELECT * FROM Products");
mySqlDataAccess.disconnect();
}
}
package com.shiyan1;
public abstract class DataAccess {
protected Database db;
public abstract void connect();
public abstract void disconnect();
public abstract void query(String sql);
}
package com.shiyan1;
public interface Database {
void connect();
void disconnect();
void query(String sql);
}
package com.shiyan1;
public class MySqlDataAccess extends DataAccess {
public MySqlDataAccess(Database db) {
this.db = db;
}
@Override
public void connect() {
db.connect();
}
@Override
public void disconnect() {
db.disconnect();
}
@Override
public void query(String sql) {
db.query(sql);
}
}
package com.shiyan1;
public class MySqlDatabase implements Database {
@Override
public void connect() {
System.out.println("连接 MySQL 数据库...");
}
@Override
public void disconnect() {
System.out.println("断开MySQL 数据库...");
}
@Override
public void query(String sql) {
System.out.println("在MySQL数据库中执行查询: " + sql);
}
}
package com.shiyan1;
public class OracleDataAccess extends DataAccess {
public OracleDataAccess(Database db) {
this.db = db;
}
@Override
public void connect() {
db.connect();
}
@Override
public void disconnect() {
db.disconnect();
}
@Override
public void query(String sql) {
db.query(sql);
}
}
package com.shiyan1;
public class OracleDatabase implements Database {
@Override
public void connect() {
System.out.println("连接 Oracle 数据库...");
}
@Override
public void disconnect() {
System.out.println("断开Oracle 数据库...");
}
@Override
public void query(String sql) {
System.out.println("在Oracle数据库中执行查询: " + sql);
}
}
package com.shiyan1;
public class SqlServerDataAccess extends DataAccess {
public SqlServerDataAccess(Database db) {
this.db = db;
}
@Override
public void connect() {
db.connect();
}
@Override
public void disconnect() {
db.disconnect();
}
@Override
public void query(String sql) {
db.query(sql);
}
}
package com.shiyan1;
public class SqlServerDatabase implements Database {
@Override
public void connect() {
System.out.println("连接 SQL Server数据库...");
}
@Override
public void disconnect() {
System.out.println("断开SQL Server 数据库...");
}
@Override
public void query(String sql) {
System.out.println("在SQL Server数据库中执行查询: " + sql);
}
}
2、设计一个“人”类,再使用装饰模式赋予“人”类更强大的本领如“天上飞”、“水下游”以及“力如牛”等而成为“超人”。试编程实现这个场景。
(1)类图
(2)实验结果
(3)实验代码
package com.shiyan2;
public class Client {
public static void main(String[] args) {
// 创建一个普通人对象
Person person = new ConcretePerson("小明");
person.show(); // 输出 "我是 小明"
// 给人对象增加飞行能力
Person flyingPerson = new FlyingDecorator(person);
flyingPerson.show(); // 输出 "我是 小明" 和 "我可以在天上飞"
// 给人对象增加游泳能力
Person swimmingPerson = new SwimmingDecorator(person);
swimmingPerson.show(); // 输出 "我是 小明" 和 "我可以在水下游"
// 给人对象增加强壮能力
Person strongPerson = new StrongDecorator(person);
strongPerson.show(); // 输出 "我是 小明" 和 "我力大无穷,可以举起一头牛"
// 给人对象同时增加飞行和强壮能力
Person flyingStrongPerson = new FlyingDecorator(new StrongDecorator(person));
flyingStrongPerson.show(); // 输出 "我是 小明"、"我力大无穷,可以举起一头牛" 和 "我可以在天上飞"
}
}
package com.shiyan2;
public class ConcretePerson implements Person {
private String name;
public ConcretePerson(String name) {
this.name = name;
}
@Override
public void show() {
System.out.println("我是 " + name);
}
}
package com.shiyan2;
public class FlyingDecorator extends PersonDecorator {
public FlyingDecorator(Person person) {
super(person);
}
@Override
public void show() {
person.show();
fly();
}
private void fly() {
System.out.println("我可以在天上飞");
}
}
package com.shiyan2;
public interface Person {
void show();
}
package com.shiyan2;
public abstract class PersonDecorator implements Person {
protected Person person;
public PersonDecorator(Person person) {
this.person = person;
}
}
package com.shiyan2;
public class StrongDecorator extends PersonDecorator {
public StrongDecorator(Person person) {
super(person);
}
@Override
public void show() {
person.show();
strong();
}
private void strong() {
System.out.println("我力大无穷,可以举起一头牛");
}
}
package com.shiyan2;
public class SwimmingDecorator extends PersonDecorator {
public SwimmingDecorator(Person person) {
super(person);
}
@Override
public void show() {
person.show();
swim();
}
private void swim() {
System.out.println("我可以在水下游");
}
}
三、实验心得:
我认为桥接模式的核心思想是将抽象与实现分离,使它们可以独立地变化。这种设计模式能够将一个大类或一系列紧密相关的类拆分成两个独立的层次结构,从而更好地应对需求变化。在这个具体的场景中,我们可以将不同的数据库抽象成一个接口,并在接口中定义了几个基本的数据库操作。然后,我们再定义一个桥接类,用于将不同的数据库和具体的数据库操作连接起来。这样,客户端可以根据需要动态地切换不同的数据库,而不需要关心数据库的具体实现。
我认为装饰模式的核心思想是动态地给对象增加新的职责,而不需要修改对象本身。这种设计模式能够避免继承带来的类爆炸问题,同时还可以让对象具有更高的灵活性和扩展性。在这个具体的场景中,我们可以将人对象作为一个基础的类,并定义一个人的基本属性和方法。然后,我们再定义一些装饰器类,用于给人对象增加新的能力,如飞行、游泳、强壮等。每个装饰器都包含一个被装饰的对象,并在该对象的基础上增加新的能力。这样,客户端可以动态地给人对象增加不同的装饰器,从而让人对象具有不同的能力,而不需要修改人对象本身。
桥接模式和装饰模式都是比较常用的设计模式,在实际的软件开发中也经常会被用到。熟练掌握这些设计模式可以帮助我们更好地设计和开发软件,从而提高软件的可维护性、可扩展性和可重用性。