JAVA学習(二):どのように対象に向かうか

6588 ワード

JAvaはオブジェクト向けのプログラミング言語ですが、オブジェクト向けのプログラミングとは何ですか.簡単に言えば、適当な相手を探して適当なことをすることです.生活の例を挙げると、一人でプログラムを開発したいのですが、彼はプログラミングができません.どうすればいいですか.彼は自分でプログラミングを学ぶことができて、マスターして、再開発して、これは過程に向かうやり方で、特徴は何でも自分で経験して、プロジェクトに対するコントロール性は比較的に良くて、しかし効率は低いです.もう一つの方法は、彼自身がプログラミングができないので、プログラミングができる人を探して、開発を手伝ってあげます.これは対象に向かうやり方で、多くのことは自分でやるのではなく、他の人に代わってやるのが特徴です.このようなやり方は、効率が高いが、プロジェクトに対するコントロール性が欠けている.他の人が作ったものは、あなたが望んでいるものではない可能性が高い.
Javaでは、オブジェクト向けの編集思想をどのように応用すればいいのでしょうか.例えば、ユーザーがログインする機能を作るには、ユーザー名とパスワードが8-16ビットである必要があります.この機能はどうすればいいですか?多くの開発者は、ユーザー名とパスワードのルール判断をControllerに入れるのがプロセス向けです.オブジェクト向けのアプローチ、ユーザー名、パスワードのルールで判断する場合は、オブジェクトに置くべきです.Userクラスを定義して、フロントエンドから送信されたユーザー名とパスワードを受信できます.クラスを定義すると、このクラスの属性は、どのようなデータを受信できるか、クラスで定義するのが最善の論理です.Userクラスには属性usernameがあり、フロントエンドから送られてきたユーザ名を受信すると、Userクラスの定義では、usernameを限定することができ、8〜16ビットでなければならない.このように、Userクラスのインスタンスこそ、適切なオブジェクトである.そしてControllerでは,判断をする必要はなく,Userクラスの対象に判断を任せる.これが適当な相手を探して適当なことをすることです.では、コードでは、このような機能をどのように実現すればいいのでしょうか.
package king;

public class User {

	private String username;
	private String password;

	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		if(username == null){
			return;
		}
		username = username.trim();
		if("".equals(username)){
			
		}else if(username.length()<8){
			
		}else if(username.length()>16){
			
		}else{
			this.username = username;
		}
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		if(password == null){
			return;
		}
		password = password.trim();
		if("".equals(password)){
			
		}else if(password.length()<8){
			
		}else if(password.length()>16){
			
		}else{
			this.password = password;
		}
	}
	@Override
	public String toString() {
		return "User [username=" + username + ", password=" + password + "]";
	}
}

このようにクラスの定義はsetメソッドでusernameとpasswordが規定されており,どのようなデータを受信できるか,現在の問題は,前述の異常データの判断において,どのように処理すべきかである.もしデータフォーマットが要求に合わないならば、それはきっとコントローラにフィードバックしなければならなくて、更にコントローラから、フロントエンドにフィードバックして、どのようにフィードバックしますか?この場合、例外メカニズムを使用します.データが要求に合わない場合は、例外を放出しますが、この例外は、プログラム内の他の異常とは異なります.そのため、この例外は、カスタムの例外を使用する必要があります.
package king;

public class KingException extends Exception {

	private static final long serialVersionUID = 1L;

	public KingException(){
		super();
	}
	
	public KingException(String message){
		super(message);
	}
	
}

これで、カスタムの異常が発生しました.そして、Userクラスのsetメソッドでは、データが要求に合わない場合、この異常を投げ出します.コード:
package king;

public class User {

	private String username;
	private String password;

	public String getUsername() {
		return username;
	}
	public void setUsername(String username) throws KingException {
		if(username == null){
			throw new KingException("    !");
		}
		username = username.trim();
		if("".equals(username)){
			throw new KingException("       !");
		}else if(username.length()<8){
			throw new KingException("       8 !");
		}else if(username.length()>16){
			throw new KingException("        16 !");
		}else{
			this.username = username;
		}
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) throws KingException {
		if(password == null){
			throw new KingException("    !");
		}
		password = password.trim();
		if("".equals(password)){
			throw new KingException("      !");
		}else if(password.length()<8){
			throw new KingException("      8 !");
		}else if(password.length()>16){
			throw new KingException("       16 !");
		}else{
			this.password = password;
		}
	}
	@Override
	public String toString() {
		return "User [username=" + username + ", password=" + password + "]";
	}
}

では、Controllerで、Userクラスのオブジェクトに値を付けるときは、この異常をキャプチャし、異常のgetMessage()メソッドを呼び出して、異常のヒント語を、フロントエンドに応答します.
クラスでデータルールを判断するのは、Controllerで判断するより、何のメリットがあるのでしょうか.メリットは、コード量が減少し、メンテナンスが向上することです.オブジェクトの中で判断すると,フロントエンドからのエラーデータだけでなく,データベース内のエラーデータ,プログラムへのアクセス,コードの繰り返し書き込みも阻止できる.Controllerに書かれている場合は、アカウントの登録、ログイン、パスワードの変更など、いくつかのインタフェースに判断ロジックを書かなければなりません.これは大量の重複コードを生成します.ルールが変更されると、いくつかの場所を修正しなければなりません.うっかりすると、修正していない場所が漏れてしまいます.考えてみれば恐ろしい!
もう一つの問題を見ると、多くの場合、私たちがメソッドを呼び出すのは、反射によって呼び出されます.では、メソッド自体が投げ出した異常を反射によってどのように取得するかは、実は簡単です.
package king;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Controller {
	
	public static void main(String[] args) {
		test();
	}
	
	public static void test(){
		User user = new User();
		Class clazz = User.class;
		Method method;
		try {
			method = clazz.getMethod("setUsername", String.class);
			method.invoke(user, "123");
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			Throwable t = e.getTargetException();
			if(t instanceof KingException){
				System.out.println(t.getMessage());
			}
		}
	}
}

ポイントは一番後ろのcatchで、e.getTargetException()を通して、メソッド自体が投げ出す異常を取得し、まず異常のタイプがKingExceptionと一致すれば、対応する処理ができると判断します.もし一致しなければ、それはプログラムが投げ出した他の異常で、これはプログラムのバグかもしれません.もちろん、私のところにはelse分岐は書いていません.プログラムを実行すると、ユーザー名が8ビット未満ではないことが印刷されます.
さらに,オブジェクトとjson変換に用いるjacksonパケットが,オブジェクトとjson変換の際にメソッド自体の異常をどのように取得するかを見る.
package king;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Controller {
	
	public static void main(String[] args) throws KingException {
		String json = "{\"username\":\"1223\",\"password\":\"32651\"}";
		ObjectMapper mapper = new ObjectMapper();
		try {
			User user = mapper.readValue(json, User.class);
			System.out.println(user);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			Throwable t = e.getCause();
			if(t instanceof KingException){
				throw (KingException) t;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}

ここでは,最後から2番目のcatchにおいて,e.getCause()メソッドにより,メソッド自体が投げ出す異常を取得することに重点を置く.
これらを知って、自分の方法をカプセル化することができますか?
テストグループに参加することを歓迎します:91425817、一緒にテストのことを討論します.