创建者模式-简单/工厂/抽象工厂-解决简单对象创建问题
- 创建型模式
- 简单工厂(Simple Factory)
- 解决简单对象创建问题
- 描述
- 适用环境
- 优点:
- 缺点:
- 违反原则
- 代码实现
- 工厂方法(Factory Method)
- 解决产品对象创建问题
- 描述
- 适用环境
- 优点:
- 缺点:
- 违反原则
- 代码实现
- 抽象工厂(Abstract Factory)
- 解决产品族对象创建问题
- 描述
- 适用环境
- 优点:
- 缺点:
- 违反原则
- 代码实现
创建型模式
简单工厂(Simple Factory)
解决简单对象创建问题
描述
通过将对象的创建过程封装在一个工厂类中,使得客户端无需了解对象的具体创建方式和细节,只需要向工厂类传递参数即可获取所需的对象。这种方式可以降低代码的耦合性,使得系统更加易于维护和扩展。
适用环境
当需要创建的对象较少且不会频繁变化时。客户端只知道传入工厂类的参数,而不关心如何创建具体对象的过程。
优点:
工厂类可以隐藏产品创建的细节,实现了客户端与产品实现类的解耦。通过向工厂类传递参数,可以在不修改代码的情况下新增产品类型。
缺点:
工厂类中包含了所有产品的创建逻辑,一旦有任何改动或新产品添加,则需要修改工厂类的代码,并重新编译部署。
违反原则
可能违反开闭原则:新增产品需要修改工厂类。
可能违反依赖倒置原则:客户端依赖具体产品实现类,而不是抽象产品接口。
代码实现
一个云书馆实现一个故事讲解器,根据用户输入的书籍类型来生成相应的故事讲解
使用简单工厂模式,在BookFactory类中定义一个静态方法createBook(),该方法根据传入的书籍类型创建不同的书籍对象,并返回一个StoryTeller对象。
// 在客户端调用
public class Client {public static void main(String[] args) {String bookType = "小说";StoryTeller book = BookFactory.createBook(bookType);if (book != null) {book.tellStory();}}
}public interface StoryTeller {void tellStory();
}public class NovelBook implements StoryTeller {@Overridepublic void tellStory() {System.out.println("这是一本小说,它讲述了一个动人的故事。");}
}public class EssayBook implements StoryTeller {@Overridepublic void tellStory() {System.out.println("这是一本散文集,它引领读者进入优美的诗意世界。");}
}public class PoetryBook implements StoryTeller {@Overridepublic void tellStory() {System.out.println("这是一本诗集,它将伟大的诗人的思想和情感传递给读者。");}
}public class BookFactory {public static StoryTeller createBook(String bookType) {if (bookType.equals("小说")) {return new NovelBook();} else if (bookType.equals("散文")) {return new EssayBook();} else if (bookType.equals("诗集")) {return new PoetryBook();}return null;}
}
工厂方法(Factory Method)
解决产品对象创建问题
描述
将对象的创建延迟到子类中进行,从而使得产品的具体实现对客户端隐藏起来,同时也支持增加新产品的类型而不需要修改现有代码。这种方式可以提高系统的灵活性和可扩展性,同时也符合“开闭原则”。
适用环境
需要为某个产品族创建一套产品对象。客户端只需要关注产品接口,而不关系具体的产品实现类。
优点:
可以让子类决定实际创建的产品类型。可以避免由于新增产品类型导致原来的工厂类需要修改的问题。
缺点:
每增加一个新产品,就需要新增一个对应的产品工厂类,增加了系统的复杂度。
违反原则
可能违反开闭原则:新增产品需要修改具体工厂类。
可能违反依赖倒置原则:客户端依赖具体产品实现类,而不是抽象产品接口。
代码实现
使用工厂方法模式,定义一个Book接口,并让不同类型的书籍实现该接口。同时创建一个BookFactory接口和多个具体的BookFactory类,每个工厂类可以创建一种类型的书籍对象。客户端通过调用特定的子类工厂来获取相应类型的书籍对象。
// 在客户端调用
public class Client {public static void main(String[] args) {String bookType = "小说";BookFactory bookFactory = null;if (bookType.equals("小说")) {bookFactory = new NovelBookFactory();} else if (bookType.equals("散文")) {bookFactory = new EssayBookFactory();} else if (bookType.equals("诗集")) {bookFactory = new PoetryBookFactory();}Book book = bookFactory.createBook();book.storyTelling();}
}
public interface Book {void storyTelling();
}public class NovelBook implements Book {@Overridepublic void storyTelling() {System.out.println("这是一本小说,它讲述了一个动人的故事。");}
}public class EssayBook implements Book {@Overridepublic void storyTelling() {System.out.println("这是一本散文集,它引领读者进入优美的诗意世界。");}
}public class PoetryBook implements Book {@Overridepublic void storyTelling() {System.out.println("这是一本诗集,它将伟大的诗人的思想和情感传递给读者。");}
}public interface BookFactory {Book createBook();
}public class NovelBookFactory implements BookFactory {@Overridepublic Book createBook() {return new NovelBook();}
}public class EssayBookFactory implements BookFactory {@Overridepublic Book createBook() {return new EssayBook();}
}public class PoetryBookFactory implements BookFactory {@Overridepublic Book createBook() {return new PoetryBook();}
}
抽象工厂(Abstract Factory)
解决产品族对象创建问题
描述
提供一个接口用于创建一系列相互依赖或者相互关联的产品,从而避免了直接使用多个工厂类造成的复杂度和耦合度。这种方式可以支持更高级别的组件协作,同时也使得系统更加易于维护和扩展。
适用环境
系统需要创建多个产品族,且这些产品间关系比较密切,需要相互协作。系统不依赖于具体产品类。
优点:
可以在不修改代码的情况下增加新的产品族。抽象工厂隔离了客户端与具体产品类的关系,并使得具体产品的改变对客户端没有影响。
缺点:
当需要新增一个产品族时,需要同时新增抽象工厂接口和所有具体实现类,增加了系统的复杂度。
违反原则
可能违反开闭原则:新增产品族需要修改抽象工厂及其所有实现类。
可能违反依赖倒置原则:客户端依赖具体产品实现类,而不是抽象产品接口。
代码实现
使用抽象工厂模式,定义一个Book接口,并让不同类型的书籍实现该接口。同时创建一个BookFactory接口和多个具体的BookFactory类,每个工厂类可以创建一种类型的书籍对象。在此基础上,定义一个AbstractBookFactory接口,该接口有三个方法分别用于创建小说、散文和诗集。具体的语言版本(如中文或英文)可以作为参数传递给客户端,客户端通过实例化不同的工厂类来创建相应语言版本的AbstractBookFactory对象,并调用其方法来获取相应类型的书籍对象。
// 在客户端调用
public class Client {public static void main(String[] args) {String languageType = "英文";AbstractBookFactory bookFactory = null;if (languageType.equals("英文")) {bookFactory = new EnglishBookFactory();} else if (languageType.equals("中文")) {bookFactory = new ChineseBookFactory();}Book novelBook = bookFactory.createNovelBook();Book essayBook = bookFactory.createEssayBook();Book poetryBook = bookFactory.createPoetryBook();novelBook.storyTelling();essayBook.storyTelling();poetryBook.storyTelling();}
}public interface Book {void storyTelling();
}public class EnglishNovelBook implements Book {@Overridepublic void storyTelling() {System.out.println("This is a novel book, it tells an inspiring story.");}
}public class EnglishEssayBook implements Book {@Overridepublic void storyTelling() {System.out.println("This is an essay book, it leads readers into a poetic world.");}
}public class EnglishPoetryBook implements Book {@Overridepublic void storyTelling() {System.out.println("This is a poetry book, it conveys the thoughts and emotions of great poets.");}
}public class ChineseNovelBook implements Book {@Overridepublic void storyTelling() {System.out.println("这是一本小说,它讲述了一个动人的故事。");}
}public class ChineseEssayBook implements Book {@Overridepublic void storyTelling() {System.out.println("这是一本散文集,它引领读者进入优美的诗意世界。");}
}public class ChinesePoetryBook implements Book {@Overridepublic void storyTelling() {System.out.println("这是一本诗集,它将伟大的诗人的思想和情感传递给读者。");}
}public interface AbstractBookFactory {Book createNovelBook();Book createEssayBook();Book createPoetryBook();
}public class EnglishBookFactory implements AbstractBookFactory {@Overridepublic Book createNovelBook() {return new EnglishNovelBook();}@Overridepublic Book createEssayBook() {return new EnglishEssayBook();}@Overridepublic Book createPoetryBook() {return new EnglishPoetryBook();}
}public class ChineseBookFactory implements AbstractBookFactory {@Overridepublic Book createNovelBook() {return new ChineseNovelBook();}@Overridepublic Book createEssayBook() {return new ChineseEssayBook();}@Overridepublic Book createPoetryBook() {return new ChinesePoetryBook();}
}