综合使用设计模式实验
姓名:蔡仕林
学号:201126630701
(一) 实验设计场景描述
某国际电子商务系统,要处理许多不同国家的订单。不同国家的订单税额计算方法是不
同的,并且会不断变化。除此之外假定订单分为会员订单和非会员订单,会员订货有积分奖
励,非会员则没有,不同级别的会员积分规则不同;订货时须确定订单金额、会员类型、国
别等信息(为简化,不需要货物数据),订单对象则要完成税金计算和积分计算;我们计算
得到了商品的销售价格,现在客户要求打印销售票据,并且打印的销售票据要添加表头和页
脚信息。公司要求处理若干不同类型(格式)的表头和页脚,按照客户实际需要来选择不同
的表头和页脚。并且要求利用工厂模式获得客户需要的销售票据。用 java 图形界面实现。
(二) 实验方案
1、用文字描述解题的思路。体现软件设计模式中的什么原则
本次实验是将策略模式,装饰模式和工厂模式组合应用。这三个模式的 UML 图可以结
合,策略模式和装饰模式共用一个组件,具体组件销售票据在工厂中进行实例化对象,作为
工厂模式的产品,以下分三方面进行描述。
1.策略模式:销售票据跟客户下达的订单生成,订单中有两个变化的属性,国别和是否
会员变化引起税金和积分的变化,根据策略模式原理将需要变化的部分分割出来进行封装,
我的思路是设计两个接口,一个处理税金,包含一个抽象计算税金函数。一个处理积分,包
含一个抽象积分计算函数。在订单对象也就是上下文中设计两个这两个接口类型的成员变
量,税金接口下面设计中国美国两个类实现接口,积分接口下面设计非会员,普通会员和高
级会员三个类实现接口。
2.装饰模式:装饰者和被装饰者,本实验要求装饰销售票据的表头页脚信息。参考书上
的装饰模式的 UML 图,设计组件 Form(与策略模式共用组件),具体组件 SellForm(销售
票据)与工厂模式共用组件,装饰 Decorator,将表头页脚分开装饰,可设计四个具体装饰
类 HeadDecoratorOne Two 分别是类型 1 和 2 的表头,FooterDecoratorOne Two 分别是类型 1
和 2 的页脚,总共有四种搭配的销售票据。
3.工厂模式:一个工厂类,不同类型的销售票据是具体产品,抽象工厂类由具体工厂继
承,在抽象工厂类中声明一个抽象函数 createForm,由继承类进行定义,根据用户的需求,
然后返回不同的销售票据对象。具体产品分别为四种不同表头页脚搭配的销售票据,继承
SellForm。类中使用装饰模式构造出相应的销售票据的表头和页脚,赋值给自身的成员变量。
4. 体现软件设计模式中的开闭原则,面向抽象原则,多用组合少用继承。
2、用 UML 中的类图表示实验设计的类结构
(三) 源程序简单说明
简单截取重要的源代码,每个代码实现功能,并对重要部分附注释。
------------------------Application(图形测试界面)---------------------------------
package Application;
import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import Decorator.*;
import Strategy.*;
import Factory.*;
public class Application extends JFrame {
别",7);
public JTextField a=new JTextField("订单金额",7);
public JTextField hy=new JTextField("会员类型",5);
public JTextField tax=new JTextField(5);
public JTextField gj=new JTextField("国
public JTextField money=new JTextField(5);
public JTextField grade=new JTextField(5);
public JTextArea form=new JTextArea(5, 15);
public JTextField bt=new JTextField("表头类型",6);
public JTextField yj=new JTextField("页脚类型",6);
String []s={"非会员","普通会员","高级会员"};
String []t={"中国","美国"};
String []b={"表 头 1","表 头 2"};
String []y={"页 脚 1","页 脚 2"};
public JComboBox cb=new JComboBox(s);
public JComboBox gb=new JComboBox(t);
public JComboBox bta=new JComboBox(b);
public JComboBox yja=new JComboBox(y);
Order order=null;
public Application(){
super("订单信息");
Container c=getContentPane();
c.setLayout(new FlowLayout());
JButton b1=new JButton("计算税金");
b1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JButton b1=(JButton)e.getSource();
order=new Order(gb.getSelectedIndex(),cb.getSelectedIndex());
double jq=Double.parseDouble(money.getText());
tax.setText(Double.toString(order.gettax(jq)));
}
});
JButton b2=new JButton("计算积分");
b2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JButton b2=(JButton)e.getSource();
order=new Order(gb.getSelectedIndex(),cb.getSelectedIndex());
double jq=Double.parseDouble(money.getText());
grade.setText(Double.toString(order.getgrade(jq)));
}
});
JButton b3=new JButton("打印票据");
b3.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JButton b3=(JButton)e.getSource();
order=new Order(gb.getSelectedIndex(),cb.getSelectedIndex());
double jq=Double.parseDouble(money.getText());
Factory factory=new FormFactory();
sellform=factory.getForm(bta.getSelectedIndex(),yja.getSelectedIndex());
SellForm
"+gb.getSelectedItem().toString()+cb.getSelectedItem().toString()+"销售票据"+"\n"+
sellform.head()+"\n\n"+" 共 消 费 "+jq+" 元 ,"+" 收 取 税 金
"+Double.toString(order.gettax(jq))+"元"+"\n\n"+sellform.footer());
form.setText("
}
});
a.setEditable(false); gj.setEditable(false);hy.setEditable(false);bt.setEditable(false);
yj.setEditable(false);tax.setEditable(false);grade.setEditable(false);form.setEditable(false);
c.add(hy);c.add(cb); c.add(gj);c.add(gb); c.add(a) ;c.add(money);c.add(b1);c.add(tax);
c.add(b2);c.add(grade);c.add(bt);c.add(bta);c.add(yj);c.add(yja);c.add(b3);
c.add(form);
}
public static void main(String args[])
{
Application app=new Application();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setSize(220,450);
app.setVisible(true);
}
}
----------------------------------策略模式------------------------------------
package Strategy;
public class Order {
TaxStrategy ordertax=null;
GradeStrategy ordergrade=null;
Order order=null;
public Order(int country,int type)
{
switch(country){
case 0:
China taxc=new China();
ordertax=taxc;
break;
case 1:
USA taxu=new USA();
ordertax=taxu;
break;
}
switch(type){
case 0:
Nmember gradef=new Nmember();
ordergrade=gradef;
break;
case 1:
Rmember gradep=new Rmember();
ordergrade=gradep;
break;
case 2:
Smember gradeg=new Smember();
ordergrade=gradeg;
break;
}
}
public Order(Order order){this.order=order;}
public Order(){}
public double gettax(double money)
{
return ordertax.OrderTax(money);
}
public int getgrade(double money)
{
return ordergrade.OrderGrade(money);
}
public String head(){return null;}
public String footer(){return null;}
}
-----------------------工厂模式--------------------------------
package Factory;
import Decorator.SellForm;
public abstract class Factory {
public SellForm getForm(int bt,int yj){
SellForm form=createForm(bt,yj);
return form;
}
public abstract SellForm createForm(int bt,int yj);
}
package Factory;
import Decorator.*;
public class FormFactory extends Factory {
public SellForm createForm(int bt,int yj){
if(bt==0&&yj==0){
return new H1F1Form();}
else if(bt==1&&yj==1){
return new H2F2Form();}
else if(bt==0&&yj==1){
return new H1F2Form();}
else if(bt==1&&yj==0){
return new H2F1Form();}
return null;
}
}
-------------------------------------------装饰模式----------------------------------------
package Decorator;
import Strategy.*;
public class SellForm extends Order{
public String head="表头:";
public String footer="页脚:";
public String head(){
return head;
}
public String footer(){
return footer;
}
}
package Decorator;
import Strategy.*;
public abstract class Decorator extends Order{
protected Order order;
public Decorator(int country,int type){
super(country,type);
}
public Decorator(Order order){
super(null);
this.order=order;
}
}
(四)实验结果
用截屏方式呈现实验数据
项目文件目录:
运行界面及测试结果:输入数据:高级会员 中国 2000 表头 1 页脚 1
输入数据:普通会员 美国 2000 表头 2 页脚 2