目錄
簡單工廠模式
傳統方式
簡單工廠模式
靜態工廠模式
工廠方法模式
抽象工廠模式
工廠模式JDK-Calendar原始碼分析
工廠模式小結
簡單工廠模式
看一個具體的需求
看一個披薩的專案:要便于披薩種類的擴展,要便于維護
(1)披薩的種類很多(比如GreekPizz、CheesePizz等)
(2)披薩的制作有prepare,bake, cut, box
(3)完成披薩店訂購功能,
傳統方式
使用傳統的方式來完成
①思路分析(類圖)

②代碼演示
撰寫OrderPizza.java去訂購需要的各種Pizza
public class OrderPizza {
//構造器
public OrderPizza(){
Pizza pizza=null;
String orderType;//訂購披薩的型別
do{
orderType=getType();
if(orderType.equals("greek")){
pizza=new GreekPizza();
pizza.setName("希臘披薩");
}else if(orderType.equals("chesse")){
pizza=new CheesePizza();
pizza.setName("奶酪披薩");
}else{
break;
}
//輸出pizza制作程序
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}while(true);
}
private String getType(){
try{
BufferedReader strin=new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str=strin.readLine();
return str;
}catch (IOException e){
e.printStackTrace();
return "";
}
}
}
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza();
}
}
public class GreekPizza extends Pizza{
@Override
public void prepare() {
System.out.println("給希臘披薩準備原材料");
}
}
public class PepperPizza extends Pizza{
@Override
public void prepare() {
System.out.println("給胡椒披薩準備原材料");
}
}
public class CheesePizza extends Pizza {
@Override
public void prepare() {
System.out.println("給制作奶酪披薩,準備原材料");
}
}
public abstract class Pizza {
//名字
protected String name;
//準備原材料,不同的披薩不一樣,所以為抽象方法
public abstract void prepare();
public void bake(){
System.out.println(name+ " baking;");
}
public void cut(){
System.out.println(name+" cutting;");
}
public void box(){
System.out.println(name+" boxing");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
傳統方式的優缺點
1)優點是比較好理解,簡單易操作,
2)缺點是違反了設計模式的ocp 原則,即對擴展開放,對修改關閉,即當我們給類增加新功能的時候,盡量不修
改代碼,或者盡可能少修改代碼.
3)比如我們這時要新增加一個Pizza的種類(Pepper披薩),我們需要做如下修改.如果我們增加一個 Pizza類,只要是訂購Pizza的代碼都需要修改,

4)改進的思路分析
分析:修改代碼可以接受,但是如果我們在其它的地方也有創建 Pizza的代碼,就意味著,也需要修改,而創建Pizza的代碼,往往有多處,
思路:把創建Pizza物件封裝到一個類中,這樣我們有新的Pizza種類時,只需要修改該類就可,其它有創建到Pizza物件的代碼就不需要修改了.->簡單工廠模式
簡單工廠模式
基本介紹
1)簡單工廠模式是屬于創建型模式,是工廠模式的一種,簡單工廠模式是由一個工廠物件決定創建出哪一種產品類的實體,簡單工廠模式是工廠模式家族中最簡單實用的模式
2)簡單工廠模式:定義了一個創建物件的類,由這個類來封裝實體化物件的行為(代碼)
3)在軟體開發中,當我們會用到大量的創建某種、某類或者某批物件時,就會使用到工廠模式.
使用簡單工廠模式
簡單工廠模式的設計方案:定義一個可以實體化Pizaa物件的類,封裝創建物件的代碼,
代碼演示:
//簡單工廠類
public class SimpleFactory {
//根據orderType,回傳對應的Pizza物件
public Pizza createPizza(String orderType){
Pizza pizza=null;
System.out.println("使用簡單工廠模式");
if(orderType.equals("greek")){
pizza=new GreekPizza();
pizza.setName("希臘披薩");
}else if(orderType.equals("chesse")){
pizza=new CheesePizza();
pizza.setName("奶酪披薩");
}else if(orderType.equals("pepper")){
pizza=new PepperPizza();
pizza.setName("胡椒披薩");
}
return pizza;
}
//簡單工廠模式也叫靜態工廠模式
}
public class OrderPizza {
//定義一個簡單工廠物件
SimpleFactory simpleFactory;
Pizza pizza=null;
//構造器
public OrderPizza(SimpleFactory simpleFactory){
setFactory(simpleFactory);
}
public void setFactory(SimpleFactory simpleFactory){
String orderType="";//用戶輸入
this.simpleFactory=simpleFactory;//設定簡單工廠物件
do{
orderType=getType();
pizza=this.simpleFactory.createPizza(orderType);
//輸出pizza
if(pizza!=null){ //訂購成功
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}else{
System.out.println("訂購披薩失敗");
break;
}
}while (true);
}
private String getType(){
try{
BufferedReader strin=new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str=strin.readLine();
return str;
}catch (IOException e){
e.printStackTrace();
return "";
}
}
}
//相當于一個客戶端,發出訂購
public class PizzaStore {
public static void main(String[] args) {
//使用簡單工廠模式
new OrderPizza(new SimpleFactory());
System.out.println("退出程式");
}
}
靜態工廠模式
代碼演示:
//簡單工廠類
public class SimpleFactory {
//根據orderType,回傳對應的Pizza物件
public static Pizza createPizza2(String orderType){
Pizza pizza=null;
System.out.println("使用簡單工廠模式2");
if(orderType.equals("greek")){
pizza=new GreekPizza();
pizza.setName("希臘披薩");
}else if(orderType.equals("chesse")){
pizza=new CheesePizza();
pizza.setName("奶酪披薩");
}else if(orderType.equals("pepper")){
pizza=new PepperPizza();
pizza.setName("胡椒披薩");
}
return pizza;
}
//簡單工廠模式也叫靜態工廠模式
}
public class OrderPizza2 {
Pizza pizza=null;
String orderType="";
//構造器
public OrderPizza2(){
do{
orderType=getType();
pizza=SimpleFactory.createPizza2(orderType);
//輸出pizza
if(pizza!=null){ //訂購成功
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}else{
System.out.println("訂購披薩失敗");
break;
}
}while (true);
}
//寫一個方法,可以客戶希望訂購披薩的種類
private String getType(){
try{
BufferedReader strin=new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str=strin.readLine();
return str;
}catch (IOException e){
e.printStackTrace();
return "";
}
}
}
工廠方法模式
一個新的需求:披薩專案新的需求:客戶在點披薩時,可以點不同口味的披薩,比如北京的奶酪piza、北京的胡椒pizza或者是倫敦的奶酪pizza、倫敦的胡椒pizza,
思路1:使用簡單工廠模式,創建不同的簡單工廠類,比如BJPizzaSimpleFactory、LDPizzaSimpleFactory等等.從當前這個案例來說,也是可以的,但是考慮到專案的規模,以及軟體的可維護性、可擴展性并不是特別好
思路2:使用工廠方法模式
工廠方法模式介紹
1)工廠方法模式設計方案:將披薩專案的實體化功能抽象成抽象方法,在不同的口味點餐子類中具體實作,
2)工廠方法模式:定義了一個創建物件的抽象方法,由子類決定要實體化的類,工廠方法模式將物件的實體化推遲到子類,
工廠方法模式應用案例
1)披薩專案新的需求:客戶在點披薩時,可以點不同口味的披薩﹐比如北京的奶酪pizza、北京的胡椒pizza或者是倫敦的奶酪pizza、倫敦的胡椒pizza
2)思路分析圖解
3)代碼演示
public class BJCheesePizza extends Pizza {
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("北京的奶酪pizza");
System.out.println("北京的奶酪pizza,準備材料 ");
}
}
public class BJPepperPizza extends Pizza {
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("北京的胡椒pizza");
System.out.println(" 北京的胡椒pizza,準備材料 ");
}
}
public class LDPepperPizza extends Pizza{
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("倫敦的胡椒pizza");
System.out.println("倫敦的胡椒pizza,準備材料 ");
}
}
public class LDCheesePizza extends Pizza{
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("倫敦的奶酪pizza");
System.out.println("倫敦的奶酪pizza,準備材料");
}
}
public abstract class Pizza {
protected String name; //名字
//準備原材料,不同的披薩不一樣,所以為抽象方法
public abstract void prepare();
public void bake() {
System.out.println(name + " baking;");
}
public void cut() {
System.out.println(name + " cutting;");
}
public void box() {
System.out.println(name + " boxing;");
}
public void setName(String name) {
this.name = name;
}
}
public abstract class OrderPizza {
//定義一個抽象方法,createPizza,讓各個子類自己實作
abstract Pizza createPizza(String orderType);
//構造器
public OrderPizza() {
Pizza pizza = null;
String orderType; //訂購披薩的型別
do {
orderType = getType();
pizza = createPizza(orderType); //抽象方法,由工廠子類完成
//輸出pizza 制作程序
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} while (true);
}
//
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza 種類:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
public class BJOrderPizza extends OrderPizza {
@Override
Pizza createPizza(String orderType) {
Pizza pizza = null;
if(orderType.equals("cheese")) {
pizza = new BJCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new BJPepperPizza();
}
// TODO Auto-generated method stub
return pizza;
}
}
public class LDOrderPizza extends OrderPizza {
@Override
Pizza createPizza(String orderType) {
Pizza pizza = null;
if(orderType.equals("cheese")) {
pizza = new LDCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new LDPepperPizza();
}
// TODO Auto-generated method stub
return pizza;
}
}
public class PizzaStore {
public static void main(String[] args) {
String loc = "bj";
if (loc.equals("bj")) {
//創建北京口味的各種披薩
new BJOrderPizza();
} else {
//創建倫敦口味的各種披薩
new LDOrderPizza();
}
// TODO Auto-generated method stub
}
}
抽象工廠模式
基本介紹
l)抽象工廠模式:定義了一個interface介面用于創建相關或有依賴關系的物件簇,而無需指明具體的類
2)抽象工廠模式可以將簡單工廠模式和工廠方法模式進行整合,
3)從設計層面看,抽象工廠模式就是對簡單工廠模式的改進(或者稱為進一步的抽象),
4) 將工廠抽象成兩層,AbsFactory(抽象工廠)和具體實作的工廠子類,程式員可以根據創建物件型別使用對應的工廠子類,這樣將單個的簡單工廠類變成了工廠簇,更利于代碼的維護和擴展,
5)類圖

抽象工廠模式應用實體
使用抽象工廠模式完成披薩專案
//一個抽象工廠模式的抽象層(介面)
public interface AbsFactory {
//讓下面的工廠子類來具體實作
public Pizza createPizza(String orderType);
}
public class LDFactory implements AbsFactory {
@Override
public Pizza createPizza(String orderType) {
System.out.println("~使用的是抽象工廠模式~");
Pizza pizza = null;
if (orderType.equals("cheese")) {
pizza = new LDCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new LDPepperPizza();
}
return pizza;
}
}
//這是工廠子類
public class BJFactory implements AbsFactory {
@Override
public Pizza createPizza(String orderType) {
System.out.println("~使用的是抽象工廠模式~");
// TODO Auto-generated method stub
Pizza pizza = null;
if(orderType.equals("cheese")) {
pizza = new BJCheesePizza();
} else if (orderType.equals("pepper")){
pizza = new BJPepperPizza();
}
return pizza;
}
}
public class OrderPizza {
AbsFactory factory;
// 構造器
public OrderPizza(AbsFactory factory) {
setFactory(factory);
}
private void setFactory(AbsFactory factory) {
Pizza pizza = null;
String orderType = ""; //用戶輸入
this.factory = factory;
do {
orderType = getType();
// factory 可能是北京的工廠子類,也可能是倫敦的工廠子類
pizza = factory.createPizza(orderType);
if (pizza != null) { // 訂購ok
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} else {
System.out.println("訂購失敗");
break;
}
} while (true);
}
// 寫一個方法,可以獲取客戶希望訂購的披薩種類
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza 型別:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
public class PizzaStore {
public static void main(String[] args) {
// TODO Auto-generated method stub
//new OrderPizza(new BJFactory());
new OrderPizza(new LDFactory());
}
}
工廠模式JDK-Calendar原始碼分析
JDK中的Calendar類中,就使用了簡單工廠模式



工廠模式小結
1)工廠模式的意義
將實體化物件的代碼提取出來,放到一個類中統一管理和維護,達到和主專案的依賴關系的解耦,從而提高專案的擴展和維護性,
2)三種工廠模式(簡單工廠模式、工廠方法模式、抽象工廠模式)
3)設計模式的依賴抽象原則
①創建物件實體時,不要直接new類,而是把這個new類的動作放在一個工廠的方法中,并回傳,有的書上說,變數不要直接持有具體類的參考,
②不要讓類繼承具體類,而是繼承抽象類或者是實作interface(介面)
③不要覆寫基類中已經實作的方法,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/337621.html
標籤:其他
