まず第一に、この質問は少し長くなりますが、私の問題を完全に説明するために、私のプロジェクトについて多くの情報を提供する必要があると感じていますので、ご容赦ください!
私はチャートを頻繁に使用する会社で働いているので、常に scats からチャートを作成しなければならないという問題を回避するために、新しい Java プロジェクトを作成し、私と同僚がこれらを作成するために使用できる「パッケージ」を作成することにしました。チャート。それらをジェネリックと呼ぶことができます。
したがって、このプロジェクトではビルダー パターンと多くのインターフェイスと抽象クラスを使用します。クライアント (開発者) がこれらのインターフェイス、パターン、およびクラスを使用し、フローに合わせてメソッドをオーバーライドするという考え方です。クライアント (開発者) に残された唯一のことは、これらのメソッドを埋めて、自分で UI を作成し、プログラムを公開することです。
プログラムは順調に進んでおり、非常に誇りに思う機能をたくさん作成しました (私は学生なので)。プロセス全体をうまく計画したと思っていましたが、いくつかの問題に遭遇しました!
まず最初に、クラスを示してデータフローを説明します (できるだけ短くします)。
最初は GUI です (これは、ユーザーが常に自分で作成する必要があるクラスですが、組み込みパッケージを使用して、次のコードを使用してチャートを作成できます)。
ChartBuilder cb = new LineChartBuilder();
Director d = new Director();
d.buildTypeOne(cb, "Hello", PeriodSelection.HOUR,"");
これで、ディレクターはチャートを作成する準備が整いました。
このPeroidSelection.Hour
場合、標準時間を設定する列挙型であり、チャートのカテゴリ軸を開始時間に設定するため、収集されるデータは、1 時間ごとにデータを取得する必要があることを認識します (この場合は 8.00 から 19.00 まで)。これが Enum である理由は、これらのタイプの期間が最終的なものであり、変更できるのは営業日と営業時間のみであり、非常に簡単に変更できるからです! のプレビューは次のPeriodSelection enum
とおりです。
public enum PeriodSelection{
HOUR(new String[]{"8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00"}),
MONTH(new String[]{"Jan", "Feb", "Marts", "April", "Maj", "Juni", "Juli", "Agu", "Sep", "Oct", "Nov", "Dec"}),
DAYS(new String[]{"Mandag", "Tirsdag", "Onsdag","Torsdag","Fredag","Lørdag","Søndag"});
private String[] timeIntervals;
private PeriodSelection(String[] timeIntervals){
this.timeIntervals = timeIntervals;
}
public String[] getTimeIntervals(){
return timeIntervals;
}
}
Director に入ると、director はチャートを作成する準備が整いましたが、最初にデータベースからデータを収集する必要があります。
public void buildTypeOne(ChartBuilder builder, String title, PeriodSelection selection, String queueName){
try {
builder.setObjectList(stat.getData(queueName, start, end));
} catch (DopeDBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
builder.selection = selection;
builder.initiate(title);
builder.createSeries();
builder.createSymbol();
builder.createTable();
}
ご覧のとおり、ビルダーは特定の方法で構築されています。これは、チャートがテーブルとチャートの両方で構成されており、これら 2 つをリンクする必要があるためです。チャートについてはあまり詳しく説明しません。質問。
メソッド extendsの最初の行に示されている stat クラスと、buildTypeOne
呼び出された抽象クラスはstatisticPattern
次のようになります。
public abstract class StatisticPattern {
protected ArrayList<ObjectInterface> cq = new ArrayList<>();
protected ObjectInterface contact;
protected ProviderInterface p;
/**
*
*
* {@link Constructor}
*/
public StatisticPattern(){
try {
p = new Provider();
} catch (DopeDBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
*
* @param name
* @param start
* @param end
* @return
* @throws SQLException
* @throws DopeDBException
*/
protected ArrayList<ObjectInterface> getData(String name, DateTime start, DateTime end) throws SQLException, DopeDBException{
return cq;
}
/**
*
* @param contact2
*/
protected void processSingleQueueData(ObjectInterface contact2) {
}
/**
*
* @param queueName
* @throws SQLException
*/
protected void obtainNewData(String queueName) throws SQLException {
}
/**
*
* @param name
* @param start
* @param end
* @return
*/
protected boolean doIhaveIt(String name, DateTime start, DateTime end) {
return false;
}
/**
*
* @param start
* @param end
* @return
*/
protected boolean checkDatas(DateTime start, DateTime end) {
return start.toDateMidnight().isEqual(end.toDateMidnight());
}
/**
*
* @param start
* @param end
* @return
*/
protected Integer daysBetween(DateTime start, DateTime end) {
return end.dayOfYear().get()-start.dayOfYear().get();
}
前述のように、このクラスの目的は、ディレクタがこれらのメソッドを見つけて使用できるように、開発者がクラスを拡張してメソッドをオーバーライドすることです。これにより、メソッドの実装方法と入力方法はプログラムごとに異なります。
このプログラムでは、統計クラスは次のようになります。
public class Statistics extends StatisticPattern {
private DateTime start;
private DateTime end;
/**
* This class checks whether the program has already collected the data
* @Override
*/
public ArrayList<ObjectInterface> getData(String name, DateTime start, DateTime end) throws DopeDBException{
if (this.start.equals(start) && this.end.equals(end)) {
if (name.equalsIgnoreCase("All")) {
return cq;
}else if (doIhaveIt(name, start, end)) {
return cq;
}
}else {
try {
obtainNewData(name);
} catch (SQLException e) {
e.printStackTrace();
}
}
return cq;
}
@Override
protected void obtainNewData(String queueName) throws SQLException {
setDates(start, end);
this.cq = p.obtainData(start, end, queueName);
}
ご覧のとおり、メソッドの独自の実装を作成しました。getData
このメソッドは、obtainNewData
p (プロバイダー クラス - データベースへの接続とも呼ばれます) からデータを取得するメソッドを呼び出します。
obtainData
ご想像のとおり、プロバイダー クラスは、メソッド内にメソッドが 1 つしかない実装とインターフェイスも備えています。
public interface ProviderInterface {
public ArrayList<ObjectInterface> obtainData(DateTime start, DateTime end, String name) throws SQLException;
}
ここでも、開発者はこのメソッドを実装する必要がありますが、好きなように埋めることができます。ここで最も重要なことは、戻り値の型が ObjectInterface 型の ArrayList であることです。
public interface ObjectInterface {
HashMap<String, Integer> data = new HashMap<String, Integer>();
String type = "";
public String getType();
public void addData(String key, Integer value);
public Integer getData(Object key);
}
基本的に、チャートに入力する必要があるすべてのデータを含むハッシュマップを実装する必要があります。このデータは、オブジェクトの作成時に追加され、プロバイダのリストに追加されます。このリストが返され、Director はそれを chartbuilders のデータ リストに設定し、チャートを埋めます。
この場合、チャートを埋めなければならない最終的なオブジェクトは次のようになります。
public class ContactQueue implements ObjectInterface {
private HashMap<String, Integer> data = new HashMap<String, Integer>();
private String type;
public ContactQueue(String type){
this.type = type;
}
public String getType(){
return type;
}
public void addData(String key, Integer value){
if (data.containsKey(key)) {
Integer i = data.get(key);
data.put(key, value+i);
}else {
data.put(key, value);
}
}
public Integer getData(Object key){
return data.get(key);
}
public String toString(){
return type;
}
}
では質問へ!
収集するデータが 1 種類しかない場合、これらはすべて完全に機能します。しかし、私が現在取り組んでいるプログラムは、5 つの異なるテーブルからデータを取得する必要があり、そのすべてを各チャートに追加する必要があります。データベース テーブルを選択するように設計するにはどうすればよいですか? その特定のテーブルのリストを返しますか?
私はすでに次のコードで試しました:
if (name.equalsIgnoreCase("Besvarelse")) {
return besvarelse25(start, end);
}else if (name.equalsIgnoreCase("intern")) {
return intern(start, end);
}else if (name.equalsIgnoreCase("besvarelseProcent")) {
return besvarelseProcent(start,end);
}else if (name.equalsIgnoreCase("Email_data")) {
return email_data(start, end);
}else if (name.equalsIgnoreCase("Email_Hånd")) {
return email_haand(start, end);
}else if (name.equalsIgnoreCase("Email_Antal")) {
return email_antal(start, end);
}
else if (name.equalsIgnoreCase("Henvendelser")) {
return henvendelser(start, end);
}
ただし、控えめに言っても、それはちょっと冗長で醜いようです。
クライアント(開発者)が新しいプログラムを作成するたびに変更しなければならない Enum を再度作成することを考えましたが、これが正しい方法であるかどうかはわかりません。
また、プロジェクト全体についてどう思いますか?私はそれを釘付けにしましたか、それとも失敗しましたか?
読んでくれてありがとう、私はあなたの返事を読むのを楽しみにしています