憋在家裏的第8天,今天開始進入結構型設計模式。java
結構型設計模式是從程序的結構上解決模塊之間的耦合問題。設計模式
定義:爲其餘對象提供一種代理以控制對這個對象的訪問。安全
這個模式的幾個角色分爲如下:ide
這個模式就像你和代購的存在同樣,你提出需求,由代購來幫你購買。這個句子裏基本上就歸納了整個代理模式的全貌。客戶端就是咱們需求者,而真實主題就是你要找的代購幫你買,最後一個代理,找誰買。 如下用代碼表示靜態代理。post
/** * 抽象主題類 * 中心主題,買東西。 */
public interface Shop {
void buy();
}
/** * 真實主題類 * 有這麼一我的,能夠幹這件事,他就是代理 */
public class Person implements Shop {
@Override
public void buy() {
System.out.println("購買");
}
}
/** * 代理類 * 你要告訴本身找那個代購買 */
public class WhoBuy implements Shop {
private Shop shop;
WhoBuy(Shop shop){
this.shop = shop;
}
@Override
public void buy() {
shop.buy();
}
}
/** * 客戶端類 * 就是這個想買東西的人了 */
public class User {
public static void main(String[] args) {
Shop person = new Person();
Shop purchase = new WhoBuy(person);
purchase.buy();
}
}
複製代碼
靜態代理,主要是爲了讓人更好的理解代理模式。在開發中主要仍是使用反射機制來完成的,也就是動態代理模式。學習
/** * 動態代理類 */
public class DynamicPurchase implements InvocationHandler {
private Object object;
DynamicPurchase(Object object){
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(object, args);
if(method.getName().equals("buy")){
System.out.println("買上");
}
return result;
}
}
/** * 客戶端類 */
public class User {
public static void main(String[] args) {
Shop person = new Person();
DynamicPurchase dynamicPurchase = new DynamicPurchase(person);
ClassLoader loader = person.getClass().getClassLoader();
Shop purchase = (Shop) Proxy.newProxyInstance(loader, new Class[]{Shop.class}, dynamicPurchase);
purchase.buy();
}
}
複製代碼
和靜態代理的不一樣就在於代理類,使用反射機制。 這種代理模式的優勢:this
動態地給一個對象添加一些額外的職責。spa
這個模式的角色有:設計
人是一個慢慢學習的生物,從一開始只會咿咿呀呀,通過學習,學會了數學,英語。這個時候數學、英語,兩個科目就是一種裝飾了。代理
/** * 抽象組件 * 做爲一我的,必然會有學習的能力。 */
public abstract class Person {
public abstract void learn();
}
/** * 組件具體實現類 * 人一開始只會咿咿呀呀 */
public class Me extends Person {
@Override
public void learn() {
System.out.println("咿咿呀呀");
}
}
/** * 抽象裝飾類 * 有一個老師教書育人 */
public abstract class Teacher extends Person {
private Person person;
Teacher(Person person){
this.person = person;
}
@Override
public void learn() {
person.learn();
}
}
/** * 裝飾具體類 * 這個老師教數學,也就教會了孩子 */
public class MathTeacher extends Teacher {
MathTeacher(Person person) {
super(person);
}
public void teach(){
System.out.println("學會了數學");
}
@Override
public void learn() {
super.learn();
teach();
}
}
// 具體使用
public class Main {
public static void main(String[] args) {
Person person = new Me();
MathTeacher mathTeacher = new MathTeacher(person);
mathTeacher.learn();
}
}
複製代碼
優勢:
Component
,若是Component
發生了改變,子類必然收到巨大的衝擊。要求一個子系統 的外部與內部的通訊必須經過一個統一的對象進行。
這個模式的角色有:
這裏以爲以前看到的武俠的例子很是好。 一個武俠自己分爲招式、內功、經脈三個系統,每次放招都是根據三個子系統的合理使用來釋放。
/** * 三大子系統 */
public class 經脈 {
public void jingmai(){
System.out.println("開啓經脈");
}
}
public class 內功 {
public void JiuYang(){
System.out.println("使用九陽神功");
}
public void QianKun(){
System.out.println("使用乾坤大挪移");
}
}
public class 招式 {
public void QiShangQuan(){
System.out.println("使用七傷拳");
}
public void ShengHuoLing(){
System.out.println("使用聖火令");
}
}
/** * 外觀類 * 也就是張無忌 */
public class 張無忌 {
private JingMai jingMai;
private NeiGong neiGong;
private ZhaoShi zhaoShi;
張無忌(){
jingMai = new JingMai();
neiGong = new NeiGong();
zhaoShi = new ZhaoShi();
}
public void QianKun(){
jingMai.jingmai();
neiGong.QianKun();
}
public void QiShang(){
jingMai.jingmai();
neiGong.JiuYang();
zhaoShi.QiShangQuan();
}
}
複製代碼
給外人看到的只有張無忌的出招是七傷拳,可是不知道內部的具體操做,這也就是外觀類的總體展示方式了。 優勢:
使用共享對象有效地支持大量細粒度的對象。
該模式下的對象有
其實往簡單了說就是一種緩衝池的技術。
/** * 享元工廠 */
public class VipFactory {
private static Map<String, Vip> cache = new HashMap<>();
public static Vip getVip(String number){
if(cache.containsKey(number)){
return cache.get(number);
}else{
Vip vip = new Vip(number);
cache.put(number, vip);
return vip;
}
}
}
/** * 享元角色 */
public class Vip implements IVip {
private String name;
private String number;
Vip(String number){
this.number = number;
}
@Override
public void showVip(String number) {
if (number.equals(number)) {
System.out.println(name == null? "空": name);
}
}
}
/** * 享元抽象角色 */
public interface IVip {
void showVip(String number);
}
複製代碼
在享元工廠中咱們顯而易見的看到了由static
修飾的cache
變量,這就是一個緩衝,若是緩衝中存在,就從緩衝中取,不存在則建立。
以上就是個人學習成果,若是有什麼我沒有思考到的地方或是文章內存在錯誤,歡迎與我分享。
相關文章推薦: