Pola desain (Pola desain) adalah sekumpulan ringkasan pengalaman desain kode yang diklasifikasikan dan dikatalogkan yang digunakan berulang kali, diketahui oleh kebanyakan orang.
Pola desain dibagi menjadi tiga jenis, dengan total 23 jenis:
Ditulis dengan mengacu pada artikel di Hongyang, Tutorial Pemula, dll. Mohon koreksi saya jika ada kesalahan. Jika ada pelanggaran, silakan hubungi saya untuk menghapusnya.
1. Pola desain Pola Pengamat (Observer Pattern) Mengambil contoh layanan publik WeChat
2. Pola Desain Pola Pabrik (Factory Pattern) dimulai dengan penjualan Roujiamo
3. Pola Desain Pola Singleton (Singleton Pattern) Analisis Lengkap
4. Pola Desain Pola strategi (Strategy Pattern) mengambil permainan peran sebagai latar belakangnya
5. Pola Desain Pola Adaptor (Adapter Pattern) Ambil contoh charger ponsel
6. Pola Perancangan Pola Perintah untuk mengelola peralatan rumah pintar
7. Pola Desain Pola Dekorator membawa Anda kembali ke dunia legendaris
8. Mode desain, mode tampilan (Pola Fasad), mode film sekali klik
9. Metode Desain Pola Template Pola menunjukkan hari seorang programmer
10. Pola Desain Pola Negara (State Pattern) Ambil contoh mesin penjual otomatis
11. Pola Pembangun Pola Desain (Builder Pattern) Ambil contoh pembuatan mobil dan pembelian mobil
12. Pola Desain Pola Prototipe (Pola Prototipe) Ambil beberapa bentuk sebagai contoh
13. Pola desain Pola Kelas Terbang (Flyweight Pattern) mengambil beberapa bentuk secara acak sebagai contoh
14. Pola Desain Pola Proxy (Pola Proxy) Ambil gambar dari disk sebagai contoh
15. Pola Desain Pola Jembatan (Bridge Pattern) Ambil contoh gambar lingkaran dengan warna berbeda
16. Pola kombinasi pola desain (Pola Komposit) Ambil contoh pembuatan dan pencetakan hierarki karyawan
17. Pola Desain Pola Iterator (Pola Iterator) Ambil contoh penggunaan iterator untuk mencetak nama
18. Pola Perancangan Pola Mediator (Mediator Pattern) Mengambil contoh ruang obrolan publik
19. Desain Pola Memento Pattern (Pola Memento) Ambil contoh Memento
20. Pola Desain Pola Interpreter (Interpreter Pattern) Ambil penjelasan sebuah kalimat sebagai contoh
21. Pola desain pola rantai tanggung jawab (Chain of Responsibility Pattern) Ambil log pencetakan di Android Studio sebagai contoh
22. Pola Desain Pola Pengunjung (Visitor Pattern) Ambil contoh tampilan komponen komputer
- Pengamat
- Pabrik
- Lajang
- Strategi
- Adaptor
- Memerintah
- Penghias
- Fasad
- Metode Templat
- Negara
- Pembangun
- Prototipe
- Kelas terbang
- Proksi
- Menjembatani
- Gabungan
- Pengulangan
- Penengah
- Kenang-kenangan
- Rantai Tanggung Jawab
- Pengunjung
Mendefinisikan ketergantungan satu-ke-banyak antar objek, sehingga ketika suatu objek berubah, semua ketergantungannya akan diberitahukan dan diperbarui secara otomatis.
Ada banyak tempat di JDK atau Andorid yang menerapkan pola pengamat, seperti XXXView.addXXXListenter. Tentu saja XXXView.setOnXXXListener belum tentu merupakan pola pengamat, karena pola pengamat adalah hubungan satu-ke-banyak, dan untuk setXXXListener, itu adalah satu pasangan. Hubungan antara 1 dan 1 harus disebut panggilan balik.
Antarmuka khusus: Subject.java;
/**
* 注册一个观察者
*/
public void registerObserver ( Observer observer );
/**
* 移除一个观察者
*/
public void removeObserver ( Observer observer );
/**
* 通知所有观察者
*/
public void notifyObservers ();
Kelas implementasi akun layanan 3D: ObjectFor3D.java
@ Override
public void registerObserver ( Observer observer ) {
observers . add ( observer );
}
@ Override
public void removeObserver ( Observer observer ) {
int index = observers . indexOf ( observer );
if ( index >= 0 ) {
observers . remove ( index );
}
}
@ Override
public void notifyObservers () {
for ( Observer observer : observers ) {
observer . update ( msg );
}
}
/**
* 主题更新信息
*/
public void setMsg ( String msg ) {
this . msg = msg ;
notifyObservers ();
}
Semua pengamat perlu mengimplementasikan antarmuka ini: Observer.java
public ObserverUser1 ( Subject subject ) {
subject . registerObserver ( this );
}
@ Override
public void update ( String msg ) {
Log . e ( "-----ObserverUser1 " , "得到 3D 号码:" + msg + ", 我要记下来。" );
}
Tes akhir: ObserverActivity.java
// 创建服务号
objectFor3D = new ObjectFor3D ();
// 创建两个订阅者
observerUser1 = new ObserverUser1 ( objectFor3D );
observerUser2 = new ObserverUser2 ( objectFor3D );
// 两个观察者,发送两条信息
objectFor3D . setMsg ( "201610121 的3D号为:127" );
objectFor3D . setMsg ( "20161022 的3D号为:000" );
Mari kita daftar secara singkat kelompok pola ini:
1. Mode pabrik statis
2. Mode pabrik sederhana (membeli Roujiamo di toko)
public RoujiaMo creatRoujiaMo ( String type ) {
RoujiaMo roujiaMo = null ;
switch ( type ) {
case "Suan" :
roujiaMo = new ZSuanRoujiaMo ();
break ;
case "La" :
roujiaMo = new ZLaRoujiaMo ();
break ;
case "Tian" :
roujiaMo = new ZTianRoujiaMo ();
break ;
default : // 默认为酸肉夹馍
roujiaMo = new ZSuanRoujiaMo ();
break ;
}
return roujiaMo ;
}
3. Model metode pabrik (membuka cabang)
Menyediakan metode abstrak untuk membuat Roujia MoStore: RoujiaMoStore.java
public abstract RoujiaMo sellRoujiaMo ( String type );
Implementasi khusus metode abstrak: XianRoujiaMoStore.java
Cabang tersebut masih menggunakan model pabrik sederhana: XianSimpleRoujiaMoFactory.java
4. Pola pabrik abstrak (menggunakan bahan baku resmi)
/**
* 准备工作
*/
public void prepare ( RoujiaMoYLFactory roujiaMoYLFactory ) {
Meet meet = roujiaMoYLFactory . creatMeet ();
YuanLiao yuanLiao = roujiaMoYLFactory . creatYuanLiao ();
Log . e ( "---RoujiaMo:" , "使用官方的原料 ---" + name + ": 揉面-剁肉-完成准备工作 yuanLiao:" + meet + "yuanLiao:" + yuanLiao );
}
Mode singleton terutama untuk menghindari pemborosan sumber daya yang disebabkan oleh pembuatan banyak instance, dan banyak instance dapat dengan mudah menyebabkan hasil yang salah karena banyak panggilan. Menggunakan mode singleton dapat memastikan bahwa hanya ada satu instance di seluruh aplikasi .
Definisi: Hanya diperlukan tiga langkah untuk memastikan keunikan suatu objek
Bandingkan definisi:
Gaya Hungry Han [tersedia]: SingletonEHan.java
Berisi gaya Han malas [disarankan kunci verifikasi ganda]: SingletonLanHan.java
private SingletonLanHan () {}
private static SingletonLanHan singletonLanHanFour ;
public static SingletonLanHan getSingletonLanHanFour () {
if ( singletonLanHanFour == null ) {
synchronized ( SingletonLanHan . class ) {
if ( singletonLanHanFour == null ) {
singletonLanHanFour = new SingletonLanHan ();
}
}
}
return singletonLanHanFour ;
}
Pola strategi: Mendefinisikan sekumpulan algoritme dan merangkumnya secara terpisah agar dapat dipertukarkan. Pola ini memungkinkan perubahan algoritme tidak bergantung pada pelanggan yang menggunakan algoritme tersebut.
RoleA roleA = new RoleA ( "---A" );
roleA . setiDisplayBehavior ( new DisplayYZ ())
. setiAttackBehavior ( new AttackXL ())
. setiDefendBehavior ( new DefendTMS ())
. setiRunBehavior ( new RunJCTQ ());
roleA . display (); // 样子
roleA . attack (); // 攻击
roleA . run (); // 逃跑
roleA . defend (); // 防御
Definisi: Mengubah antarmuka suatu kelas menjadi antarmuka lain yang diharapkan oleh klien. Adaptor mengizinkan kelas dengan antarmuka yang tidak kompatibel untuk bekerja sama satu sama lain. Definisi ini sah-sah saja, mengatakan bahwa fungsi adaptor adalah mengubah antarmuka yang satu menjadi antarmuka yang lain.
Ambil contoh pengisi daya: Pengisi daya ponsel umumnya sekitar 5V.Tegangan AC rumah tangga kami di China adalah 220V, jadi pengisian daya ponsel memerlukan adaptor (peredam tegangan).
Ponsel: Mobile.java
Ponsel ini mengandalkan antarmuka yang menyediakan tegangan 5V: V5Power.java
Yang kami miliki adalah AC rumah tangga 220V: V220Power.java
Adaptor untuk melengkapi fungsi mengubah 220V ke 5V : V5PowerAdapter.java
Tes terakhir: Isi daya telepon:
Mobile mobile = new Mobile ();
V5Power v5Power = new V5PowerAdapter ( new V200Power ());
mobile . inputPower ( v5Power );
Definisi: Merangkum "permintaan" ke dalam objek sehingga objek lain dapat diparameterisasi menggunakan permintaan, antrean, atau log yang berbeda. Mode perintah juga mendukung operasi yang tidak dapat dilakukan. (Penyederhanaan: Enkapsulasi permintaan menjadi sebuah objek dan pisahkan peminta tindakan dan pelaksana tindakan.)
QuickCommand quickCloseCommand = new QuickCommand ( new Command []{ new LightOffCommand ( light ), new ComputerOffCommand ( computer ), new DoorCloseCommand ( door )});
controlPanel . setCommands ( 6 , quickOpenCommand );
controlPanel . keyPressed ( 6 );
controlPanel . setCommands ( 0 , new DoorOpenCommand ( door )); // 开门
controlPanel . keyPressed ( 0 );
Pola Dekorator: Untuk memperluas fungsionalitas, dekorator memberikan alternatif integrasi yang lebih fleksibel, secara dinamis melampirkan tanggung jawab pada objek.
Mari kita jelaskan secara singkat di mana pola dekorator berperan. Saat kita mendesain sebuah kelas, kita perlu menambahkan beberapa fungsi tambahan ke kelas ini, dan kita tidak ingin mengubah kode kelas ini bermain. Sudah waktunya. Hal ini juga mencerminkan sebuah prinsip: kelas harus terbuka untuk perluasan dan tertutup untuk modifikasi.
Persyaratan: Merancang sistem perlengkapan dalam game. Persyaratan dasarnya adalah mampu menghitung kekuatan serangan dan deskripsi setiap perlengkapan setelah ditanamkan berbagai permata:
1. Peralatan kelas super: IEquip.java
2. Kelas implementasi masing-masing peralatan:
3. Dekorasi kelas super (dekorasi juga termasuk peralatan): IEquipDecorator.java
4. Implementasi dekorasi kelas:
5. Tes akhir: Hitung kekuatan serangan dan lihat deskripsi:
Log . e ( "---" , "一个镶嵌2颗红宝石,1颗蓝宝石的靴子: " );
IEquip iEquip = new RedGemDecorator ( new RedGemDecorator ( new BlueGemDecorator ( new ShoeEquip ())));
Log . e ( "---" , "攻击力:" + iEquip . caculateAttack ());
Log . e ( "---" , "描述语:" + iEquip . description ());
Definisi: Menyediakan antarmuka terpadu untuk mengakses sekelompok antarmuka dalam subsistem. Tampilannya mendefinisikan antarmuka tingkat tinggi untuk membuat subsistem lebih mudah digunakan. Faktanya, demi kenyamanan pelanggan, sekelompok operasi diringkas menjadi sebuah metode.
Permintaan: Saya lebih suka menonton film, jadi saya membeli proyektor, komputer, stereo, mendesain pencahayaan di dalam ruangan, dan membeli mesin popcorn. Kemudian ketika saya ingin menonton film, saya perlu menonton sekali klik dan mematikannya sekali klik .
Peralihan dan operasi lainnya untuk setiap kelas perangkat:
misalnya: Mesin popcorn: PopcornPopper.java
Kelas bioskop: HomeTheaterFacade.java
/**
* 一键观影
*/
public void watchMovie () {
computer . on ();
light . down ();
popcornPopper . on ();
popcornPopper . makePopcorn ();
projector . on ();
projector . open ();
player . on ();
player . make3DListener ();
}
Tes terakhir: menonton film sekali klik:
new HomeTheaterFacade ( computer , light , player , popcornPopper , projector ). watchMovie ();
Definisi: Mendefinisikan kerangka suatu algoritma dan mengalihkan beberapa langkah ke subkelas. Metode templat memungkinkan subkelas untuk mendefinisikan ulang langkah-langkah algoritma tanpa mengubah struktur algoritma.
Persyaratan: Jelaskan secara singkat: Perusahaan kami memiliki pemrogram, penguji, SDM, manajer proyek, dll. Mode metode templat digunakan di bawah ini untuk mencatat status pekerjaan semua personel.
Tiga jenis peran dalam pola metode templat
1. Metode Konkrit
2. Metode Abstrak
3. Metode Kait
Kelas super pekerja: Worker.java
// 具体方法
public final void workOneDay () {
Log . e ( "workOneDay" , "-----------------work start----------------" );
enterCompany ();
work ();
exitCompany ();
Log . e ( "workOneDay" , "-----------------work end----------------" );
}
// 工作 抽象方法
public abstract void work ();
// 钩子方法
public boolean isNeedPrintDate () {
return false ;
}
private void exitCompany () {
if ( isNeedPrintDate ()) {
Log . e ( "exitCompany" , "---" + new Date (). toLocaleString () + "--->" );
}
Log . e ( "exitCompany" , name + "---离开公司" );
}
Kelas implementasi programmer (waktu dapat diketahui): ITWorker.java
/**
* 重写父类的此方法,使可以查看离开公司时间
*/
@ Override
public boolean isNeedPrintDate () {
return true ;
}
Tes akhir:
Lihat bagaimana semua orang bekerja:
QAWorker qaWorker = new QAWorker ( "测试人员" );
qaWorker ();
HRWorker hrWorker = new HRWorker ( "莉莉姐" );
hrWorker . workOneDay ();
...
Periksa kapan programmer meninggalkan perusahaan:
ITWorker itWorker = new ITWorker ( "jingbin" );
itWorker . workOneDay ();
Definisi: Mengizinkan suatu objek mengubah perilakunya ketika keadaan internalnya berubah, membuat objek tampak seolah-olah telah mengubah kelasnya.
Definisinya mulai kabur lagi. Coba pikirkan ketika keadaan internal suatu objek berubah, perilakunya berubah seiring dengan perubahan keadaan tersebut.
Persyaratan: Ambil contoh mesin penjual otomatis (ada status seperti koin dimasukkan dan tidak dimasukkan koin, serta metode memasukkan koin dan mengembalikan koin)
Implementasi awal mesin penjual otomatis yang perlu ditingkatkan: VendingMachine.java
Mesin penjual otomatis yang ditingkatkan (lebih mudah dibentuk): VendingMachineBetter.java
// 放钱
public void insertMoney () {
currentState . insertMoney ();
}
// 退钱
public void backMoney () {
currentState . backMoney ();
}
// 转动曲柄
public void turnCrank () {
currentState . turnCrank ();
if ( currentState == soldState || currentState == winnerState ) {
currentState . dispense (); //两种情况会出货
}
}
// 出商品
public void dispense () {
Log . e ( "VendingMachineBetter" , "---发出一件商品" );
if ( count > 0 ) {
count --;
}
}
// 设置对应状态
public void setState ( State state ) {
this . currentState = state ;
}
Antarmuka negara: State.java
Kelas implementasi antarmuka yang sesuai dengan negara bagian:
Tes mesin penjual otomatis yang ditingkatkan:
// 初始化售货机,且里面有3个商品
VendingMachineBetter machineBetter = new VendingMachineBetter ( 3 );
machineBetter . insertMoney ();
machineBetter . turnCrank ();
Mode konstruksi adalah mode pembuatan objek. Mode konstruksi dapat memisahkan representasi internal suatu produk dari proses produksi produk tersebut, sehingga suatu proses konstruksi dapat menghasilkan objek produk dengan representasi internal yang berbeda.
Persyaratan: Pengguna pergi ke toko mobil untuk membeli mobil.
Analisis: Bengkel mobil mengekstrak mobil yang sesuai sesuai dengan kebutuhan setiap pengguna
Superkelas pembangun: Pembangun
public abstract class Builder {
public abstract void setPart ( String name , String type );
public abstract Product getProduct ();
}
Kelas implementasi yang sesuai dengan Builder: ConcreteBuilder
public class ConcreteBuilder extends Builder {
private Product product = new Product ();
@ Override
public void setPart ( String name , String type ) {
product . setName ( name );
product . setType ( type );
}
@ Override
public Product getProduct () {
return product ;
}
}
Manajer toko mengambil mobil:
// 店长
Director director = new Director ();
// 得到宝马汽车,内部实现提取宝马汽车的详情操作
Product product = director . getBProduct ();
// 展示汽车信息
product . showProduct ();
Pola prototipe digunakan untuk membuat objek berulang sambil memastikan kinerja. Jenis pola desain ini merupakan pola kreasi yang menyediakan cara optimal untuk membuat objek.
Pola ini mengimplementasikan antarmuka prototipe yang digunakan untuk membuat tiruan dari objek saat ini. Mode ini digunakan ketika biaya pembuatan objek secara langsung relatif tinggi. Misalnya, sebuah objek perlu dibuat setelah operasi database yang mahal. Kita dapat menyimpan objek dalam cache, mengembalikan tiruannya pada permintaan berikutnya, dan memperbarui database bila diperlukan untuk mengurangi panggilan database.
Mengambil beberapa bentuk sebagai contoh, ada empat langkah:
1. Buat kelas abstrak yang mengimplementasikan antarmuka Cloneable. Bentuk (mengimplementasikan Cloneable)
public abstract class Shape implements Cloneable {
private String id ;
protected String type ;
public abstract void draw ();
public String getId () {
return id ;
}
public void setId ( String id ) {
this . id = id ;
}
@ Override
public Object clone () {
Object object = null ;
try {
object = super . clone ();
} catch ( CloneNotSupportedException e ) {
Log . e ( "--" , e . getMessage ());
}
return object ;
}
}
2. Buat kelas entitas yang memperluas kelas abstrak di atas. Lingkaran, Persegi Panjang, Kotak
public class Circle extends Shape {
public Circle () {
type = "Circle" ;
}
@ Override
public void draw () {
Log . e ( "---" , "Inside Circle::draw() method." );
}
}
3. Buat kelas untuk mendapatkan kelas entitas dari database dan menyimpannya dalam Hashtable. BentukCache
public class ShapeCache {
private static Hashtable < String , Shape > shapeMap = new Hashtable < String , Shape >();
public static Shape getShape ( String shapeId ) {
Shape shapeCache = shapeMap . get ( shapeId );
return ( Shape ) shapeCache . clone ();
}
// 对每种形状都运行数据库查询,并创建该形状
// shapeMap.put(shapeKey, shape);
// 例如,我们要添加三种形状
public static void loadCache () {
Circle circle = new Circle ();
circle . setId ( "1" );
shapeMap . put ( circle . getId (), circle );
Rectangle rectangle = new Rectangle ();
rectangle . setId ( "2" );
shapeMap . put ( rectangle . getId (), rectangle );
Square square = new Square ();
square . setId ( "3" );
shapeMap . put ( square . getId (), square );
}
}
4. Gunakan kelas ShapeCache untuk mendapatkan tiruan dari bentuk yang disimpan di Hashtable.
// 使用 ShapeCache 类来获取存储在 Hashtable 中的形状的克隆。
ShapeCache . loadCache ();
Shape shapeCache1 = ShapeCache . getShape ( "1" );
Shape shapeCache2 = ShapeCache . getShape ( "2" );
Shape shapeCache3 = ShapeCache . getShape ( "3" );
Terutama digunakan untuk mengurangi jumlah objek yang dibuat untuk mengurangi penggunaan memori dan meningkatkan kinerja. Jenis pola desain ini adalah pola struktural, yang menyediakan cara untuk mengurangi jumlah objek dan dengan demikian meningkatkan struktur objek yang dibutuhkan oleh aplikasi.
Pola kelas terbang mencoba menggunakan kembali objek yang sudah ada dengan tipe yang sama, atau membuat objek baru jika tidak ditemukan objek yang cocok. Kita akan mendemonstrasikan pola ini dengan membuat 5 objek yang menggambar 20 lingkaran di lokasi berbeda. Karena hanya tersedia 5 warna, maka properti color digunakan untuk memeriksa objek Lingkaran yang ada.
Mengambil beberapa bentuk secara acak sebagai contoh, ada empat langkah:
1. Buat antarmuka.
public interface Shape {
void draw ();
}
2. Buat kelas entitas yang mengimplementasikan antarmuka.
public class Circle implements Shape {
private String color ;
private int x ;
private int y ;
private int radius ;
public Circle ( String color ) {
this . color = color ;
}
public void setX ( int x ) {
this . x = x ;
}
public void setY ( int y ) {
this . y = y ;
}
public void setRadius ( int radius ) {
this . radius = radius ;
}
@ Override
public void draw () {
Log . e ( "---" , "Circle: Draw() [Color : " + color
+ ", x : " + x + ", y :" + y + ", radius :" + radius );
}
}
3. Buat pabrik untuk menghasilkan objek kelas entitas berdasarkan informasi yang diberikan.
public class ShapeFactory {
private static final HashMap < String , Shape > circleMap = new HashMap < String , Shape >();
public static Shape getShape ( String color ) {
Shape shape = circleMap . get ( color );
if ( shape == null ) {
shape = new Circle ( color );
circleMap . put ( color , shape );
Log . e ( "getShape" , "Creating circle of color : " + color );
}
return shape ;
}
}
4. Gunakan pabrik ini untuk mendapatkan objek kelas entitas dengan meneruskan informasi warna.
for ( int i = 0 ; i < 20 ; i ++) {
Circle circle = ( Circle ) ShapeFactory . getShape ( getRandomColor ());
circle . setX ( getRandomX ());
circle . setY ( getRandomY ());
circle . setRadius ( 100 );
circle . draw ();
}
Satu kelas mewakili fungsionalitas kelas lain. Dalam pola proxy, kami membuat objek dengan objek yang sudah ada untuk menyediakan antarmuka fungsional ke dunia luar. Dapat dipahami bahwa jika tidak ada objek seperti itu di memori, maka akan dibuat, dan jika ada, objek tersebut akan langsung dikembalikan.
Mengambil gambar dari disk sebagai contoh, ada tiga langkah totalnya:
1. Buat antarmuka.
public interface Image {
void display ();
}
2. Buat kelas entitas RealImage yang mengimplementasikan antarmuka. Kelas proksi yang sesuai: ProxyImage.
public class RealImage implements Image {
private String fileName ;
public RealImage ( String fileName ) {
this . fileName = fileName ;
loadFromDisk ( fileName );
}
private void loadFromDisk ( String fileName ) {
Log . e ( "RealImage" , "loading " + fileName );
}
@ Override
public void display () {
Log . e ( "RealImage" , "Displaying " + fileName );
}
}
public class ProxyImage implements Image {
private String fileName ;
private RealImage realImage ;
public ProxyImage ( String fileName ) {
this . fileName = fileName ;
}
@ Override
public void display () {
if ( realImage == null ) {
realImage = new RealImage ( fileName );
}
realImage . display ();
}
}
3. Bila diminta, gunakan ProxyImage untuk mendapatkan objek kelas RealImage.
Image image = new ProxyImage ( "test_10mb.png" );
// 第一次是new的,图像从磁盘加载
image . display ();
// 第二次取缓存,图像不需要从磁盘加载
image . display ();
Bridge digunakan untuk memisahkan abstraksi dan implementasi sehingga keduanya dapat berubah secara independen. Jenis pola desain ini adalah pola struktural, yang memisahkan abstraksi dan implementasi dengan menyediakan struktur penghubung di antara keduanya.
Mengambil contoh menggambar lingkaran dengan warna berbeda, implementasinya dibagi menjadi lima langkah:
1. Buat antarmuka implementasi jembatan.
public interface DrawAPI {
void drawCircle ( int radius , int x , int y );
}
2. Buat kelas implementasi jembatan entitas yang mengimplementasikan antarmuka DrawAPI. Lingkaran Merah, Lingkaran Hijau
public class RedCircle implements DrawAPI {
@ Override
public void drawCircle ( int radius , int x , int y ) {
Log . e ( "---" , "Drawing Circle[ color: red, radius: "
+ radius + ", x: " + x + ", " + y + "]" );
}
}
3. Gunakan antarmuka DrawAPI untuk membuat kelas abstrak Shape.
public abstract class Shape {
protected DrawAPI drawAPI ;
protected Shape ( DrawAPI drawAPI ) {
this . drawAPI = drawAPI ;
}
public abstract void draw ();
}
4. Buat kelas entitas yang mengimplementasikan antarmuka Shape.
public class Circle extends Shape {
private int x , y , radius ;
protected Circle ( int x , int y , int radius , DrawAPI drawAPI ) {
super ( drawAPI );
this . x = x ;
this . y = y ;
this . radius = radius ;
}
@ Override
public void draw () {
drawAPI . drawCircle ( radius , x , y );
}
}
5. Gunakan kelas Shape dan DrawAPI untuk menggambar lingkaran dengan warna berbeda.
// 画红圆
Circle circle = new Circle ( 10 , 10 , 100 , new RedCircle ()); s
circle . draw ();
// 画绿圆
Circle circle2 = new Circle ( 20 , 20 , 100 , new GreenCircle ());
circle2 . draw ();
Juga disebut pola bagian-keseluruhan, pola ini digunakan untuk memperlakukan sekelompok objek serupa sebagai satu objek. Mode komposisi menggabungkan objek menurut struktur pohon, yang digunakan untuk mewakili sebagian dan keseluruhan hierarki. Jenis pola desain ini merupakan pola struktural, yang menciptakan struktur pohon dari kelompok objek.
Ambil contoh membuat dan mencetak hierarki karyawan, contoh unit terkecil:
1. Buat kelas Karyawan dengan daftar objek Karyawan.
public class Employee {
private String name ;
// 部门
private String dept ;
// 工资
private int salary ;
// 员工 list
private List < Employee > subordinates ;
public Employee ( String name , String dept , int salary ) {
this . name = name ;
this . dept = dept ;
this . salary = salary ;
this . subordinates = new ArrayList < Employee >();
}
public void add ( Employee e ) {
subordinates . add ( e );
}
public void remove ( Employee e ) {
subordinates . remove ( e );
}
public List < Employee > getSubordinates () {
return subordinates ;
}
@ Override
public String toString () {
return "Employee{" +
"name='" + name + ''' +
", dept='" + dept + ''' +
", salary=" + salary +
", subordinates=" + subordinates +
'}' ;
}
}
2. Gunakan kelas Karyawan untuk membuat dan mencetak hierarki karyawan.
final Employee ceo = new Employee ( "John" , "CEO" , 30000 );
Employee headSales = new Employee ( "Robert" , "Head sales" , 20000 );
Employee headMarketing = new Employee ( "Michel" , "Head Marketing" , 20000 );
Employee clerk1 = new Employee ( "Laura" , "Marketing" , 10000 );
Employee clerk2 = new Employee ( "Bob" , "Marketing" , 10000 );
Employee salesExecutive1 = new Employee ( "Richard" , "Sales" , 10000 );
Employee salesExecutive2 = new Employee ( "Rob" , "Sales" , 10000 );
ceo . add ( headSales );
ceo . add ( headMarketing );
headSales . add ( salesExecutive1 );
headSales . add ( salesExecutive2 );
headMarketing . add ( clerk1 );
headMarketing . add ( clerk2 );
Log . e ( "---" , ceo . toString ());
// 打印
/*
* Employee{name='John', dept='CEO', salary=30000,
* subordinates=[Employee{name='Robert', dept='Head sales', salary=20000,
* subordinates=[
* Employee{name='Richard', dept='Sales', salary=10000, subordinates=[]},
* Employee{name='Rob', dept='Sales', salary=10000, subordinates=[]}]},
* Employee{name='Michel', dept='Head Marketing', salary=20000,
* subordinates=[Employee{name='Laura', dept='Marketing', salary=10000, subordinates=[]},
* Employee{name='Bob', dept='Marketing', salary=10000, subordinates=[]}]}]}
*/
Pola desain yang sangat umum di lingkungan pemrograman Java dan .Net. Pola ini digunakan untuk mengakses elemen objek koleksi secara berurutan tanpa mengetahui representasi yang mendasari objek koleksi tersebut. Pola iterator adalah pola perilaku.
Mengambil contoh penggunaan iterator untuk mencetak nama, ada tiga langkah total:
1. Buat antarmuka:
public interface Iterator {
public boolean hasNext ();
public Object next ();
}
public interface Container {
public Iterator getIterator ();
}
2. Buat kelas entitas yang mengimplementasikan antarmuka Kontainer. Kelas ini memiliki kelas dalam NameIterator yang mengimplementasikan antarmuka Iterator.
public class NameRepository implements Container {
private String names [] = { "John" , "jingbin" , "youlookwhat" , "lookthis" };
@ Override
public Iterator getIterator () {
return new NameIterator ();
}
private class NameIterator implements Iterator {
int index ;
@ Override
public boolean hasNext () {
if ( index < names . length ) {
return true ;
}
return false ;
}
@ Override
public Object next () {
if ( hasNext ()) {
return names [ index ++];
}
return null ;
}
}
}
3. Gunakan NameRepository untuk mendapatkan iterator dan mencetak namanya.
NameRepository nameRepository = new NameRepository ();
for ( Iterator iterator = nameRepository . getIterator (); iterator . hasNext (); ) {
String name = ( String ) iterator . next ();
Log . e ( "---" , name );
/*
* /---: John
* /---: jingbin
* /---: youlookwhat
* /---: lookthis
*/
}
Digunakan untuk mengurangi kompleksitas komunikasi antara banyak objek dan kelas. Pola ini menyediakan kelas perantara yang biasanya menangani komunikasi antar kelas yang berbeda dan mendukung penggandengan longgar, sehingga membuat kode lebih mudah dipelihara. Model mediator adalah model perilaku.
Mengambil contoh ruang obrolan publik, langkah contoh unit minimum adalah:
1. Buat kelas perantara.
public class CharRoom {
public static void showMessage ( User user , String message ) {
Log . e ( "---" , new Date (). toString ()
+ " [" + user . getName () + "] : " + message );
}
}
2. Buat kelas pengguna.
public class User {
private String name ;
public User ( String name ) {
this . name = name ;
}
public String getName () {
return name ;
}
public void setName ( String name ) {
this . name = name ;
}
public void sendMessage ( String message ) {
// 使用中介类
CharRoom . showMessage ( this , message );
}
}
3. Gunakan objek Pengguna untuk menampilkan komunikasi di antara mereka.
User jingbin = new User ( "jingbin" );
jingbin . sendMessage ( "Hi~ youlookwhat!" );
//---: Sun Feb 02 08:11:47 GMT+00:00 2020 [jingbin] : Hi~ youlookwhat!
User jingbin = new User ( "youlookwhat" );
jingbin . sendMessage ( "Hi~ jingbin!" );
//---: Sun Feb 02 08:11:49 GMT+00:00 2020 [youlookwhat] : Hi~ jingbin!
Menyimpan keadaan tertentu suatu objek sehingga dapat dipulihkan pada waktu yang tepat. Mode memo adalah mode perilaku.
Mengambil contoh memo, langkah unit minimumnya adalah:
1. Buat kelas Kenang-kenangan.
public class Memento {
private String state ;
public Memento ( String state ) {
this . state = state ;
}
public String getState () {
return state ;
}
public void setState ( String state ) {
this . state = state ;
}
}
2. Buat kelas Originator.
public class Originator {
private String state ;
public String getState () {
return state ;
}
public void setState ( String state ) {
this . state = state ;
}
public Memento setSateToMemento () {
return new Memento ( state );
}
public String getStateFromMemento ( Memento memento ) {
return memento . getState ();
}
}
3. Buat kelas CareTaker.
public class CareTaker {
private List < Memento > mementoList = new ArrayList < Memento >();
public void add ( Memento memento ) {
mementoList . add ( memento );
}
public Memento get ( int index ) {
return mementoList . get ( index );
}
}
4. Gunakan objek CareTaker dan Originator.
// 管理者
CareTaker careTaker = new CareTaker ();
Originator originator = new Originator ();
originator . setState ( "State #1" );
originator . setState ( "State #2" );
// 保存状态
careTaker . add ( originator . setSateToMemento ());
originator . setState ( "State #3" );
// 保存状态
careTaker . add ( originator . setSateToMemento ());
originator . setState ( "State #4" );
Log . e ( "---" , "Current State: " + originator . getState ());
// 得到保存的状态
String fromMemento1 = originator . getStateFromMemento ( careTaker . get ( 0 ));
Log . e ( "---" , "First Saved State: " + fromMemento1 );
String fromMemento2 = originator . getStateFromMemento ( careTaker . get ( 1 ));
Log . e ( "---" , "Second Saved State: " + fromMemento2 );
/*
* /---: Current State: State #4
* /---: First Saved State: State #2
* /---: Second Saved State: State #3
*/
Menyediakan cara untuk mengevaluasi tata bahasa atau ekspresi suatu bahasa dan merupakan pola perilaku. Pola ini mengimplementasikan antarmuka ekspresi yang menafsirkan konteks tertentu. Mode ini digunakan dalam penguraian SQL, mesin pengolah simbol, dll.
Ambil contoh kalimat penjelasan, langkah satuan minimumnya:
1. Buat antarmuka ekspresi Ekspresi.
public interface Expression {
public boolean interpreter ( String content );
}
2. Buat kelas entitas yang mengimplementasikan antarmuka di atas. TerminalExpression, AtauExpression, DanExpression.
public class TerminalExpression implements Expression {
private String data ;
public TerminalExpression ( String data ) {
this . data = data ;
}
@ Override
public boolean interpreter ( String content ) {
// 是包含判断
return content . contains ( data );
}
}
public class OrExpression implements Expression {
private Expression expression1 ;
private Expression expression2 ;
public OrExpression ( Expression expression1 , Expression expression2 ) {
this . expression1 = expression1 ;
this . expression2 = expression2 ;
}
@ Override
public boolean interpreter ( String content ) {
return expression1 . interpreter ( content ) || expression2 . interpreter ( content );
}
}
public class AndExpression implements Expression {
private Expression expression1 ;
private Expression expression2 ;
public AndExpression ( Expression expression1 , Expression expression2 ) {
this . expression1 = expression1 ;
this . expression2 = expression2 ;
}
@ Override
public boolean interpreter ( String content ) {
return expression1 . interpreter ( content ) && expression2 . interpreter ( content );
}
}
3. Gunakan kelas Ekspresi untuk membuat aturan dan menguraikannya.
/**
* 规则:jingbin 和 youlookwhat 是男性
*/
public static Expression getMaleExpression () {
TerminalExpression jingbin = new TerminalExpression ( "jingbin" );
TerminalExpression youlookwhat = new TerminalExpression ( "youlookwhat" );
return new OrExpression ( jingbin , youlookwhat );
}
/**
* 规则:Julie 是一个已婚的女性
*/
public static Expression getMarriedWomanExpression () {
TerminalExpression julie = new TerminalExpression ( "Julie" );
TerminalExpression married = new TerminalExpression ( "Married" );
return new AndExpression ( julie , married );
}
Expression maleExpression = getMaleExpression ();
// jingbin is male: true
Log . e ( "---" , "jingbin is male: " + maleExpression . interpreter ( "jingbin" ));
Expression womanExpression = getMarriedWomanExpression ();
// Julie is married woman: true
Log . e ( "---" , "Julie is married woman: " + womanExpression . interpreter ( "Married Julie" ));
Pola Rantai Tanggung Jawab menciptakan rantai objek penerima permintaan. Pola ini memisahkan pengirim dan penerima permintaan berdasarkan jenis permintaan. Jenis pola desain ini adalah pola perilaku. Dalam pola ini, biasanya setiap penerima berisi referensi ke penerima lainnya. Jika suatu objek tidak dapat menangani permintaan tersebut, maka objek tersebut meneruskan permintaan yang sama ke penerima berikutnya, dan seterusnya.
Mengambil log pencetakan di Android Studio sebagai contoh, langkah unit minimumnya adalah:
1. Buat kelas logger abstrak AbstrakLogger.
public abstract class AbstractLogger {
public static int INFO = 1 ;
public static int DEBUG = 2 ;
public static int ERROR = 3 ;
protected int level ;
// 责任链中的下一个元素
protected AbstractLogger nextLogger ;
public void setNextLogger ( AbstractLogger nextLogger ) {
this . nextLogger = nextLogger ;
}
public void logMessage ( int level , String message ) {
if ( this . level <= level ) {
write ( message );
}
// 递归效果,不断调用下一级 logMessage
if ( nextLogger != null ) {
nextLogger . logMessage ( level , message );
}
}
protected abstract void write ( String message );
}
2. Buat kelas entitas yang memperluas kelas logger.
public class ConsoleLogger extends AbstractLogger {
public ConsoleLogger ( int level ) {
this . level = level ;
}
@ Override
protected void write ( String message ) {
Log . e ( "---" , "Standard Console::Logger " + message );
}
}
public class FileLogger extends AbstractLogger {
public FileLogger ( int level ) {
this . level = level ;
}
@ Override
protected void write ( String message ) {
Log . e ( "---" , "File::Logger " + message );
}
}
public class ErrorLogger extends AbstractLogger {
public ErrorLogger ( int level ) {
this . level = level ;
}
@ Override
protected void write ( String message ) {
Log . e ( "---" , "Error Console::Logger " + message );
}
}
3. Buat berbagai jenis logger. Beri mereka tingkat kesalahan yang berbeda dan dalam setiap logger atur logger berikutnya. Logger berikutnya di setiap logger mewakili bagian dari rantai.
public static AbstractLogger getChainOfLoggers () {
ErrorLogger errorLogger = new ErrorLogger ( AbstractLogger . ERROR );
FileLogger fileLogger = new FileLogger ( AbstractLogger . DEBUG );
ConsoleLogger consoleLogger = new ConsoleLogger ( AbstractLogger . INFO );
errorLogger . setNextLogger ( fileLogger );
fileLogger . setNextLogger ( consoleLogger );
return errorLogger ;
}
AbstractLogger logger = getChainOfLoggers ();
// ---: Standard Console::Logger this is an information.
logger . logMessage ( AbstractLogger . INFO , "this is an information." );
// ---: File::Logger this is a debug level information.
// ---: Standard Console::Logger this is a debug level information.
logger . logMessage ( AbstractLogger . DEBUG , "this is a debug level information." );
// ---: Error Console::Logger this is a error level information.
// ---: File::Logger this is a error level information.
// ---: Standard Console::Logger this is a error level information.
logger . logMessage ( AbstractLogger . ERROR , "this is a error level information." );
Dalam pola pengunjung, kami menggunakan kelas pengunjung, yang mengubah algoritma eksekusi kelas elemen. Dengan cara ini, algoritme eksekusi elemen dapat berubah seiring perubahan pengunjung. Jenis pola desain ini adalah pola perilaku. Berdasarkan skema, objek elemen telah menerima objek pengunjung sehingga objek pengunjung dapat menangani operasi pada objek elemen.
Mengambil komponen komputer layar sebagai contoh, hal ini terutama diimplementasikan dalam lima langkah:
1. Tentukan antarmuka yang mewakili elemen.
public interface ComputerPart {
public void accept ( ComputerPartVisitor computerPartVisitor );
}
2. Buat kelas entitas yang memperluas kelas di atas. Keyboard, Monitor, Mouse, Komputer
public class Computer implements ComputerPart {
private ComputerPart [] parts ;
public Computer () {
this . parts = new ComputerPart []{ new Mouse (), new Keyboard (), new Monitor ()};
}
@ Override
public void accept ( ComputerPartVisitor computerPartVisitor ) {
for ( ComputerPart part : parts ) {
part . accept ( computerPartVisitor );
}
computerPartVisitor . visit ( this );
}
}
public class Mouse implements ComputerPart {
@ Override
public void accept ( ComputerPartVisitor computerPartVisitor ) {
computerPartVisitor . visit ( this );
}
}
3. Tentukan antarmuka yang mewakili pengunjung.
public interface ComputerPartVisitor {
public void visit ( Computer computer );
public void visit ( Mouse mouse );
public void visit ( Keyboard keyboard );
public void visit ( Monitor monitor );
}
4. Buat pengunjung entitas yang mengimplementasikan kelas-kelas di atas.
public class ComputerPartDisplayVisitor implements ComputerPartVisitor {
@ Override
public void visit ( Computer computer ) {
Log . e ( "---" , "Displaying Computer." );
}
@ Override
public void visit ( Mouse mouse ) {
Log . e ( "---" , "Displaying Mouse." );
}
@ Override
public void visit ( Keyboard keyboard ) {
Log . e ( "---" , "Displaying Keyboard." );
}
@ Override
public void visit ( Monitor monitor ) {
Log . e ( "---" , "Displaying Monitor." );
}
}
5. Gunakan ComputerPartDisplayVisitor untuk menampilkan komponen Komputer.
ComputerPart computer = new Computer ();
computer . accept ( new ComputerPartDisplayVisitor ());
/*
*打印:
*---: Displaying Mouse.
*---: Displaying Keyboard.
*---: Displaying Monitor.
*---: Displaying Computer.
*/