设计模式Android 其他相关文章:
【设计模式Android】设计模式六大原则
定义:为其他对象提供一种代理以控制这个对象的访问
代理模式中的角色
Subject抽象主题
抽象主题可以是一个抽象类也可以是一个接口。
public interface Subject{
public void doSomeThing();
}
RealSubject具体实例
被代理的角色,是逻辑的具体执行者。
public class RealSubject implements Subject{
@Override
public void doSomeThing() {
//do some things
}
}
代理类
用来代理实际类执行逻辑
public class Proxy implements Subject{
private Subject subject = null;
public Proxy(){
subject = new RealSubject();
}
@Override
public void doSomeThing() {
subject.doSomeThing();
}
}
举个例子
在这里我们举这样一个例子。
比如我们在玩游戏的时候希望找个代练,代替我们升级打怪。这个这个代练就可以认为是一个代理。
我们可以简单写一下做个对比:
Subject抽象主题类
我们在这里定义一下游戏玩家的抽象行为:
public interface IGame {
public void attack();
public void move();
public void dead();
public void update();
}
RealSubject真是主题类
在这里我们定义下玩家的实际行为:
public class GamePlayer implements IGame
{
private String name;
public GamePlayer(String name){
this.name = name;
}
@Override
public void attack() {
System.out.println(name+"正在"+"攻击");
}
@Override
public void move() {
System.out.println(name+"正在"+"行走");
}
@Override
public void dead() {
System.out.println(name+"已经"+"死亡");
}
@Override
public void update() {
System.out.println(name+"已经"+"升级");
}
}
代理类
现在需要找一个类替我们去执行我们要执行的行为。
public class GamePlayerProxy implements IGame {
private IGame player = null;
public GamePlayerProxy(IGame player){
this.player = player;
}
@Override
public void attack() {
player.attack();
}
@Override
public void move() {
player.move();
}
@Override
public void dead() {
player.dead();
}
@Override
public void update() {
player.update();
}
}
实例化执行
我们现在看一下应该如何在程序中调用:
public class Main {
public static void main(String[] args) {
IGame player = new GamePlayer("deep");
IGame proxy = new GamePlayerProxy(player);
proxy.move();
proxy.attack();
proxy.update();
proxy.dead();
}
}
为什么要用代理模式
有些开发者看了这篇文章可能会问,我们在写程序中,为什么要用代理模式,我们直接商用上面提到的真是主题类RealSubject不就行了吗?
可以是可以,但是不符合我们之前提到过的设计原则(【设计模式Android】设计模式六大原则)
隔离原则
在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用, 其特征是代理类与委托类有同样的接口。
开闭原则
代理类不仅仅是一个隔离客户端和委托类的中介。我们还可以借助代理来在增加一些功能,而不需要修改原有代码,严重的复合开闭原则哦。
优点:
- 职责清晰,RealSubject只处理实际业务逻辑,不用关心其它。
- 高扩展性,复合开闭原则,方便进行修改
拓展
普通代理
客户端只访问代理,不访问真实角色。
就如同上文中举的例子一样。调用者只知道代理而不知道真实角色,我们修改一下上面的例子:
public class GamePlayerProxy implements IGame {
private IGame player = null;
public GamePlayerProxy(String name){
this.player = new GamePlayer(name);
}
@Override
public void attack() {
player.attack();
}
@Override
public void move() {
player.move();
}
@Override
public void dead() {
player.dead();
}
@Override
public void update() {
player.update();
}
}
修改一下调用,可以看出:
public class Main {
public static void main(String[] args) {
IGame proxy = new GamePlayerProxy("deep");
proxy.move();
proxy.attack();
proxy.update();
proxy.dead();
}
}
强制代理
强制代理比较特殊,它是通过真实角色找到代理角色,我们还是修改一下上面的例子的代理类:
public class GamePlayer implements IGame
{
private String name;
private IGame proxy = null;
public GamePlayer(String name){
this.name = name;
}
public IGame getProxy() {
this.proxy = new GamePlayerProxy(this);
return this.proxy;
}
@Override
public void attack() {
if (this.getProxy()!=null){
System.out.println(name+"正在"+"攻击");
}else {
System.out.println("请指定代理");
}
}
@Override
public void move() {
if (this.getProxy()!=null) {
System.out.println(name + "正在" + "行走");
}else {
System.out.println("请指定代理");
}
}
@Override
public void dead() {
if (this.getProxy()!=null) {
System.out.println(name + "已经" + "死亡");
}else {
System.out.println("请指定代理");
}
}
@Override
public void update() {
if (this.getProxy()!=null) {
System.out.println(name + "已经" + "升级");
}else {
System.out.println("请指定代理");
}
}
private boolean isProxy(){
if (this.proxy == null){
return false;
}else {
return true;
}
}
}
增加一个私有方法,检查是否有指定的代理。通过这个方式你可以看出,你想绕过代理直接访问真实的类,但是,真实类,还是给你返回代理。我们访问如下:
public class Main {
public static void main(String[] args) {
IGame player = new GamePlayer("deep");
player.move();
player.attack();
player.update();
player.dead();
}
}
总结
代理模式跟中介者模式容易搞混,之后的文章我们会再介绍一下中介者模式,并进行一下对比。