题目描述:现假设要实现一个网络商城系统的部分功能
1、商品状态的订阅:网络商城中的每一种商品,供应商和用户都可以对其进行订阅关注。对供应商来说,当商品缺货的时候,提醒供应商补货。对于用户来说,当商品价格变动的时候,或商品由缺货变成有货的时候,可以自动通知用户。请使用观察者模式,实现这种效果。
2、订单状态的管理:当用户在商城中下了订单后,订单存在着几种状态:下单状态(下订单未付款),已付款状态(付款未发货),已发货状态(发货未确认),已完成状态(用户确认或售后完成),已取消状态(用户未付款或用户取消),售后状态(用户收货确认后有退换货问题)。状态之间存在行为转换,请用状态模式,实现订单状态的转换。
3、订单发货的管理:该商城在全国有西南、西北、东南、东北4个物流中心,订单会根据收货地的范围不同,确定应该由那个物流中心发货。请使用代理模式,实现订单发货的物流管理。
详细代码(本人在初学阶段,纯属分享,代码仅供参考):
1、商品状态的订阅:
//抽象主题
package finalhomework.商品状态订阅;
public interface Subject {
public void addObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObservers();
}
//-------------------------------------------------------------------------------
package finalhomework.商品状态订阅;
import java.util.ArrayList;
//具体主题
public class Commodity implements Subject{
Goods goods; //商品,进行通知时作为参数进行传递
public void setGoods(Goods goods){
this.goods = goods;
}
public void setPrice(double price){
goods.setPrice(price);
}
ArrayList<Observer> arrayList = new ArrayList<>();
@Override
public void addObserver(Observer observer) {
arrayList.add(observer);
}
@Override
public void removeObserver(Observer observer) {
int i = arrayList.indexOf(observer);
if (i>=0){
arrayList.remove(observer);
}
}
@Override
public void notifyObservers() {
for (Observer observer:arrayList) {
if ((goods.newPrice-goods.oldPrice)!=0 || (goods.number)>0){
if (observer.getId() == "User"){
observer.update(goods);
}
}else if (goods.number<=0){
if (observer.getId() == "Supplier"){
observer.update(goods);
}
}
}
}
//主题进行通知的方法
public void changeData(Goods goods){
this.goods = goods;
notifyObservers();
}
}
//-------------------------------------------------------------------------------
//用于通知的商品对象类
package finalhomework.商品状态订阅;
public class Goods {
String name;
double oldPrice;
double newPrice;
int number;
public Goods(String name,double Price,int number) {
this.name = name;
this.oldPrice = Price;
this.newPrice = Price;
this.number = number;
}
public String getName() {
return name;
}
public double getPrice() {
return newPrice;
}
public int getNumber() {
return number;
}
public void setPrice(double price) {
oldPrice = newPrice;
newPrice = price;
}
public void setNumber(int number) {
this.number = number;
}
public void sub(int number){
this.number -= number;
}
}
//-------------------------------------------------------------------------------
//抽象观察者
package finalhomework.商品状态订阅;
public abstract class Observer {
String id;
abstract String getId();
abstract void update(Goods goods);
}
//-------------------------------------------------------------------------------
//具体供应商观察者
package finalhomework.商品状态订阅;
public class Supplier extends Observer{
//供应商
String id = "Supplier";
Goods goods;
public String getId(){
return id;
}
//在具体供应商中
@Override
public void update(Goods goods) {
this.goods = goods;
System.out.println("商品:["+goods.getName()+"] 无货!已通知供应商进行补货!");
}
public void supplyNum(int number){
goods.setNumber(number);
System.out.println("补货成功!当前商品剩余:"+number);
}
}
//-------------------------------------------------------------------------------
//具体用户观察者
package finalhomework.商品状态订阅;
import java.text.DecimalFormat;
public class User extends Observer{
//用户
String id = "User";
DecimalFormat df = new DecimalFormat("0.00");
public String getId(){
return id;
}
//在具体用户类中
@Override
void update(Goods goods) {
System.out.println("用户端收到消息:");
if (goods.number>0){
System.out.println("商品名:"+goods.name+" 已有货!");
}
if ((goods.newPrice - goods.oldPrice)>0){
System.out.println("商品名:"+goods.name+" 较近期上涨:"+df.format((goods.newPrice - goods.oldPrice))+"元");
}else if ((goods.newPrice - goods.oldPrice)<0){
System.out.println("商品名:"+goods.name+" 较近期下降:"+(df.format(-(goods.newPrice - goods.oldPrice)))+"元");
}
}
}
2、订单状态的管理:
package finalhomework.订单状态管理;
//上下文环境,存放一个当前状态
public class Order {
//当前状态
State curState;
public Order() {
this.curState = new SelectState(this);
}
public void setState(State state){
this.curState = state;
}
public void placeOrder(){ //下单
curState.placeOrder();
}
public void pay(){ //付款
curState.pay();
}
public void cancel(){ //取消
curState.cancel();
}
public void deliver(){ //发货
curState.deliver();
}
public void accomplish(){ //完成
curState.accomplish();
}
public void aftermarket(){ //售后
curState.aftermarket();
}
}
//--------------------------------------------------------------------------
package finalhomework.订单状态管理;
//抽象状态类,封装与状态相关的行为
public abstract class State {
//持有一个订单对象
public static Order ORDER;
public abstract void placeOrder();
public abstract void pay();
public abstract void cancel();
public abstract void deliver();
public abstract void accomplish();
public abstract void aftermarket();
}
//--------------------------------------------------------------------------
package finalhomework.订单状态管理;
//默认在选择状态(自己加上的,题目中没有。为了实现状态间能够形成闭环)
public class SelectState extends State{
public SelectState(Order order) {
ORDER = order;
}
@Override
public void placeOrder() {
System.out.println("选择商品成功!请及时下单!");
ORDER.setState(new PlaceOrderState(ORDER));
}
@Override
public void pay() {
System.out.println("请先选择商品!");
}
@Override
public void cancel() {
ORDER.setState(this);
}
@Override
public void deliver() {
System.out.println("请先选择商品!");
}
@Override
public void accomplish() {
System.out.println("请先选择商品!");
}
@Override
public void aftermarket() {
System.out.println("请先选择商品!");
}
}
//--------------------------------------------------------------------------
package finalhomework.订单状态管理;
public class PlaceOrderState extends State{
public PlaceOrderState(Order order) {
ORDER = order;
System.out.println(" --当前在下单状态");
}
@Override
public void placeOrder() {
System.out.println("请勿重复下单!");
}
@Override
public void pay() {
System.out.println("当前商品已完成支付!");
ORDER.setState(new PayState(ORDER));
}
@Override
public void cancel() {
System.out.println("订单已取消,请选择合适商品下单!");
ORDER.setState(new CancelState(ORDER));
}
@Override
public void deliver() {
System.out.println("请先完成当前商品的支付!");
}
@Override
public void accomplish() {
System.out.println("请先完成当前商品的支付!");
}
@Override
public void aftermarket() {
System.out.println("请先完成当前商品的支付!");
}
}
//--------------------------------------------------------------------------
package finalhomework.订单状态管理;
public class PayState extends State{
public PayState(Order order) {
ORDER = order;
System.out.println(" --当前在支付状态");
}
@Override
public void placeOrder() {
System.out.println("请完成当前商品的支付!");
}
@Override
public void pay() {
System.out.println("已支付成功!请勿重复支付!");
}
@Override
public void cancel() {
System.out.println("订单已取消!请选择商品进行下单!");
ORDER.setState(new CancelState(ORDER));
}
@Override
public void deliver() {
System.out.println("商品已发货!");
ORDER.setState(new DeliverState(ORDER));
}
@Override
public void accomplish() {
System.out.println("请先对下单商品进行支付!");
}
@Override
public void aftermarket() {
System.out.println("请先对下单商品进行支付!");
}
}
//--------------------------------------------------------------------------
package finalhomework.订单状态管理;
public class DeliverState extends State{
public DeliverState(Order order) {
ORDER = order;
System.out.println(" --当前在发货状态");
}
@Override
public void placeOrder() {
System.out.println("商品已发货,请耐心等待!");
}
@Override
public void pay() {
System.out.println("商品已发货,请耐心等待!");
}
@Override
public void cancel() {
System.out.println("商品已发货,若有疑问请收货后选择售后服务!");
}
@Override
public void deliver() {
System.out.println("商品已发货,请耐心等待!");
}
@Override
public void accomplish() {
System.out.println("商品已签收!若有疑问您可进入售后服务!");
ORDER.setState(new AccomplishState(ORDER));
}
@Override
public void aftermarket() {
System.out.println("请先完成当前商品签收!");
}
}
//--------------------------------------------------------------------------
package finalhomework.订单状态管理;
public class CancelState extends State{
public CancelState(Order order) {
ORDER = order;
System.out.println(" --当前在取消状态");
ORDER.setState(new SelectState(ORDER));
}
@Override
public void placeOrder() {
}
@Override
public void pay() {
}
@Override
public void cancel() {
}
@Override
public void deliver() {
}
@Override
public void accomplish() {
}
@Override
public void aftermarket() {
}
}
//--------------------------------------------------------------------------
package finalhomework.订单状态管理;
public class AccomplishState extends State{
public AccomplishState(Order order) {
ORDER = order;
System.out.println(" --当前在完成状态");
}
@Override
public void placeOrder() {
System.out.println("进入商城选择界面!");
ORDER.setState(new SelectState(ORDER));
}
@Override
public void pay() {
System.out.println("请选择商品下单!");
}
@Override
public void cancel() {
System.out.println("请选择商品下单!");
}
@Override
public void deliver() {
System.out.println("请选择商品下单!");
}
@Override
public void accomplish() {
System.out.println("请选择商品下单!");
}
@Override
public void aftermarket() {
System.out.println("进入售后服务!");
ORDER.setState(new AftermarketState(ORDER));
}
}
//-------------------------------------------------------------------------
package finalhomework.订单状态管理;
public class AftermarketState extends State{
public AftermarketState(Order order) {
ORDER = order;
System.out.println(" --当前在售后状态");
}
@Override
public void placeOrder() {
System.out.println("再次进入商城选择界面!");
ORDER.setState(new SelectState(ORDER));
}
@Override
public void pay() {
System.out.println("请选择商品下单!");
}
@Override
public void cancel() {
System.out.println("请选择商品下单!");
}
@Override
public void deliver() {
System.out.println("请选择商品下单!");
}
@Override
public void accomplish() {
System.out.println("售后已完成!欢迎挑选合适商品再次进行购买!");
ORDER.setState(new AccomplishState(ORDER));
}
@Override
public void aftermarket() {
System.out.println("违规操作!");
}
}
3、订单发货的管理:
//抽象物流中心
package finalhomework.订单发货管理;
public abstract class LogisticCenter {
public String location;
public String getLocation() {
return location;
}
public abstract void deliver();
}
//---------------------------------------------------------
package finalhomework.订单发货管理;
public class NortheastLogisticCenter extends LogisticCenter{
String location = "东北";
@Override
public String getLocation() {
return location;
}
@Override
public void deliver() {
System.out.println("从东北部物流中心发出!");
}
}
//---------------------------------------------------------
package finalhomework.订单发货管理;
public class NorthwestLogisticCenter extends LogisticCenter{
String location = "西北";
@Override
public String getLocation() {
return location;
}
@Override
public void deliver() {
System.out.println("从西北部物流中心发出!");
}
}
//---------------------------------------------------------
package finalhomework.订单发货管理;
public class SoutheastLogisticCenter extends LogisticCenter{
String location = "东南";
@Override
public String getLocation() {
return location;
}
@Override
public void deliver() {
System.out.println("从东南部物流中心发出!");
}
}
//---------------------------------------------------------
package finalhomework.订单发货管理;
public class SouthwestLogisticCenter extends LogisticCenter{
String location = "西南";
@Override
public String getLocation() {
return location;
}
@Override
public void deliver() {
System.out.println("从西南部物流中心发出!");
}
}
//--------------------------------------------------------
//物流代理
package finalhomework.订单发货管理;
public class LogisticsCenterProxy extends LogisticCenter{
//物流中心
LogisticCenter logisticCenter;
public LogisticsCenterProxy(LogisticCenter logisticCenter) {
this.logisticCenter = logisticCenter;
}
@Override
public void deliver() {
logisticCenter.deliver();
}
}
商城类代码(综合):
package finalhomework;
import finalhomework.商品状态订阅.Commodity;
import finalhomework.商品状态订阅.Goods;
import finalhomework.商品状态订阅.Supplier;
import finalhomework.商品状态订阅.User;
import finalhomework.订单状态管理.Order;
import finalhomework.订单状态管理.SelectState;
import finalhomework.订单发货管理.*;
import java.util.ArrayList;
import java.util.Scanner;
public class OnlineMallSystem {
static int i; //保存goodslist中物品数量
//添加对象引用
Order order; //状态模式中的环境
LogisticCenter logisticCenter; //代理模式中物流中心
ArrayList<LogisticCenter> logisticCenters = new ArrayList<>(); //存放四个物流中心
LogisticsCenterProxy logisticsCenterProxy; //物流代理
ArrayList<Goods> goodslist = new ArrayList<>(); //保存商品数量
//观察者模式
User user = new User(); //用户观察者
Supplier supplier = new Supplier(); //供应商观察者
Commodity commodity = new Commodity(); //主题,用于更新数据
public void run() throws InterruptedException {
commodity.addObserver(user);
commodity.addObserver(supplier);
goodslist.add(new Goods("苹果", 5.5,20));
goodslist.add(new Goods("香蕉", 6.6,21));
goodslist.add(new Goods("鸭梨", 12.5,23));
goodslist.add(new Goods("西瓜", 4.5,15));
logisticCenters.add(new NortheastLogisticCenter());
logisticCenters.add(new NorthwestLogisticCenter());
logisticCenters.add(new SouthwestLogisticCenter());
logisticCenters.add(new SoutheastLogisticCenter());
Scanner scanner = new Scanner(System.in);
while(true){
//进行通知
for (i=0;i<goodslist.size();i++){
commodity.changeData(goodslist.get(i));
}
System.out.println("正在进入商城用户端,请稍等...");
Thread.sleep(1000); //模拟进入1秒
System.out.println("----------------欢迎进入在线商城----------------");
System.out.println("- 本商城现提供商品如下: -");
for (i=0;i<goodslist.size();i++){
System.out.println("-"+(i+1)+"."+goodslist.get(i).getName()+" "+"单价:"+goodslist.get(i).getPrice()+"元"+" 当前剩余量:"+goodslist.get(i).getNumber()+"-");
}
System.out.println("- 亲~ 请选择对应序号进行下单哟! -");
System.out.println("------------------按0退出!------------------- (注意:按-1可进入商城后台管理系统)");
int k; //商城中的选择序号
k = scanner.nextInt();
if (k == 0) { //退出循环
System.out.println("欢迎下次光临!");
break;
}else if(k <= i && k>0){
while (true){
order = new Order();
System.out.println("-------------已选择:"+goodslist.get(k-1).getName()+"--------------");
System.out.println("- 请选择对应服务: -");
System.out.println("-1.下单 -");
System.out.println("-2.重新选择 -");
System.out.println("-----------------服务----------------");
int fun= scanner.nextInt(); //对应服务的序号
if (fun == 1){
System.out.println("-------------已选择:"+goodslist.get(k-1).getName()+"--------------");
System.out.println("-单价:"+goodslist.get(k-1).getPrice()+" -");
System.out.println("-----------------订购-----------------");
System.out.println("请输入"+goodslist.get(k-1).getName()+"的数量");
int n; //下单的商品数量
//用于判断正确的输入数量
while (true){
n = scanner.nextInt();
if (n > goodslist.get(k-1).getNumber()){
System.out.println("输入数量大于当期剩余数量,请重新输入!");
}else{
break;
}
}
while (true){
int t = 0;
System.out.println("请输入您的收货地所处地区,我们将为您就近发货[东北/西北/东南/西南]");
String d = scanner.next();
// if ("东北".equals(d)){
// logisticCenter = new NortheastLogisticCenter();
// break;
// }else if("东南".equals(d)){
// logisticCenter = new NortheastLogisticCenter();
// break;
// }else if("西北".equals(d)){
// logisticCenter = new SouthwestLogisticCenter();
// break;
// }else if("西南".equals(d)){
// logisticCenter = new SouthwestLogisticCenter();
// break;
// }
for (LogisticCenter logisticCenter:logisticCenters){
if (d.equals(logisticCenter.getLocation())){
logisticsCenterProxy = new LogisticsCenterProxy(logisticCenter);
t = 1;
}
}
if (t == 1){
break;
} else {
System.out.println("请输入提供选项中正确的地址之一!");
}
}
order.placeOrder(); //订单状态由选择状态到下单状态
// logisticsCenterProxy = new LogisticsCenterProxy(logisticCenter); //传入对应的代理类
System.out.println("请输入[Y/N]进行支付 Y:支付/N:取消");
String p = scanner.next();
if (p.equalsIgnoreCase("y")){
goodslist.get(k-1).sub(n); //该商品数量减少n
System.out.println("-----"+goodslist.get(k-1).getName()+"订购成功"+"------------");
System.out.println("-单价:"+goodslist.get(k-1).getPrice()+" 元 -");
System.out.println("-数量:"+n+" -");
System.out.println("-总价:"+(n*goodslist.get(k-1).getPrice())+" 元 -");
System.out.println("-----------------订单信息---------------");
order.pay(); //订单状态由下单状态到付款状态
System.out.println("----------------");
logisticsCenterProxy.deliver(); //物流代理发货
System.out.println("----------------");
order.deliver(); //订单状态由付款状态到发货状态
System.out.println("----------------");
order.accomplish();//订单到完成状态
while (true){
System.out.println("-1.进入售后退货 -");
System.out.println("-2.暂不售后 -");
int fun2 = scanner.nextInt();
if (fun2 == 1){
order.aftermarket(); //订单到售后状态
System.out.println("--------退货成功-------");
System.out.println("-退货数量:"+n+" -");
goodslist.get(k-1).sub(-n);
order.accomplish(); //最后转为完成状态
}
break;
}
System.out.println("=======期待下次光临!========");
System.out.println();
order.setState(new SelectState(order)); //一次购买结束,订单回到选择状态
System.out.println("==========================");
break;
}else{
order.cancel(); //支付取消,订单由下单状态到取消状态
}
}else if(fun == 2){
break;
}
}
} else if (k == -1) {
int fun5;
//进入后台前判断商品是否出现数量不足
//模拟供应商进行补货
System.out.println("--------商城物品自检中---------");
for (i = 0; i < goodslist.size(); i++) {
if (goodslist.get(i).getNumber() == 0) {
System.out.println("-商品:" + goodslist.get(i).getName() + " 当前剩余量:" + goodslist.get(i).getNumber() + "-");
commodity.changeData(goodslist.get(i));
System.out.println("请输入进货数量:");
fun5 = scanner.nextInt();
supplier.supplyNum(fun5);
System.out.println("-------------------");
}
}
System.out.println("----------自检完成-----------");
System.out.println("============================");
while (true) {
//用于测试观察者模式中,价格波动对用户的通知
System.out.println("----------欢迎进入商城后台管理系统!-----------");
System.out.println("- 选择商品对应序号可进行修改: -");
for (i = 0; i < goodslist.size(); i++) {
System.out.println("-" + (i + 1) + "." + goodslist.get(i).getName() + " " + "单价:" + goodslist.get(i).getPrice() + "元" + " 当前剩余量:" + goodslist.get(i).getNumber() + "-");
}
System.out.println("----------------按0退出立即后台!-----------------");
int hk;//后台中的选择序号
hk = scanner.nextInt();
if (hk <= i && hk > 0) {
while (true) {
System.out.println("-------------已选择:" + goodslist.get(hk - 1).getName() + "--------------");
System.out.println("- 请选择对应服务: -");
System.out.println("-1.修改价格 -");
System.out.println("-2.重新选择 -");
System.out.println("-----------------服务----------------");
int fun3 = scanner.nextInt(); //对应服务的序号
if (fun3 == 1) {
System.out.println(goodslist.get(hk - 1).getName() + "的当前价格为:" + goodslist.get(hk - 1).getPrice() + " || 请输入新的价格:");
double fun4 = scanner.nextDouble(); //对应服务的序号
goodslist.get(hk - 1).setPrice(fun4);
System.out.println("---设置成功!---");
System.out.println(goodslist.get(hk - 1).getName() + "的当前价格为:" + goodslist.get(hk - 1).getPrice());
System.out.println("==============");
} else {
break;
}
}
} else {
break;
}
}
}else{
System.out.println("输入错误!");
}
}
}
}
启动商城:
package finalhomework;
//运行在线商城
public class OnlineMallSystemTest {
public static void main(String[] args) throws InterruptedException {
OnlineMallSystem onlineMallSystem = new OnlineMallSystem();
onlineMallSystem.run();
}
}
总结:一:在状态模式中,尝试使用状态机来对订单的状态进行管理,或者在订单中持有所有状态下的对象,在需要使用时直接作为参数传入。二:当用户下单后,可以尝试生成一个带有编号的订单,在用户购买后,或者取消支付或退货后,用订单实现对购买商品的数量的改变来代替商城运行中直接调用商品的方法来修改。