Java设计模式中建造者模式和原型模式的介绍(代码示例)
本篇文章给大家带来的内容是关于Java设计模式中建造者模式和原型模式的介绍(代码示例) ,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
前言
在上一篇中我们学习了工厂模式,介绍了简单工厂模式、工厂方法和抽象工厂模式。本篇则介绍设计模式中属于创建型模式的建造者模式和原型模式。
建造者模式
简介
建造者模式是属于创建型模式。建造者模式使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
简单的来说就是将一个复杂的东西抽离出来,对外提供一个简单的调用,可以在同样的构建过程创建不同的表示。和工厂模式很相似,不过相比而言更加注重组件的装配。
这里用一个示例来进行说明。
我们一天吃的食物有这些,煎饼、盒饭、拉面、豆浆、牛奶和果汁。分为三餐、早餐、午餐和晚餐,餐点主要包含吃的(俗称饭)和喝的(豆浆,果汁之类的),那么我们可以把煎饼和豆浆作为早餐,盒饭和果汁作为午餐,这样我们可以清楚的知道要吃早餐和午餐包含什么食物。
首先我们定义一个食物类,有两个属性,吃的和喝的。
class Meal{ private String food; private String drinks; public String getFood() { return food; } public void setFood(String food) { this.food = food; } public String getDrinks() { return drinks; } public void setDrinks(String drinks) { this.drinks = drinks; } }
定义了食物时候,我们在定义一个食物的标准接口,一份食物包含什么,其实也就是吃的和喝的。
interface IBuilderFood{ void buildFood(); void buildDrinks(); Meal createMeal(); }
食物接口定义一个吃的和一个喝的组件,然后通过createMeal()方法返回我们需要的食物。
那么现在我们便可以定义一份早餐和午餐。
代码示例:
class Breakfast implements IBuilderFood{ Meal meal; public Breakfast(){ meal=new Meal(); } @Override public void buildFood() { meal.setFood("煎饼"); } @Override public void buildDrinks() { meal.setDrinks("豆浆"); } @Override public Meal createMeal() { return meal; } } class Lunch implements IBuilderFood{ Meal meal; public Lunch(){ meal=new Meal(); } @Override public void buildFood() { meal.setFood("盒饭"); } @Override public void buildDrinks() { meal.setDrinks("果汁"); } @Override public Meal createMeal() { return meal; } }
定义完之后,建造早餐和午餐的的过程已经完毕了。但是这并不是建造者模式,它有个核心的Director(导演者),它用来创建复杂对象的部分,对该部分进行完整的创建或者按照一定的规则进行创建。那么这里我们可以创建一个Director,用来创建一份餐点。至于创建的是什么餐点,它不用知道,这一点由调用者来进行决定。
这里我们就可以定义一个饭店,可以创建一份餐点,创建什么餐点有顾客决定。
代码示例:
class FoodStore{ public Meal createBreakfast(IBuilderFood bf){ bf.buildDrinks(); bf.buildFood(); return bf.createMeal(); } }
创建完成这个Director之后,我们再来进行调用测试。
代码示例:
public class BuilderTest { public static void main(String[] args) { FoodStore foodStore=new FoodStore(); Meal meal=foodStore.createBreakfast(new Breakfast()); Meal meal2=foodStore.createBreakfast(new Lunch()); System.out.println("小明早上吃的是:"+meal.getFood()+",喝的饮料是:"+meal.getDrinks()); System.out.println("小明中午吃的是:"+meal2.getFood()+",喝的饮料是:"+meal2.getDrinks()); } }
输出结果:
小明早上吃的是:煎饼,喝的饮料是:豆浆 小明中午吃的是:盒饭,喝的饮料是:果汁
简单的介绍了下建造者模式的运作原理,可以概况为这4点:
Builder:指定一个抽象的接口,规定该产品所需实现部件的创建,并不涉及具体的对象部件的创建。
ConcreteBuilder:需实现Builder接口,并且针对不同的逻辑,进行不同方法的创建,最终提供该产品的实例。
Director:用来创建复杂对象的部分,对该部分进行完整的创建或者按照一定的规则进行创建。
Product:示被构造的复杂对象。
使用场景:
适用一些基本组件不便,但是组合经常变化的时候。比如超市促销的大礼包。
优点:
建造者独立,易扩展。
便于控制细节风险。
缺点
内部结构复杂,不易于理解。
产品直接需要有共同点,范围有控制。
原型模式
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
一般来说我们在创建对象的时候是直接创建的,但是创建该对象的代价很大的时候,重复的二次创建就有些不划算,这时我们就可以使用原型模式。
打个比方,我们都发送过邮件,在节日的时候一般发送的是祝福语句,在这些祝福语句中,一般除了名字不一样之外,大部分都是一样的。这时我们就可以利用该模式来进行相应出创建。
这里还是用一个的简单的示例来说明。
小明和小红在同一天生日,然后我们需要给他们发送邮件进行祝福,但是由于比较懒,祝福语除了名字之外都是一样的。这时我们就可以先完成祝福语的编写,然后克隆该祝福语,最后根据不同的名称进行发送。不过这里就从简了,只是简单的打印下而已。
代码示例:
public class PrototypeTest { public static void main(String[] args) { Mail mail=new Mail(); mail.setMsg("生日快乐!"); Mail mail2=(Mail) mail.clone(); mail.setName("小明"); mail2.setName("小红"); System.out.println(mail.toString()); System.out.println(mail2.toString()); } } class Mail implements Cloneable { private String name; private String msg; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Object clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; } @Override public String toString() { return name + ":" + msg ; } }
输出结果:
小明:生日快乐! 小红:生日快乐!
看完原型模式的创建,是不是感觉就是和Java中克隆即为类似呢?
实际上它的核心也就是克隆。
克隆有两种,浅克隆和深克隆,本文主要介绍的是浅克隆。
浅克隆:
在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。
简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。
实现Cloneable接口并重写Object类中的clone()方法;
深克隆:
在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。
简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。
实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。
使用场景:
类初始化的时候需要消耗大量资源的时候;
获取数据库连接繁琐的时候;
一个对象,有很多个修改者的时候;
优点:
1.可以提升性能;
缺点:
1.因为必须实现Cloneable 接口,所以用起来可能不太方便。
相关推荐:
Atas ialah kandungan terperinci Java设计模式中建造者模式和原型模式的介绍(代码示例). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas





Panduan Nombor Sempurna di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor Perfect dalam Java?, contoh dengan pelaksanaan kod.

Panduan untuk Weka di Jawa. Di sini kita membincangkan Pengenalan, cara menggunakan weka java, jenis platform, dan kelebihan dengan contoh.

Panduan untuk Nombor Smith di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor smith di Jawa? contoh dengan pelaksanaan kod.

Dalam artikel ini, kami telah menyimpan Soalan Temuduga Spring Java yang paling banyak ditanya dengan jawapan terperinci mereka. Supaya anda boleh memecahkan temuduga.

Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah

Panduan untuk TimeStamp to Date di Java. Di sini kita juga membincangkan pengenalan dan cara menukar cap waktu kepada tarikh dalam java bersama-sama dengan contoh.

Kapsul adalah angka geometri tiga dimensi, terdiri daripada silinder dan hemisfera di kedua-dua hujungnya. Jumlah kapsul boleh dikira dengan menambahkan isipadu silinder dan jumlah hemisfera di kedua -dua hujungnya. Tutorial ini akan membincangkan cara mengira jumlah kapsul yang diberikan dalam Java menggunakan kaedah yang berbeza. Formula volum kapsul Formula untuk jumlah kapsul adalah seperti berikut: Kelantangan kapsul = isipadu isipadu silinder Dua jumlah hemisfera dalam, R: Radius hemisfera. H: Ketinggian silinder (tidak termasuk hemisfera). Contoh 1 masukkan Jejari = 5 unit Ketinggian = 10 unit Output Jilid = 1570.8 Unit padu menjelaskan Kirakan kelantangan menggunakan formula: Kelantangan = π × r2 × h (4

Java ialah bahasa pengaturcaraan popular yang boleh dipelajari oleh pembangun pemula dan berpengalaman. Tutorial ini bermula dengan konsep asas dan diteruskan melalui topik lanjutan. Selepas memasang Kit Pembangunan Java, anda boleh berlatih pengaturcaraan dengan mencipta program "Hello, World!" Selepas anda memahami kod, gunakan gesaan arahan untuk menyusun dan menjalankan program, dan "Hello, World!" Pembelajaran Java memulakan perjalanan pengaturcaraan anda, dan apabila penguasaan anda semakin mendalam, anda boleh mencipta aplikasi yang lebih kompleks.
