文章目录
- 设计模式大作业
- 软 件 设 计 模 式 任 务 书
- 设计要求:
- 学生应完成的工作:
- 1. 应用场景描述
- 2. 设计模式选择
- 3. 实现语言与工具
- 参考文献阅读:
- 工作计划:
- 一、系统目标
- 1. 设计目的
- 2. 需求描述
- 二、 系统模式选择
- 1.需求分析
- 2.选用设计模式
- 1. 系统功能模块设计
- 2. 系统模块类图
- 3. 系统控制函数
- 三、 系统实现
- 3.1 Agent.java
- 3.2 AgentFrame.java
- 3.3 DeliverGoods.java
- 3.4 DeliverMethod.java
- 3.5 Express.java
- 3.7 Coca_Cola.java
- 3.8 Coca_ColaFactory.java
- 3.9 Coke.java
- 3.10 CokeFactory.java
- 3.11 Pepsi.java
- 3.12 PepsiFactory.java
- 3.13 Coca_ColaCompany.java
- 3.14 PepsiCompany.java
- 3.15 Order.java
- 3.16 OrderBuidler.java
- 3.17 Test.java
- 3.18 Message.java
- 3.19 Recipient.java
- 四、 系统测试
- 五、总结
- 1. 实现的功能和优点
- 2. 完成心得
- 题外话:
设计模式大作业
课程名称: 软件设计模式
设计题目: 可乐商城管理系统
软 件 设 计 模 式 任 务 书
设计要求:
1.设计一个应用场景,最少使用所学过的三种设计模式解决一个实际问题。一人一题,不可重复。
2.应用场景设计要合理,模式选择要适当。
3.要求给出系统模式结构图,主要类的设计代码。
4.编写验证程序,在验证程序中要在显著位置显示个人信息。
学生应完成的工作:
1. 应用场景描述
本系统模拟可乐代理商从进货到可乐公司生产发货以及销售给顾客的整个过程。可细分为以下三个部分:
(1)可乐代理商选择进货,同时发送邮件通知可乐公司
(2)可乐公司生产可乐,及时发货并提醒代理商收货
(3)顾客购买可乐,选择拿货方式,并生成订单
2. 设计模式选择
共使用了5种设计模式,分别是原型模式、单例模式、抽象工厂模式、代理模式、建造者模式。
3. 实现语言与工具
实现语言:Java
使用工具:idea
参考文献阅读:
①设计模式(第二版) 清华大学出版社 刘伟
②Java设计模式及实践 机械工业出版社 卡玛尔米特.辛格
③Java设计模式 清华大学出版社 刘伟
④传智播客
⑤CSDN网
工作计划:
- 审题,查阅资料,进行设计前的必要资料准备(3天)。
- 把程序完整运行出来(4天)。
- 增加改进程序(3天)。
- 写课程设计报告(3天)。
- 提交课程设计报告(1天)。
任务下达日期: 2021 年 6 月 3 日
任务完成日期: 2021 年 6 月 14 日
一、系统目标
1. 设计目的
在人们日益繁忙的今天,为了充分合理的利用好有限的时间,本系统模拟可乐代理商从进货到可乐公司生产发货以及销售给顾客的整个过程。可细分为以下三个部分:
(1)可乐代理商选择进货,同时发送邮件通知可乐公司;
(2)可乐公司生产可乐,及时发货并提醒代理商收货;
(3)顾客购买可乐,选择拿货方式,并生成订单 ;
整个系统采用互答界面,有效回应客户。
2. 需求描述
当在应用界面上运行这个系统的时候,界面下回出现一个对话框,你可以根据系统的提示,选择想要的可乐种类,然后在控制台选择自己想要的种类,就可以得到相应的订单了。
操作系统:Windows 10
运行环境:Idea
二、 系统模式选择
1.需求分析
这个系统,是面对多个对象设计的。模拟可乐代理商从进货到可乐公司生产发货以及销售给顾客的整个过程,可乐被年轻人叫做快乐肥宅水,可乐的两大巨头分为为可口可乐和百事可乐,它们每年的销售量和需求量都很庞大,导致工作繁忙,这个项目,对于项目中的每个对象都可以明确的对应了供应链上的一环,每个都在个自岗位上,明确工作量。
2.选用设计模式
原型模式、单例模式、抽象工厂模式、代理模式、建造者模式。
1. 系统功能模块设计
原型模式:在需要一个类的大量对象的时候,使用原型模式是最佳选择,因为原型模式是在内存中对这个对象进行拷贝,要比直接new这个对象性能要好很多,在这种情况下,需要的对象越多,原型模式体现出的优点越明显。
单例模式:.在单例模式中,活动的单例只有一个实例——代理商,对单例类的所有实例化(可口可乐和百事可乐)都是相同的一个代理商。这样就防止其它对象对自己的实例化,确保所有的对象都访问一个实例 ,通过单例模式,声明一个静态方法,因为构造函数是受保护的(Private),这样可以确保该类就不会被实例化,而且用上面那个实例化为空的,可以获取唯一可用的对象,返回一个唯一的值。
抽象工厂模式:抽象工厂模式是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
代理模式:在代理模式中,一个类代表另一个类的功能。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
意图:为其他对象提供一种代理以控制对这个对象的访问。
主要解决:在直接访问对象时带来的问题
建造者模式:使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
2. 系统模块类图
图一(单例模式类图:代理商)
图二(单例模式类图:百事可乐)
图三(单例模式类图:可口可乐)
图四(邮件类–原型模式(浅克隆)类图)
图五(抽象工厂模式类图)
图六(订单具体建造者—建造者模式类图)
图七(代理模式类图)
图八(总的设计类图)
3. 系统控制函数
在系统的控制函数中,调用了之前设置的类
三、 系统实现
3.1 Agent.java
package agent;
import message.Message;
//单例模式---代理商
public class Agent {private Message message;private Agent(){}private static class SingletonInstance{//静态内部类private static final Agent INSTANCE = new Agent();}public static Agent getInstance(){return SingletonInstance.INSTANCE;}public String call(){return "代理商";}public Message getMessage() {return message;}public void setMessage(Message message) {this.message = message;}}
3.2 AgentFrame.java
package agent;import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;import coke.Coca_ColaFactory;
import coke.CokeFactory;
import coke.PepsiFactory;
import company.Coca_ColaCompany;
import company.PepsiCompany;
import customer.Order;
import customer.OrderBuidler;
import message.Message;
import message.Recipient;
//程序运行时呈现的窗体
public class AgentFrame extends JFrame implements ActionListener{private static final long serialVersionUID = 1L;public JLabel label;public JButton b1,b2,b3;public JPanel panel;public JTextArea tf1;public JCheckBox cb1,cb2;public JRadioButton rb1,rb2;public JScrollPane sp;int count = 0;Agent agent = Agent.getInstance();//单例生成对象Coca_ColaCompany coca = Coca_ColaCompany.getInstance();PepsiCompany pepsi = PepsiCompany.getInstance();public AgentFrame() {super("可乐商城");label = new JLabel("1代理商选择进货 2 可乐公司供货 3 顾客购买商品");b1 = new JButton("确认");b2 = new JButton("发货&提醒");b3 = new JButton("确定");panel = new JPanel();tf1 = new JTextArea();cb1 = new JCheckBox("可口可乐");cb2 = new JCheckBox("百事可乐");rb1 = new JRadioButton("门店自取");rb2 = new JRadioButton("快递送达");sp = new JScrollPane();b1.addActionListener(this);b2.addActionListener(this);b3.addActionListener(this);tf1.setText("");tf1.setLineWrap(true); //自动换行panel.setLayout(null);//将panel的布局设置为空,这样能自定义组件位置panel.add(label);panel.add(tf1);panel.add(b1);panel.add(b2);panel.add(b3);panel.add(cb1);panel.add(cb2);panel.add(rb1);panel.add(rb2);panel.add(sp);label.setBounds(20, 20, 400, 20);cb1.setBounds(20, 50, 100, 20);cb2.setBounds(20, 80, 100, 20);b1.setBounds(20, 110, 70, 30);b2.setBounds(150, 50, 100, 30);rb1.setBounds(300, 50, 100, 20);rb2.setBounds(300, 80, 100, 20);b3.setBounds(300, 110, 70, 30);tf1.setBounds(20, 150, 400, 200);sp.setBounds(20, 150, 400, 200);sp.setViewportView(tf1);this.setSize(450,400);//设置窗口大小this.setLocationRelativeTo(null);//运行程序后界面在电脑屏幕正中央显示this.getContentPane().add(panel);this.setVisible(true);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口即结束程序}@Overridepublic void actionPerformed(ActionEvent e) {if(e.getSource()==b1){count=0;tf1.append("\n========--1、代理商选择进货--========");tf1.append("\n开始发送邮件...");Recipient recipient = new Recipient("可口可乐&百事可乐公司", "12345678@email");Message message = new Message("代理商",recipient);Message clone = (Message) message.clone();//原型模式,浅克隆邮件信息if (cb1.isSelected() && cb2.isSelected()) {agent.setMessage(clone);tf1.append("\n代理商向可乐公司请求进货:可口可乐*x件,百事可乐*x件,");tf1.append("\n发件人:"+agent.getMessage().getSender()+",收件人:"+agent.getMessage().getRecipient()+"");tf1.append("\n邮件发送中... 发送成功!!!");tf1.append("\n等待可乐公司送货");} else if (cb1.isSelected()) {recipient.setName("可口可乐公司");clone.setRecipient(recipient);agent.setMessage(clone);tf1.append("\n代理商向可口可乐公司请求进货:可口可乐*x件,");tf1.append("\n发件人:"+agent.getMessage().getSender()+",收件人:"+agent.getMessage().getRecipient()+"");tf1.append("\n邮件发送中... 发送成功!!!");tf1.append("\n等待可乐公司送货");} else if (cb2.isSelected()) {recipient.setName("百事可乐公司");clone.setRecipient(recipient);agent.setMessage(clone);tf1.append("\n代理商向百事可乐公司请求进货:百事可乐*x件");tf1.append("\n发件人:"+agent.getMessage().getSender()+",收件人:"+agent.getMessage().getRecipient()+"");tf1.append("\n邮件发送中... 发送成功!!!");tf1.append("\n等待可乐公司送货");} else {count--;tf1.append("\n请选择进货商品");JOptionPane.showMessageDialog(this, "请选择进货物品", "提示消息", JOptionPane.WARNING_MESSAGE);}tf1.append("\n=================================\n");cb1.setSelected(false);//清空选择cb2.setSelected(false);count++;}if(e.getSource()==b2){if(!tf1.getText().equals("")&&count!=0){count=0;tf1.append("\n========--2、可乐公司供货--========");CokeFactory coca = new Coca_ColaFactory();//抽象工厂模式CokeFactory pepsi = new PepsiFactory();tf1.append("\n"+coca.produceCoke().produce()+"\n"+pepsi.produceCoke().produce() );tf1.append("\n已发货请注意查收!,邮件发送中... 发送成功!!!");tf1.append("\n代理商验收商品并签收,商品售卖中,顾客已支付---请选择收货方式:");tf1.append("\n(1)门店自取,(2)快递送达");}else{tf1.append("\n未接受到发货请求!");JOptionPane.showMessageDialog(this, "未接受到发货请求!", "提示消息", JOptionPane.WARNING_MESSAGE);}tf1.append("\n===============================\n");}if(e.getSource()==b3){tf1.append("\n========--3、销售给顾客--========");if(rb1.isSelected()||rb2.isSelected()){String str1= JOptionPane.showInputDialog("请输入姓名");String str2= JOptionPane.showInputDialog("请输入要购买的商品(可口可乐or百事可乐)");String str3 = null;if(rb2.isSelected()){str3= JOptionPane.showInputDialog("请输入地址");}tf1.append("\n订单生成中...");OrderBuidler builder = new OrderBuidler(str1, str2, str3);Order order = builder.create();tf1.append("\n顾客姓名:"+order.getName());tf1.append("\n购买商品:"+order.getGoods());tf1.append("\n顾客地址:"+order.getAddress());DeliverGoods deliverGoods;if(!rb1.isSelected()){deliverGoods = new DeliverMethod(true);tf1.append("\n"+deliverGoods.selectMethod());}else{deliverGoods = new DeliverMethod(false);tf1.append("\n"+deliverGoods.selectMethod());}tf1.append("\n=============================");tf1.append("\n感谢您购买我们的商品,祝您购物愉快!");}else{tf1.append("\n请先选择收货方式!");JOptionPane.showMessageDialog(this, "请先选择收货方式!", "提示消息", JOptionPane.WARNING_MESSAGE);}} }
}
3.3 DeliverGoods.java
package agent;
//抽象运输货物类--代理模式
public interface DeliverGoods {public String sendCoke(String method);public String selectMethod();
}
3.4 DeliverMethod.java
package agent;
//发货方式---快递代理or门店自取
public class DeliverMethod implements DeliverGoods{boolean flag;public DeliverMethod(boolean flag){this.flag = flag;}@Overridepublic String selectMethod(){if(flag){//如果flag为true,则选择快递代理方式发货DeliverGoods express = new Express(flag);return express.sendCoke("快递公司代理");}else{//否则,门店自取DeliverGoods tradition = new Tradition(flag);return tradition.sendCoke("门店自取");}}@Overridepublic String sendCoke(String method) {return null;}
}
3.5 Express.java
package agent;
//通过快递公司代理方式发货
public class Express implements DeliverGoods{boolean flag;String m = null;public Express(boolean flag ){this.flag = flag;}@Overridepublic String sendCoke(String method) {if(flag == true){m = method;}return "您的订单已生成,已经通过"+m+"方式为您发货,请注意查收!";}@Overridepublic String selectMethod() {return null;}
}
3.6 Tradition.java
package agent;
//通过传统运输方式发货
public class Tradition implements DeliverGoods {boolean flag;String m = null;public Tradition(boolean flag) {this.flag = flag;}@Overridepublic String sendCoke(String method) {if(flag == false){m = method;}return "您的订单已生成,请持订单到线下各大"+m+",谢谢!";}@Overridepublic String selectMethod() {return null;}
}
3.7 Coca_Cola.java
package coke;
//可口可乐--具体产品类
public class Coca_Cola implements Coke {@Overridepublic String produce() {String str = "可口可乐正在生产...";return str;}
}
3.8 Coca_ColaFactory.java
package coke;
//可口可乐具体工厂类
public class Coca_ColaFactory implements CokeFactory{@Overridepublic Coke produceCoke() {return new Coca_Cola();}
}
3.9 Coke.java
package coke;
//抽象可乐产品类
public interface Coke {public String produce();
}
3.10 CokeFactory.java
package coke;
//抽象可乐工厂类--抽象工厂模式
public interface CokeFactory {public Coke produceCoke();
}
3.11 Pepsi.java
package coke;
//百事可乐--具体产品类
public class Pepsi implements Coke {@Overridepublic String produce() {String str = "百事可乐正在生产...";return str;}
}
3.12 PepsiFactory.java
package coke;
//百事可乐具体工厂类
public class PepsiFactory implements CokeFactory{@Overridepublic Coke produceCoke() {return new Pepsi();}
}
3.13 Coca_ColaCompany.java
package company;
//单例模式---可口可乐总公司
public class Coca_ColaCompany {private Coca_ColaCompany(){}private static class SingletonInstance{//静态内部类private static final Coca_ColaCompany INSTANCE = new Coca_ColaCompany();}public static Coca_ColaCompany getInstance(){return SingletonInstance.INSTANCE;}public String call(){return "可口可乐公司";}
}
3.14 PepsiCompany.java
package company;
//单例模式--百事可乐总公司
public class PepsiCompany {private PepsiCompany(){}private static class SingletonInstance{//静态内部类private static final PepsiCompany INSTANCE = new PepsiCompany();}public static PepsiCompany getInstance(){return SingletonInstance.INSTANCE;}public String call(){return "百事可乐公司";}
}
3.15 Order.java
package customer;
//订单类
public class Order {private String name;//顾客姓名private String goods;//购买的商品private String address;//地址public Order(OrderBuidler builder){this.name = builder.getName();this.goods = builder.getGoods();this.address = builder.getAddress();}//生成订单public void createOrder(){System.out.println("----订单已生成----");if(name != null){System.out.println("顾客姓名:"+name);}System.out.println("购买的商品:"+goods);System.out.println("地址"+address);}public String getName() {return name;}public String getGoods() {return goods;}public String getAddress() {return address;}
}
3.16 OrderBuidler.java
package customer;
//订单具体建造者---建造者模式
public class OrderBuidler {private String name;//顾客姓名private String goods;//购买的商品private String address;//地址public OrderBuidler(String name,String goods,String address){this.name = name;this.goods = goods;this.address = address;}//生成订单方法public Order create(){return new Order(this);}public String getName() {return name;}public String getGoods() {return goods;}public String getAddress() {return address;}
}
3.17 Test.java
package main;import agent.AgentFrame;
import coke.Coca_ColaFactory;
import coke.Coke;
import coke.CokeFactory;public class Test {public static void main(String[] args){AgentFrame f = new AgentFrame();}
}
3.18 Message.java
package message;
//邮件类--原型模式(浅克隆)
public class Message implements Cloneable {String sender;//发送方Recipient recipient;//收件人public Message(String sender,Recipient recipient){this.sender = sender;this.recipient = recipient;}public Object clone(){//克隆方法Message clone = null;try{clone = (Message) super.clone();}catch(CloneNotSupportedException e){e.printStackTrace();}return clone;}public String getSender() {return sender;}public void setSender(String sender) {this.sender = sender;}public Recipient getRecipient() {return recipient;}public void setRecipient(Recipient recipient) {this.recipient = recipient;}
}
3.19 Recipient.java
package message;
//收件人信息
public class Recipient {private String name;//收件人姓名private String email;//收件人邮箱public Recipient(String name,String email){this.name = name;this.email = email;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}@Overridepublic String toString(){return name;}
}
四、 系统测试
图(4-1 主界面)
图(4-2 代理商选择一种可乐进货)
图(4-3 若代理商没有选择可乐进行发货提醒,则跳出弹窗)
图(4-3 若代理商选择可口可乐后进行发货提醒)
图(4-4 顾客选择收货方式(门店自取):输入自己的姓名)
图(4-5 顾客选择收货方式(门店自取):输入要的商品)
图(4-6 生成订单)
五、总结
1. 实现的功能和优点
其实就是一个小系统,代码挺简单的,但要融合多个设计模式,所以代码还是挺多的(19个类)本系统模拟可乐代理商从进货到可乐公司生产发货以及销售给顾客的整个过程。可细分为以下三个部分:
(1)可乐代理商选择进货,同时发送邮件通知可乐公司
(2)可乐公司生产可乐,及时发货并提醒代理商收货
顾客购买可乐,选择拿货方式,并生成订单
共使用了5种设计模式,分别是原型模式、单例模式、抽象工厂模式、代理模式、建造者模式。
2. 完成心得
通过这一次,最后的大作业。我将设计模式以前学过的,通过这一次的实验,又一次的复习了起来。通过本次的大作业,将杂乱不堪的程序,通过一些常见的应用于软件开发的设计模式引入到本次的设计模式里面来,减少了代码的冗余,并且,类与类,模块与模块之间耦合度较弱。代码修改比较方便,并且,有利于后期进行东西的添加。
题外话:
本实验报告纯手写靠自己理解两天肝出来的肯定有不足,可以借鉴但不要全搬,参考来自
源代码网盘资源,链接和提取码下方自提,需要的自行下载吧:
链接:https://pan.baidu.com/s/1LlDIQPKDnP0sbjut6QyHCg
提取码:ljtv