工厂设计模式分为三种:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
简单工厂模式
专门定义一个类来创建其他类的实例(将类的实例化交给工厂来实现)
简单工厂模式:
//简单实现一个客户买手机的过程
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Main main=new Main();
System.out.println("请输入你要买的手机品牌:");
Scanner scanner=new Scanner(System.in);
String string=scanner.nextLine();
Phone phone=PhoneFactory.getInstance(string);
main.BuyPhone(phone);
}
public void BuyPhone(Phone phone){
phone.printPhone();
}
}
interface Phone {
void printPhone();
}
class HuaWeiPhone implements Phone{
@Override
public void printPhone() {
System.out.println("HuaWei");
}
}
class XiaoMiPhone implements Phone{
@Override
public void printPhone() {
System.out.println("XiaoMi");
}
}
class PhoneFactory{
public static Phone getInstance(String type){
Phone phone=null;
if(type.equals("HuaWei")){
phone=new HuaWeiPhone();
}else if(type.equals("XiaoMi")){
phone=new XiaoMiPhone();
}
return phone;
}
}
简单工厂模式缺点:
- 添加具体产品时需要修改工厂,违反了OCP开放封闭原则
工厂方法模式
针对每个产品提供一个工厂类,在客户端来决定使用哪个工厂类来创建对象
public class Main {
public static void main(String args[]) {
Main main=new Main();
PhoneFactory factory=new XiaoMiFactory();
main.BuyPhone(factory.creatPhone());
}
public void BuyPhone(Phone phone){
phone.printPhone();
}
}
interface Phone{
void printPhone();
}
class HuaWeiPhone implements Phone{
@Override
public void printPhone() {
System.out.println("HuaWeiPhone");
}
}
class XiaoMiPhone implements Phone{
@Override
public void printPhone() {
System.out.println("XiaoMiPhone");
}
}
interface PhoneFactory{
Phone creatPhone();
}
class HuaWeiFactory implements PhoneFactory{
@Override
public Phone creatPhone() {
return new HuaWeiPhone();
}
}
class XiaoMiFactory implements PhoneFactory{
@Override
public Phone creatPhone() {
return new XiaoMiPhone();
}
}
工厂方法模式的缺点:
- 增加了代码量,每一款产品都要写一个工厂
- 当是添加一个产品,需要修改工厂,违背OCP
抽象工厂模式
提供一个创建一系列相关对象的接口,而不指定它们具体的类。
interface Computer {
void printComputer();
}
class MacbookProComputer implements Computer {
public void printComputer() {
System.out.println("This is a MacbookPro");
}
}
class SurfaceBookComputer implements Computer {
public void printComputer() {
System.out.println("This is a SurfaceBook");
}
}
interface OperatingSystem {
void printSystem();
}
class MacOsSystem implements OperatingSystem {
public void printSystem() {
System.out.println("This is a mac os");
}
}
class Windows8System implements OperatingSystem {
public void printSystem() {
System.out.println("This is a window 8");
}
}
interface ProductionFactory {
Computer createComputer();
OperatingSystem createSystem();
}
class AppleFactory implements ProductionFactory {
public Computer createComputer() {
return new MacbookProComputer();
}
public OperatingSystem createSystem() {
return new MacOsSystem();
}
}
class MsFactory implements ProductionFactory {
public Computer createComputer() {
return new SurfaceBookComputer();
}
public OperatingSystem createSystem() {
return new Windows8System();
}
}
public class Client {
public void buyComputer(Computer computer) {
computer.printComputer();
}
public void use(OperatingSystem s) {
s.printSystem();
}
public static void main(String[] args) {
Client client = new Client();
ProductionFactory factory = new AppleFactory();
Computer computer = factory.createComputer();
OperatingSystem system = factory.createSystem();
client.buyComputer(computer);
client.use(system);
}
}
抽象工厂模式的缺点:
- 扩展产品很麻烦,会违反OCP
- 十分笨重
代理设计模式
两个子类共同实现一个接口,一个子类负责真实业务实现,另外一个子类完成辅助真实业务的操作
public class Main {
public static void main(String args[]) {
ISubject subject = Main.getInstance();
subject.BuyPhone();
}
public static ISubject getInstance(){
return new ProxySubject(new RealSubject()) ;
}
}
interface ISubject{
void BuyPhone();
}
class RealSubject implements ISubject{
@Override
public void BuyPhone() {
System.out.println("买手机");
}
}
class ProxySubject implements ISubject{
private ISubject subject; //真实业务类
public ProxySubject(ISubject subject){
this.subject=subject;
}
public void producePhone(){
System.out.println("生产华为手机");
}
public void afterSale(){
System.out.println("售后服务");
}
@Override
public void BuyPhone() {
this.producePhone();
this.subject.BuyPhone();
this.afterSale();
}
}