![](/img/trans.png)
[英]If I use abstract class instead of interface while implementing factory pattern. Would it still be a factory pattern?
[英]If I can have multiple factory methods in a creator class, why would I ever need the abstract factory pattern?
抽象工廠模式在我們有一系列相關類時很有用,我們希望在不依賴實現的情況下實例化它們。 但是,在這種情況下使用工廠方法模式有什么問題呢?
假設我們要構建跨平台的 UI 元素,例如 Windows 和 macOS 的TextBox
和Button
,並抽象地對待它們。 這是我們使用抽象工廠模式的典型情況,我們可以通過定義以下內容來實現:
AbstractUIElementsFactory
接口WindowsUIElementsFactory
實現AbstractUIElementsFactory
MacUIElementsFactory
實現AbstractUIElementsFactory
TextBox
摘要 class
MacTextBox
擴展TextBox
WindowsTextBox
擴展TextBox
Button
摘要 class
MacButton
擴展Button
WindowsButton
擴展Button
並且應用程序將決定創建哪個具體工廠(基於一些操作系統發現機制)並將其傳遞給UIApplication
class,它實例化一個TextBox
和一個Button
,並在它們上調用display
(它們是簡單返回String
的抽象方法) .
這種情況的代碼:
package abstractFactory;
abstract class Button {
public abstract void display();
}
class MacButton extends Button {
public void display() {
System.out.println("macButton");
}
}
class WindowsButton extends Button {
@Override
public void display() {
System.out.println("winButton");
}
}
abstract class TextBox {
public abstract void display();
}
class MacTextBox extends TextBox {
@Override
public void display() {
System.out.println("macTextBox");
}
}
class WinTextBox extends TextBox {
@Override
public void display() {
System.out.println("winTextBox");
}
}
interface UICreatorAbstractFactory {
Button getButton();
TextBox getTextBox();
}
class MacFactory implements UICreatorAbstractFactory {
@Override
public Button getButton() {
return new MacButton();
}
@Override
public TextBox getTextBox() {
return new MacTextBox();
}
}
class WindowsFactory implements UICreatorAbstractFactory {
@Override
public Button getButton() {
return new WindowsButton();
}
@Override
public TextBox getTextBox() {
return new WinTextBox();
}
}
class UIApplication {
private UICreatorAbstractFactory factory;
UIApplication(UICreatorAbstractFactory _factory) {
factory = _factory;
}
public void displayUI() {
factory.getButton().display();
factory.getTextBox().display();
}
}
public class Main {
public static void main(String[] args) {
new UIApplication(new MacFactory()).displayUI();
}
}
此實現允許我們從工廠實現和 UI 元素實現中透明地獲取 UI 元素,這在很大程度上是我們使用該模式的原因。
使用相同的TextBox
、 Button
和它們的衍生物,我們可以在creator UICreator
中使用兩個工廠方法實現一個工廠方法,每個工廠方法都返回一個抽象的 UI 元素。 我們派生創建者並進行兩個特化WindowsUICreator
和MacUICreator
,每個都返回適當的具體 UI 元素,如下所示:
abstract class UICreator {
public void displayUI() {
getButton().display();
getTextBox().display();
}
protected abstract Button getButton();
protected abstract TextBox getTextBox();
}
class WindowsUICreator extends UICreator {
@Override
protected Button getButton() {
return new WindowsButton();
}
@Override
protected TextBox getTextBox() {
return new WinTextBox();
}
}
class MacUICreator extends UICreator {
@Override
protected Button getButton() {
return new MacButton();
}
@Override
protected TextBox getTextBox() {
return new MacTextBox();
}
}
public class Main {
public static void main(String[] args) {
new MacUICreator().displayUI();
}
}
這種設計的缺點是什么? 我相信它通過不必處理任何具體類來提供所需的解耦,並且在我們可以引入新的 UI 元素並為它們提供新的工廠方法或新支持的操作系統並為它們實現具體創建者的意義上提供了適當的可擴展性. 如果我們可以在設計抽象工廠模式的確切情況下使用工廠方法模式,我完全不明白我們為什么要擁有它?
我想在這里向您展示 Saurav Satpathy 博客中的一張圖片,它可以快速解釋為什么您有時需要抽象工廠而不是工廠方法。
依賴注入和相關對象收集的論點很有意義,這是偉大的創造者The Refactoring Guru 關於抽象工廠的編碼示例,這是他關於工廠方法的示例。 在我看來,這些示例之間的主要區別在於抽象工廠更好地描述了創建多種類型對象的工廠的復雜性。 此外,它有效地將代碼划分為更多類,使每個 class 更易於理解(當然,總共創建了更多類)。
請記住,到目前為止,這不是一個非常深入的分析,我想看看其他人對此事的看法,並給我一些時間自己思考。 我可能會在幾天后回來進行編輯(目前有點忙,但我偷偷給你一個快速的意見)
編輯#1 Inheritance
“贊成 object 組合超過 class inheritance。Inheritance 打破封裝,實現抽象類,不要繼承具體類! - 設計模式四人組”
所以 object inheritance 如果你讀了 GoF 的書:“可重用面向對象軟件的設計模式元素”是不鼓勵的,特別是當系統在 scope 中變得越來越復雜或更高時。編輯確實受到@FelipeLlinares 的影響。
它們都是關於創建新對象,但工廠方法僅用於創建一個產品,而抽象工廠是關於創建相關或依賴產品的系列。 在抽象工廠模式中,class 通過組合將 object 實例化的責任委托給另一個 object,而工廠方法模式使用 inheritance 並依賴子類來處理所需的 object 實例化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.