Skip to content

Instantly share code, notes, and snippets.

  • Save anton-abyzov/d9605f1be71c6c876230 to your computer and use it in GitHub Desktop.
Save anton-abyzov/d9605f1be71c6c876230 to your computer and use it in GitHub Desktop.
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.lib;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by sugawaraMBP on 15/03/25.
*/
public class Log {
private static final String TAG = "Log";
private static final String EMPTY = "";
private static boolean LOG_ENABLE = true;
private enum Level {
DEBUG,
WARNING,
INFO,
ERROR;
@Override
public String toString() {
String temp;
switch (this) {
case WARNING:
temp = "W/";
break;
case INFO:
temp = "I/";
break;
case ERROR:
temp = "E/";
break;
case DEBUG:
default:
temp = "D/";
break;
}
return temp;
}
}
private static SimpleDateFormat dateFormatter = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
private static void println(Level level, String tag, String text) {
StringBuffer buffer = new StringBuffer();
Date date = new Date();
buffer.append(dateFormatter.format(date));
buffer.append(" ");
buffer.append(level.toString());
buffer.append(tag);
buffer.append(" ");
buffer.append(text);
System.out.println(buffer.toString());
}
public static int d(String tag, String text) {
if (LOG_ENABLE) {
println(Level.DEBUG, tag, text);
}
return 0;
}
public static int d(String tag, String format, Object... args) {
if (LOG_ENABLE) {
println(Level.DEBUG, tag, format(format, args));
}
return 0;
}
public static int w(String tag, String format, Object... args) {
if (LOG_ENABLE) {
println(Level.WARNING, tag, format(format, args));
}
return 0;
}
public static int i(String tag, String format, Object... args) {
if (LOG_ENABLE) {
println(Level.INFO, tag, format(format, args));
}
return 0;
}
public static int e(String tag, String format, Object... args) {
if (LOG_ENABLE) {
println(Level.ERROR, tag, format(format, args));
}
return 0;
}
private static String format(String format, Object... args) {
try {
return String.format(format == null ? EMPTY : format, args);
} catch (RuntimeException e) {
Log.w(TAG, "format error. reason=%s, format=%s", e.getMessage(), format);
return String.format(EMPTY, format);
}
}
public static String hexString(byte[] bytes) {
if (bytes == null) {
return "(null)";
}
StringBuffer buffer = new StringBuffer();
buffer.delete(0, buffer.length());
for (byte b : bytes) {
buffer.append(String.format("%02X", b));
}
return buffer.toString();
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.service.Center;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.town.Address;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.town.House;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.town.HouseMap;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.user.Customer;
public class Main {
public static void main(String[] args) {
// 住居リストを生成する
String pref1 = "岩手";
String pref1city1 = "盛岡";
String pref1city2 = "一関";
Address addressSenderA = new Address(pref1, pref1city1, 1);
Address addressSenderB = new Address(pref1, pref1city2, 1);
House houseSenderA = new House(addressSenderA);
House houseSenderB = new House(addressSenderB);
HouseMap.houses.add(houseSenderA);
HouseMap.houses.add(houseSenderB);
HouseMap.houses.add(new House(new Address(pref1, pref1city1, 2)));
HouseMap.houses.add(new House(new Address(pref1, pref1city2, 2)));
String pref2 = "東京";
String pref2city1 = "新宿";
String pref2city2 = "品川";
Address addressReceiverA = new Address(pref2, pref2city1, 10);
Address addressReceiverB = new Address(pref2, pref2city2, 10);
House houseReceiverA = new House(addressReceiverA);
House houseReceiverB = new House(addressReceiverB);
HouseMap.houses.add(houseReceiverA);
HouseMap.houses.add(houseReceiverB);
HouseMap.houses.add(new House(new Address(pref2, pref2city1, 20)));
HouseMap.houses.add(new House(new Address(pref2, pref2city2, 20)));
// 集荷センターを生成
Center.initCenters(new Address(pref1, pref1city1, 100), new Address(pref2, pref2city2, 200));
// お客さんを生成
Customer senderA = new Customer();
Customer senderB = new Customer();
Customer receiverA = new Customer();
Customer receiverB = new Customer();
// お客さんを家に住まわせる
senderA.locale(houseSenderA);
senderB.locale(houseSenderB);
receiverA.locale(houseReceiverA);
receiverB.locale(houseReceiverB);
// 荷物を遅らせる
senderA.sendSomePackage(addressReceiverA);
senderA.sendSomePackage(addressReceiverA);
senderA.sendSomePackage(addressReceiverA);
senderB.sendSomePackage(addressReceiverB);
senderB.sendSomePackage(addressReceiverB);
senderB.sendSomePackage(addressReceiverB);
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.service;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.lib.Log;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.town.Address;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.town.Route;
import java.util.ArrayList;
import java.util.List;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class Center {
private static final String TAG = "Center";
private static List<Center> centers = new ArrayList<Center>();
public static void initCenters(Address center1, Address center2) {
centers.clear();
centers.add(new Center(center1));
centers.add(new Center(center2));
}
public static Center nearestCenter(Address targetAreaAddress) {
Center target = null;
for (Center temp : centers) {
if (temp.match(targetAreaAddress)) {
target = temp;
break;
}
}
return target;
}
private List<Deliverer> deliverers = new ArrayList<Deliverer>();
private Address centerAddress;
public Center(Address centerAddress) {
this.centerAddress = centerAddress;
}
public boolean match(Address address) {
return centerAddress.prefecture.equals(address.prefecture);
}
public void requireServiceOfPackageCollection(Address customersAddress, Package.Content.Type packageType) {
Deliverer deliverer = searchFreeDeliverer(packageType); // 暇な配達員を探す
if (deliverer == null) {
// TODO: ひとまず、暇な配達員がいない場合は新規に雇う
switch (packageType) {
case Normal:
deliverer = new Deliverer(this);
break;
case KeepRefrigerated:
deliverer = new DelivererKeepRefrigerated(this);
break;
}
deliverers.add(deliverer);
}
deliverer.goToCollectPackage(this, new Route(centerAddress, customersAddress)); // お客さんの元に集荷へ行かせる
}
public Deliverer searchFreeDeliverer(Package.Content.Type type) {
Deliverer target = null;
for (Deliverer temp : deliverers) {
if (temp.getSupportedPackageType() == type) {
if (!temp.isWorking()) {
target = temp;
break;
}
}
}
return target;
}
public void notifyCompletionOfPackageCollection(Address customersAddress) {
// TODO: 集荷完了記録を更新
Log.d(TAG, "集荷完了 : %s", customersAddress);
}
public void response(boolean success, String message) {
Log.d(TAG, "集荷命令が%s 配達員からのメッセージ : %s", success?"成功":"失敗", message);
if (!success) {
// TODO: 集荷命令が失敗したとき、別の配達員を手配する処理
}
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.service;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.lib.Log;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.town.House;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.town.HouseMap;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.town.Route;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.user.Customer;
import java.util.ArrayList;
import java.util.List;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class Deliverer {
private static final String TAG = "Deliverer";
private Center assignedCenter;
public Deliverer(Center assignedCenter) {
this.assignedCenter = assignedCenter;
}
public Package.Content.Type getSupportedPackageType() {
return Package.Content.Type.Normal;
}
private boolean isWorking = false;
public boolean isWorking() {
return isWorking;
}
private Route routeToMyCenter;
private DriverLicense driverLicense;
private enum PhysicalCondition {
Good, // 通常
SoreThroat, // のどが痛い
Feverish, // 熱がある
}
private PhysicalCondition condition = PhysicalCondition.Good;
public void goToCollectPackage(Center orderedCenter, Route routeToCustomersHouse) {
// 集荷に向かうメソッドの実装例
if (packageList.size() >= PACKAGE_LIST_COUNT_MAX) { // 積載量超過の場合
orderedCenter.response(false, "積載オーバーです!");
return;
}
switch (condition) { // 体調による分岐
case Good:
orderedCenter.response(true, "承知しました!");
drive(routeToCustomersHouse);
break;
case SoreThroat:
orderedCenter.response(true, "承知しました...");
drive(routeToCustomersHouse);
break;
case Feverish:
default:
orderedCenter.response(false, "申し訳ないのですが...");
break;
}
}
private void drive(Route route) {
// TODO: とりあえず一瞬で移動できるとする
isWorking = true;
House arrivedHouse = HouseMap.getHouse(route.to);
if (arrivedHouse != null) {
onArriveAt(arrivedHouse);
}
}
public void onArriveAt(House arrivedHouse) {
// 目的地に到着したときのイベントハンドラ
Customer customer = (Customer) arrivedHouse.ringBell(); // 家のインターホンを鳴らしてお客さんを呼び出す
if (customer != null) {
customer.onArrivedDeliverer(this); //お客さんに到着を知らせる(引数: 自分自身)
}
else {
// TODO: お客さんが不在だった場合
Log.d(TAG, "お客さんが不在!! : %s", arrivedHouse);
}
}
private List<Package> packageList = new ArrayList<Package>();
private static final int PACKAGE_LIST_COUNT_MAX = 10;
public boolean deposit(Package receivedPackage) {
if (packageList.size() >= PACKAGE_LIST_COUNT_MAX) { // 最大積載量を超過していないか確認する
return false;
}
packageList.add(receivedPackage); // 自分の荷物リストに、渡された荷物を追加する
assignedCenter.notifyCompletionOfPackageCollection(receivedPackage.getSrcAddress()); // 所属しているセンターに集荷完了を通知する
// TODO: 一瞬で集荷が完了すると仮定する
isWorking = false;
return true;
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.service;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.lib.Log;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class DelivererKeepRefrigerated extends Deliverer {
private static final String TAG = "DelivererKeepRefrigerated";
public DelivererKeepRefrigerated(Center assignedCenter) {
super(assignedCenter);
}
@Override
public Package.Content.Type getSupportedPackageType() {
return Package.Content.Type.KeepRefrigerated;
}
private Temperature getCurrentTemperature() {
// TODO: ひとまず固定の温度を返す
return new Temperature(Temperature.TEMP_DEGREES_DESIRED_REFRIGERATION);
}
public Temperature regulateTemperatureInside() {
// TODO: 庫内の温度を調整する
return getCurrentTemperature();
}
@Override
public boolean deposit(Package receivedPackage) {
Log.d(TAG, "%sを取り扱います。", receivedPackage.getContentType());
Temperature temp;
temp = regulateTemperatureInside(); // 1. 庫内の温度管理をする
if (temp.isWrong()) {
return false;
}
temp = receivedPackage.checkTemperature(); // 2. 事前に荷物が冷やされているかをチェック
if (temp.isWrong()) {
return false;
}
boolean result = super.deposit(receivedPackage); // 3. 元々の配達員の責務を果たす
return result;
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.service;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class DriverLicense {
private static final String TAG = "DriverLicense";
public DriverLicense() {
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.service;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.town.Address;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class Package {
private static final String TAG = "Package";
public Package(Address srcAddress, Address destAddress, Content content) {
this.srcAddress = srcAddress;
this.destAddress = destAddress;
this.content = content;
checkTemperature();
}
private Address srcAddress;
private Address destAddress;
private Content content;
@Override
public String toString() {
return String.format("送付元 : %s, 送付先 : %s, 送付物 : %s", srcAddress, destAddress, content);
}
public Content.Type getContentType() {
return content.getType();
}
public Address getDestAddress() {
return destAddress;
}
public Address getSrcAddress() {
return srcAddress;
}
public abstract static class Content {
public enum Type {
Normal,
KeepRefrigerated;
@Override
public String toString() {
String temp;
switch (this) {
case Normal:
temp = "通常荷物";
break;
case KeepRefrigerated:
temp = "要冷蔵モノ";
break;
default:
temp = super.toString();
break;
}
return temp;
}
}
abstract public Type getType();
abstract public void open();
@Override
public String toString() {
return getType().toString();
}
}
private Temperature temperature;
public Temperature checkTemperature() {
// TODO: とりあえず固定値を返す
switch (getContentType()) {
case KeepRefrigerated:
temperature = new Temperature(Temperature.TEMP_DEGREES_DESIRED_REFRIGERATION);
break;
default:
temperature = new Temperature(Temperature.TEMP_DEGREES_NORMAL);
break;
}
return temperature;
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.service;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class Temperature {
private static final String TAG = "Temperature";
public static final int TEMP_DEGREES_NORMAL = 20;
public static final int TEMP_DEGREES_DESIRED_REFRIGERATION = -15;
public int temperatureDegrees;
public Temperature(int temperatureDegrees) {
this.temperatureDegrees = temperatureDegrees;
}
public boolean isWrong() {
return (temperatureDegrees > TEMP_DEGREES_DESIRED_REFRIGERATION);
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.service;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class Transporter {
private static final String TAG = "Transporter";
public Transporter() {
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.town;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class Address {
private static final String TAG = "Address";
public String prefecture;
public String city;
public int number;
public Address(String prefecture, String city, int number) {
this.prefecture = prefecture;
this.city = city;
this.number = number;
}
@Override
public String toString() {
return String.format("<%s : %s - %s - %d>", this.getClass().getSimpleName(), prefecture, city, number);
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.town;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class House {
private static final String TAG = "House";
private Address address;
public House(Address address) {
this.address = address;
}
public Address getAddress() {
return address;
}
private People habitant;
public void setHabitant(People habitant) {
this.habitant = habitant;
}
public People ringBell() {
return habitant;
}
@Override
public String toString() {
return String.format("<%s : address=%s>", this.getClass().getSimpleName(), address);
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.town;
import java.util.ArrayList;
import java.util.List;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class HouseMap {
private static final String TAG = "HouseMap";
public static List<House> houses = new ArrayList<House>();
public static House getHouse(Address address) {
House target = null;
for (House house : houses) {
if (house.getAddress().equals(address)) {
target = house;
break;
}
}
return target;
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.town;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class People {
private static final String TAG = "People";
public People() {
}
public void locale(House house) {
house.setHabitant(this);
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.town;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class Route {
private static final String TAG = "Route";
public Address from;
public Address to;
public Route(Address from, Address to) {
this.from = from;
this.to = to;
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.user.content;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.lib.Log;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.service.Package;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class FrozenFood extends Package.Content {
private static final String TAG = "冷凍食品";
public String message;
public String descriptionOfFood;
public FrozenFood(String message, String descriptionOfFood) {
this.message = message;
this.descriptionOfFood = descriptionOfFood;
}
@Override
public Type getType() {
return Type.KeepRefrigerated;
}
@Override
public void open() {
Log.d(TAG, "商品の説明: \"%s\" メッセージ: \"%s\"", descriptionOfFood, message);
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.user.content;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.lib.Log;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.service.Package;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class PostCard extends Package.Content {
private static final String TAG = "はがき";
public String message;
public PostCard(String message) {
this.message = message;
}
@Override
public Type getType() {
return Type.Normal;
}
@Override
public void open() {
Log.d(TAG, "メッセージ: %s", message);
}
}
package com.example.smartphoneappdevelopguide.objectoriented.postsystem.user;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.lib.Log;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.service.Center;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.service.Deliverer;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.service.Package;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.town.Address;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.town.House;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.town.People;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.user.content.FrozenFood;
import com.example.smartphoneappdevelopguide.objectoriented.postsystem.user.content.PostCard;
/**
* Created by sugawaraMBP on 2015/11/12.
*/
public class Customer extends People {
private static final String TAG = "Customer";
private House myHouse;
public Customer() {
}
public void locale(House myHouse) {
this.myHouse = myHouse;
myHouse.setHabitant(this);
}
public void sendSomePackage(Address friendAddress) {
if (myHouse == null) {
Log.e(TAG, "myHouse == null");
return;
}
Package aPackage = createPackage(friendAddress);
deliverPackage(aPackage);
}
private Package createPackage(Address destAddress) {
Package aPackage;
int contentType = (int) (System.currentTimeMillis() % 2);
if (contentType == 0) {
aPackage = new Package(myHouse.getAddress(), destAddress, new PostCard("こんにちは!"));
}
else {
aPackage = new Package(myHouse.getAddress(), destAddress, new FrozenFood("プレゼントをどうぞ!", "高級毛ガニ"));
}
return aPackage;
}
private Package aPackage;
public void deliverPackage(Package aPackage) {
this.aPackage = aPackage;
Log.d(TAG, "荷物を送ります。 [%s]", aPackage);
Address myHouseAddress = myHouse.getAddress();
Center center = Center.nearestCenter(myHouseAddress);
if (center != null) {
center.requireServiceOfPackageCollection(myHouseAddress, aPackage.getContentType());
}
else {
// TODO: 集荷センターが見つからなかった場合
Log.d(TAG, "集荷センターが見つかりませんでした!");
}
}
public void onArrivedDeliverer(Deliverer arrivedDeliverer) {
// 配達員が到着した時のイベントハンドラ
arrivedDeliverer.deposit(aPackage); // 荷物を預ける
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment