工厂设计模式与代理设计模式

思考如下场景:
有一天,某同学准备去买笔记本,到商城发现有两款电脑她特别喜欢, 一款是 Macbook Pro, 另一款是 Surface Pro。
根据以上的场景,类图可以如下表示:
在这里插入图片描述

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");
    }
}
 
public class Client {
    public void buyComputer(Computer computer) {
        computer.printComputer();
    }
    
    public static void main(String[] args) {
        Client client = new Client();
        client.buyComputer(new MacbookProComputer());
    }
}

这时候问题就来了,如果此时这个同学又看上了一款外星人(Alienware)笔记本,我们就不得不返回客户端去修改代 码,让客户端支持Alienware笔记本。那么,如何将实例化具体类的代码从客户端中抽离,或者封装起来,使它们不会干扰应用的其他部分呢?

简单工厂模式

简单工厂模式:专门定义一个类用来创建其它类的实例,被创建的实例通常都具有共同的父类。
这里我们相当于是创建生产电脑的工厂,客户需要购买什么样的电脑,只要输入类型编号就可以获取该电脑。将类的实例化交给工厂易于解耦。
类图如下所示:
在这里插入图片描述

import java.util.Scanner;
 
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");    
    }
}
 
class ComputerFactory {    
    public static Computer getInstance(String type) {        
        Computer computer = null;        
        if (type.equals("macbook")) {            
            computer = new MacbookProComputer();        
        }else if (type.equals("surface")) {            
            computer = new SurfaceBookComputer();        
        }        
        return computer;    
    }
}
 
public class Client {    
    public void buyComputer(Computer computer) {        
        computer.printComputer();    
    }    
    
    public static void main(String[] args) {
         
        Client client = new Client();        
        Scanner scanner = new Scanner(System.in);        
        System.out.println("请输入您想要的电脑型号...");
        String type = scanner.nextLine();        
        Computer computer = ComputerFactory.getInstance(type);        
        client.buyComputer(computer);

    }
}

以上就是一个简单工厂模式

总结:
1、一个抽象产品类
2、具体产品类
3、一个工厂

优点:

  • 易于实现
  • 类的实例化交个工厂,易于解耦

缺点:

  • 添加具体产品需要修改工厂违反OCP开放封闭原则
工厂方法模式

工厂方法模式:定义一个用来创建对象的接口,让子类决定实例化哪一个类,让子类决定实例化延迟到子类。
工厂方法模式是针对每个产品提供一个工厂类,在客户端中判断使用哪个工厂类去创建对象。
将之前的 ComputerFactory 抽象成一个接口,那么创建相应具体的工厂类去实现该接口的方法。
具体类图的实现:
在这里插入图片描述

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 ComputerFactory {    
    Computer createComputer(); 
}
 
class MsFactory implements ComputerFactory {
 
    public Computer createComputer() {        
        return new SurfaceBookComputer();    
    } 
}
 
class AppleFactory implements ComputerFactory {
 
    public Computer createComputer() {        
        return new MacbookProComputer();    
    } 
}
 
public class Client {    
    public void buyComputer(Computer computer) {        
        computer.printComputer();    
    }    
        
    public static void main(String[] args) {        
        Client client = new Client();        
        ComputerFactory factory = new AppleFactory();        
        client.buyComputer(factory.createComputer());    
    } 
}

工厂方法模式是针对每个产品提供一个工厂类,在客户端中判断使用哪个工厂类去创建对象。

简单工厂模式 VS 工厂方法模式
  • 对于简单工厂模式而言,创建对象的逻辑判断放在了工厂类中,客户不感知具体的类,但是其违背了开闭原 则,如果要增加新的具体类,就必须修改工厂类。
  • 对于工厂方法模式而言,是通过扩展来新增具体类的,符合开闭原则,但是在客户端就必须要感知到具体的 工厂类,也就是将判断逻辑由简单工厂的工厂类挪到客户端。
  • 工厂方法横向扩展很方便,假如该工厂又有新的产品 Macbook Air 要生产,那么只需要创建相应的工厂类和 产品类去实现抽象工厂接口和抽象产品接口即可,而不用去修改原有已经存在的代码。

总结:

  1. 一个抽象产品类
  2. 多个具体产品类
  3. 一个抽象工厂
  4. 多个具体工厂 ——每一个具体产品对应一个具体工厂

优点:
降低了代码耦合度,对象的生成交给子类去完成 实现了开放封闭原则 - 每次添加子产品 不需要修改原有代码.
缺点:
增加了代码量,每个具体产品都需要一个具体工厂 当增加抽象产品 也就是添加一个其他产品族 需要修改工厂 违背OCP.

抽象模式

这时候负责该工厂的产品经理说要生产新的一类产品操作系统 Mac Os 和 Windows 8,这时候就引申出了抽象工 厂模式。
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
工厂方法模式和抽象工厂模式基本类似,可以这么理解:当工厂只生产一个产品的时候,即为工厂方法模式,而工 厂如果生产两个或以上的商品即变为抽象工厂模式。
我们在抽象工厂接口中新增创建系统的方法,并由实例工厂类去实现。
类图可由下表示:
在这里插入图片描述

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);   
    }
}

概要

  1. 多个抽象产品类
  2. 具体产品类
  3. 抽象工厂类 - 声明(一组)返回抽象产品的方法
  4. 具体工厂类 - 生成(一组)具体产品

优点:
代码解耦 实现多个产品族(相关联产品组成的家族),而工厂方法模式的单个产品,可以满足更多的生产需求 很好的满足OCP开放封闭原则 抽象工厂模式中我们可以定义实现不止一个接口,一个工厂也可以生成不止一个产品类 对于复杂对象的生产 相当灵活易扩展.

缺点:
扩展产品族相当麻烦 而且扩展产品族会违反OCP ,因为要修改所有的工厂 由于抽象工厂模式是工厂方法模式的扩展 总体的来说 很笨重.

总结

1】简单工厂模式最大的优点就是工厂内有具体的逻辑去判断生成什么产品,将类的实例化交给了工厂,这样当 我们需要什么产品只需要修改工厂的调用而不需要去修改客户端,对于客户端来说降低了与具体产品的依赖
2】工厂方法模式是简单工厂的扩展,工厂方法模式把原先简单工厂中的实现那个类的逻辑判断交给了客户端, 如果像添加功能只需要修改客户和添加具体的功能,不用去修改之前的类。
3】抽象工厂模式进一步扩展了工厂方法模式,它把原先的工厂方法模式中只能有一个抽象产品不能添加产品族 的缺点克服了,抽象工厂模式不仅仅遵循了OCP原则,而且可以添加更多产品(抽象产品),具体工厂也不仅仅 可以生成单一产品,而是生成一组产品,抽象工厂也是声明一组产品,对应扩展更加灵活,但是要是扩展族 系就会很笨重。

JDK中用到工厂模式的典型操作:

  • 1.Collection中的iterator方法 (集合类中的迭代器)
  • 2.java.util包中的sql相关操作
代理设计模式

两个子类共同实现一个接口,其中一个子类负责真实业务实现,另外一个子类完成辅助真实业务主题的操作。

范例
interface ISubject {     
    public void buyComputer() ; // 核心功能是买电脑 
}

class RealSubject implements ISubject {    
    public void buyComputer() {        
        System.out.println("买一台外星人电脑") ;    
    } 
} 
        
class ProxySubject implements ISubject {    
    private ISubject subject ; // 真正的操作业务    
    public ProxySubject(ISubject subject) {        
        this.subject = subject ; 
    }    
                
    public void produceComputer() { 
        System.out.println("1.生产外星人电脑") ;    
    }   
    
    public void afterSale() {        
        System.out.println("3.外星人电脑售后团队") ;   
    }   
    
    public void buyComputer() {     
        this.produceComputer() ; // 真实操作前的准备    
        this.subject.buyComputer() ; // 调用真实业务     
        this.afterSale() ; // 操作后的收尾  
    }
}
class Factory {    
    public static ISubject getInstance(){ 
        return new ProxySubject(new RealSubject()) ; 
    }
}
 
public class Test{   
    public static void main(String[] args) {        
        ISubject subject = Factory.getInstance() ;        
        subject.buyComputer() ;    
    } 
}

代理模式的本质:所有的真实业务操作都会有一个与之辅助的工具类(功能类)共同完成。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值